├── screenshot.png ├── XFunnyEditor ├── en.lproj │ └── InfoPlist.strings ├── XFunnyEditor-Prefix.pch ├── XFunnyBackgroundView.h ├── XFunnyEditor.h ├── Xcode.h ├── XFunnyBackgroundView.m ├── PreferenceWindowController.h ├── XFunnyEditor-Info.plist ├── PreferenceWindowController.m ├── PreferenceWindowController.xib └── XFunnyEditor.m ├── XFunnyEditor.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── XFunnyEditor.xccheckout └── project.pbxproj ├── .gitignore ├── LICENSE └── README.md /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/STAR-ZERO/XFunnyEditor/HEAD/screenshot.png -------------------------------------------------------------------------------- /XFunnyEditor/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /XFunnyEditor/XFunnyEditor-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'XFunnyEditor' target in the 'XFunnyEditor' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /XFunnyEditor.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | */build/* 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | profile 14 | *.moved-aside 15 | DerivedData 16 | .idea/ 17 | *.hmap 18 | 19 | #CocoaPods 20 | Pods 21 | -------------------------------------------------------------------------------- /XFunnyEditor/XFunnyBackgroundView.h: -------------------------------------------------------------------------------- 1 | // 2 | // XFunnyBackground.h 3 | // XFunnyEditor 4 | // 5 | // Created by Kenji Abe on 2013/09/26. 6 | // Copyright (c) 2013年 STAR-ZERO. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface XFunnyBackgroundView : NSView 12 | 13 | - (id)initWithFrame:(NSRect)frame color:(NSColor *)aColor; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /XFunnyEditor/XFunnyEditor.h: -------------------------------------------------------------------------------- 1 | // 2 | // XFunnyEditor.h 3 | // XFunnyEditor 4 | // 5 | // Created by Kenji Abe on 2013/07/27. 6 | // Copyright (c) 2013年 STAR-ZERO. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "Xcode.h" 11 | #import "XFunnyBackgroundView.h" 12 | #import "PreferenceWindowController.h" 13 | 14 | @interface XFunnyEditor : NSObject 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /XFunnyEditor/Xcode.h: -------------------------------------------------------------------------------- 1 | // 2 | // Xcode.h 3 | // XFunnyEditor 4 | // 5 | // Created by Kenji Abe on 2013/07/27. 6 | // Copyright (c) 2013年 STAR-ZERO. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DVTCompletingTextView : NSTextView 12 | @end 13 | 14 | @interface DVTSourceTextView : DVTCompletingTextView 15 | @end 16 | 17 | @interface DVTSourceTextScrollView : NSScrollView 18 | @end 19 | 20 | @interface DVTTextSidebarView : NSRulerView 21 | @end -------------------------------------------------------------------------------- /XFunnyEditor/XFunnyBackgroundView.m: -------------------------------------------------------------------------------- 1 | // 2 | // XFunnyBackground.m 3 | // XFunnyEditor 4 | // 5 | // Created by Kenji Abe on 2013/09/26. 6 | // Copyright (c) 2013年 STAR-ZERO. All rights reserved. 7 | // 8 | 9 | #import "XFunnyBackgroundView.h" 10 | 11 | @implementation XFunnyBackgroundView 12 | { 13 | NSColor *_backgroundColor; 14 | } 15 | 16 | - (id)initWithFrame:(NSRect)frame color:(NSColor *)aColor 17 | { 18 | self = [super initWithFrame:frame]; 19 | if (self) { 20 | _backgroundColor = aColor; 21 | [_backgroundColor retain]; 22 | } 23 | return self; 24 | 25 | } 26 | - (void)drawRect:(NSRect)dirtyRect 27 | { 28 | [_backgroundColor setFill]; 29 | NSRectFill(dirtyRect); 30 | [super drawRect:dirtyRect]; 31 | } 32 | 33 | - (void)dealloc 34 | { 35 | [_backgroundColor release]; 36 | [super dealloc]; 37 | } 38 | @end 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Kenji Abe 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /XFunnyEditor/PreferenceWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // PreferenceWindowController.h 3 | // XFunnyEditor 4 | // 5 | // Created by Kenji Abe on 2013/09/26. 6 | // Copyright (c) 2013年 STAR-ZERO. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol PreferenceDelegate 12 | 13 | @required 14 | - (void)selectedImageFile:(NSString *)imagePath; 15 | - (void)selectedPosition:(NSImageAlignment)position; 16 | - (void)selectedOpacity:(float)opacity; 17 | - (void)selectedScaleFit:(BOOL)scaleFit; 18 | @end 19 | 20 | @interface PreferenceWindowController : NSWindowController 21 | 22 | @property (assign) IBOutlet NSTextField *textFile; 23 | @property (assign) IBOutlet NSButton *buttonFile; 24 | @property (assign) IBOutlet NSComboBox *comboPosition; 25 | @property (assign) IBOutlet NSSlider *sliderOpacity; 26 | @property (assign) IBOutlet NSTextField *labelOpacity; 27 | @property (assign) IBOutlet NSButton *scaleFitButton; 28 | 29 | @property (nonatomic, assign) id delegate; 30 | 31 | - (IBAction)clickFile:(id)sender; 32 | - (IBAction)changePosition:(id)sender; 33 | - (IBAction)changeSliderOpactiy:(id)sender; 34 | - (IBAction)changeScaleFit:(id)sender; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # XFunnyEditor 2 | 3 | Xcode plugin to display an image on the background of the editor 4 | 5 | ![Screenshot](https://raw.github.com/STAR-ZERO/XFunnyEditor/master/screenshot.png) 6 | 7 | ## Install 8 | 9 | ### Manual 10 | 11 | Build the XFunnyEditor target in the Xcode project and the plugin will automatically be installed in `~/Library/Application Support/Developer/Shared/Xcode/Plug-ins`. Restart Xcode. 12 | 13 | ### Alcatraz 14 | 15 | Install from [Alcatraz](https://github.com/supermarin/Alcatraz) package manager. Restart Xcode. 16 | 17 | ## Uninstall 18 | 19 | Delete the following directory: `~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/XFunnyEditor.xcplugin`. 20 | 21 | ## Usage 22 | 23 | To Start XFunnyEditor setting screen, select `XFunnyEditor` from `Edit` menu. 24 | 25 | Please specify image file and transparency and position from setting screen. 26 | 27 | If you want to disable, please select the menu again. 28 | 29 | ## Support version 30 | 31 | This plugin is developed in MaxOS 10.8 and Xcode 5.0 32 | 33 | ## Known Issues :( 34 | 35 | * Crash By using the XFunnyEditor setting screen in the except source code editor. 36 | * Occasional crash when you select the menu. 37 | 38 | ## License 39 | 40 | [MIT License](https://github.com/STAR-ZERO/XFunnyEditor/blob/master/LICENSE) 41 | -------------------------------------------------------------------------------- /XFunnyEditor.xcodeproj/project.xcworkspace/xcshareddata/XFunnyEditor.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 8C1C2D80-54C5-451A-8ACB-C8B3A4C6E732 9 | IDESourceControlProjectName 10 | XFunnyEditor 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 6009380AEE374457373B20668826619AD46220C5 14 | https://github.com/STAR-ZERO/XFunnyEditor 15 | 16 | IDESourceControlProjectPath 17 | XFunnyEditor.xcodeproj/project.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 6009380AEE374457373B20668826619AD46220C5 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/STAR-ZERO/XFunnyEditor 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 6009380AEE374457373B20668826619AD46220C5 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 6009380AEE374457373B20668826619AD46220C5 36 | IDESourceControlWCCName 37 | XFunnyEditor 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /XFunnyEditor/XFunnyEditor-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.zero.star.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | XC4Compatible 26 | 27 | XCGCReady 28 | 29 | XCPluginHasUI 30 | 31 | DVTPlugInCompatibilityUUIDs 32 | 33 | 7FDF5C7A-131F-4ABB-9EDC-8C5F8F0B8A90 34 | AD68E85B-441B-4301-B564-A45E4919A6AD 35 | A2E4D43F-41F4-4FB9-BB94-7177011C9AED 36 | 37B30044-3B14-46BA-ABAA-F01000C27B63 37 | C4A681B0-4A26-480E-93EC-1218098B9AA0 38 | A16FF353-8441-459E-A50C-B071F53F51B7 39 | 9F75337B-21B4-4ADC-B558-F9CADF7073A7 40 | E969541F-E6F9-4D25-8158-72DC3545A6C6 41 | 0420B86A-AA43-4792-9ED0-6FE0F2B16A13 42 | 7265231C-39B4-402C-89E1-16167C4CC990 43 | F41BD31E-2683-44B8-AE7F-5F09E919790E 44 | ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /XFunnyEditor/PreferenceWindowController.m: -------------------------------------------------------------------------------- 1 | // 2 | // PreferenceWindowController.m 3 | // XFunnyEditor 4 | // 5 | // Created by Kenji Abe on 2013/09/26. 6 | // Copyright (c) 2013年 STAR-ZERO. All rights reserved. 7 | // 8 | 9 | #import "PreferenceWindowController.h" 10 | 11 | @interface PreferenceWindowController () 12 | 13 | @end 14 | 15 | @implementation PreferenceWindowController 16 | 17 | - (id)initWithWindow:(NSWindow *)window 18 | { 19 | self = [super initWithWindow:window]; 20 | if (self) { 21 | // Initialization code here. 22 | } 23 | return self; 24 | } 25 | 26 | - (void)windowDidLoad 27 | { 28 | [super windowDidLoad]; 29 | 30 | } 31 | 32 | - (void)windowWillClose:(NSNotification *)notification 33 | { 34 | int result = 1; 35 | if (self.textFile && ![self.textFile.stringValue isEqualToString:@""]) { 36 | // result ok 37 | result = 0; 38 | } 39 | [[NSApplication sharedApplication] stopModalWithCode:result]; 40 | } 41 | 42 | - (IBAction)clickFile:(id)sender { 43 | NSOpenPanel *openPanel = [NSOpenPanel openPanel]; 44 | NSArray *fileTypes = [[[NSArray alloc] initWithObjects:@"png", @"jpg", @"jpeg", nil] autorelease]; 45 | 46 | [openPanel setCanChooseDirectories:NO]; 47 | [openPanel setCanChooseFiles:YES]; 48 | [openPanel setAllowedFileTypes:fileTypes]; 49 | 50 | [openPanel beginSheetModalForWindow:self.window completionHandler:^(NSInteger resultCode){ 51 | if (resultCode == NSOKButton) { 52 | NSURL *pathURL = [[openPanel URLs] objectAtIndex:0]; 53 | NSString *imagePath = [pathURL path]; 54 | 55 | [self.textFile setStringValue:imagePath]; 56 | 57 | [self.delegate selectedImageFile:imagePath]; 58 | } 59 | }]; 60 | } 61 | 62 | - (IBAction)changePosition:(id)sender { 63 | NSInteger index = [self.comboPosition indexOfSelectedItem]; 64 | [self.delegate selectedPosition:index]; 65 | } 66 | 67 | - (IBAction)changeSliderOpactiy:(id)sender { 68 | NSUInteger opacity = floor([self.sliderOpacity floatValue]); 69 | [self.labelOpacity setStringValue:[NSString stringWithFormat:@"%ld", opacity]]; 70 | 71 | [self.delegate selectedOpacity:opacity / 100.0]; 72 | } 73 | 74 | - (IBAction)changeScaleFit:(id)sender { 75 | BOOL scaleFit; 76 | if ([self.scaleFitButton state] == NSOnState) { 77 | scaleFit = YES; 78 | } 79 | else { 80 | scaleFit = NO; 81 | } 82 | 83 | [self.delegate selectedScaleFit:scaleFit]; 84 | } 85 | 86 | @end 87 | -------------------------------------------------------------------------------- /XFunnyEditor/PreferenceWindowController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | Center 72 | Top-Center 73 | Top-Left 74 | Top-Right 75 | Left-Center 76 | Bottom-Center 77 | Bottom-Left 78 | Bottom-Right 79 | Right-Center 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /XFunnyEditor.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | BA53B91717A37C290065862C /* DVTKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BA53B91617A37C290065862C /* DVTKit.framework */; }; 11 | BA7A2A2D17F420F5007052DD /* XFunnyBackgroundView.m in Sources */ = {isa = PBXBuildFile; fileRef = BA7A2A2C17F420F5007052DD /* XFunnyBackgroundView.m */; }; 12 | BA8A874F17F40AAF00A20250 /* PreferenceWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = BA8A874D17F40AAF00A20250 /* PreferenceWindowController.m */; }; 13 | BA8A875017F40AAF00A20250 /* PreferenceWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BA8A874E17F40AAF00A20250 /* PreferenceWindowController.xib */; }; 14 | BAAC24C217A3755800C31251 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BAAC24C117A3755800C31251 /* AppKit.framework */; }; 15 | BAAC24C417A3755800C31251 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BAAC24C317A3755800C31251 /* Foundation.framework */; }; 16 | BAAC24CA17A3755800C31251 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = BAAC24C817A3755800C31251 /* InfoPlist.strings */; }; 17 | BAAC24CD17A3755800C31251 /* XFunnyEditor.m in Sources */ = {isa = PBXBuildFile; fileRef = BAAC24CC17A3755800C31251 /* XFunnyEditor.m */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXFileReference section */ 21 | BA53B91217A37AD40065862C /* Xcode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Xcode.h; sourceTree = ""; }; 22 | BA53B91617A37C290065862C /* DVTKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DVTKit.framework; path = /Applications/Xcode.app/Contents/SharedFrameworks/DVTKit.framework; sourceTree = ""; }; 23 | BA7A2A2B17F420F5007052DD /* XFunnyBackgroundView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XFunnyBackgroundView.h; sourceTree = ""; }; 24 | BA7A2A2C17F420F5007052DD /* XFunnyBackgroundView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XFunnyBackgroundView.m; sourceTree = ""; }; 25 | BA8A874C17F40AAF00A20250 /* PreferenceWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PreferenceWindowController.h; sourceTree = ""; }; 26 | BA8A874D17F40AAF00A20250 /* PreferenceWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PreferenceWindowController.m; sourceTree = ""; }; 27 | BA8A874E17F40AAF00A20250 /* PreferenceWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PreferenceWindowController.xib; sourceTree = ""; }; 28 | BAAC24BE17A3755800C31251 /* XFunnyEditor.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XFunnyEditor.xcplugin; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | BAAC24C117A3755800C31251 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 30 | BAAC24C317A3755800C31251 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 31 | BAAC24C717A3755800C31251 /* XFunnyEditor-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "XFunnyEditor-Info.plist"; sourceTree = ""; }; 32 | BAAC24C917A3755800C31251 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 33 | BAAC24CB17A3755800C31251 /* XFunnyEditor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XFunnyEditor.h; sourceTree = ""; }; 34 | BAAC24CC17A3755800C31251 /* XFunnyEditor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XFunnyEditor.m; sourceTree = ""; }; 35 | BAAC24CE17A3755800C31251 /* XFunnyEditor-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "XFunnyEditor-Prefix.pch"; sourceTree = ""; }; 36 | /* End PBXFileReference section */ 37 | 38 | /* Begin PBXFrameworksBuildPhase section */ 39 | BAAC24BB17A3755800C31251 /* Frameworks */ = { 40 | isa = PBXFrameworksBuildPhase; 41 | buildActionMask = 2147483647; 42 | files = ( 43 | BAAC24C217A3755800C31251 /* AppKit.framework in Frameworks */, 44 | BAAC24C417A3755800C31251 /* Foundation.framework in Frameworks */, 45 | BA53B91717A37C290065862C /* DVTKit.framework in Frameworks */, 46 | ); 47 | runOnlyForDeploymentPostprocessing = 0; 48 | }; 49 | /* End PBXFrameworksBuildPhase section */ 50 | 51 | /* Begin PBXGroup section */ 52 | BAAC24B517A3755800C31251 = { 53 | isa = PBXGroup; 54 | children = ( 55 | BAAC24C517A3755800C31251 /* XFunnyEditor */, 56 | BAAC24C017A3755800C31251 /* Frameworks */, 57 | BAAC24BF17A3755800C31251 /* Products */, 58 | ); 59 | sourceTree = ""; 60 | }; 61 | BAAC24BF17A3755800C31251 /* Products */ = { 62 | isa = PBXGroup; 63 | children = ( 64 | BAAC24BE17A3755800C31251 /* XFunnyEditor.xcplugin */, 65 | ); 66 | name = Products; 67 | sourceTree = ""; 68 | }; 69 | BAAC24C017A3755800C31251 /* Frameworks */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | BA53B91617A37C290065862C /* DVTKit.framework */, 73 | BAAC24C117A3755800C31251 /* AppKit.framework */, 74 | BAAC24C317A3755800C31251 /* Foundation.framework */, 75 | ); 76 | name = Frameworks; 77 | sourceTree = ""; 78 | }; 79 | BAAC24C517A3755800C31251 /* XFunnyEditor */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | BAAC24CB17A3755800C31251 /* XFunnyEditor.h */, 83 | BAAC24CC17A3755800C31251 /* XFunnyEditor.m */, 84 | BA7A2A2B17F420F5007052DD /* XFunnyBackgroundView.h */, 85 | BA7A2A2C17F420F5007052DD /* XFunnyBackgroundView.m */, 86 | BA8A874C17F40AAF00A20250 /* PreferenceWindowController.h */, 87 | BA8A874D17F40AAF00A20250 /* PreferenceWindowController.m */, 88 | BA8A874E17F40AAF00A20250 /* PreferenceWindowController.xib */, 89 | BA53B91217A37AD40065862C /* Xcode.h */, 90 | BAAC24C617A3755800C31251 /* Supporting Files */, 91 | ); 92 | path = XFunnyEditor; 93 | sourceTree = ""; 94 | }; 95 | BAAC24C617A3755800C31251 /* Supporting Files */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | BAAC24C717A3755800C31251 /* XFunnyEditor-Info.plist */, 99 | BAAC24C817A3755800C31251 /* InfoPlist.strings */, 100 | BAAC24CE17A3755800C31251 /* XFunnyEditor-Prefix.pch */, 101 | ); 102 | name = "Supporting Files"; 103 | sourceTree = ""; 104 | }; 105 | /* End PBXGroup section */ 106 | 107 | /* Begin PBXNativeTarget section */ 108 | BAAC24BD17A3755800C31251 /* XFunnyEditor */ = { 109 | isa = PBXNativeTarget; 110 | buildConfigurationList = BAAC24D117A3755800C31251 /* Build configuration list for PBXNativeTarget "XFunnyEditor" */; 111 | buildPhases = ( 112 | BAAC24BA17A3755800C31251 /* Sources */, 113 | BAAC24BB17A3755800C31251 /* Frameworks */, 114 | BAAC24BC17A3755800C31251 /* Resources */, 115 | ); 116 | buildRules = ( 117 | ); 118 | dependencies = ( 119 | ); 120 | name = XFunnyEditor; 121 | productName = XFunnyEditor; 122 | productReference = BAAC24BE17A3755800C31251 /* XFunnyEditor.xcplugin */; 123 | productType = "com.apple.product-type.bundle"; 124 | }; 125 | /* End PBXNativeTarget section */ 126 | 127 | /* Begin PBXProject section */ 128 | BAAC24B617A3755800C31251 /* Project object */ = { 129 | isa = PBXProject; 130 | attributes = { 131 | LastUpgradeCheck = 0500; 132 | ORGANIZATIONNAME = "STAR-ZERO"; 133 | }; 134 | buildConfigurationList = BAAC24B917A3755800C31251 /* Build configuration list for PBXProject "XFunnyEditor" */; 135 | compatibilityVersion = "Xcode 3.2"; 136 | developmentRegion = English; 137 | hasScannedForEncodings = 0; 138 | knownRegions = ( 139 | en, 140 | ); 141 | mainGroup = BAAC24B517A3755800C31251; 142 | productRefGroup = BAAC24BF17A3755800C31251 /* Products */; 143 | projectDirPath = ""; 144 | projectRoot = ""; 145 | targets = ( 146 | BAAC24BD17A3755800C31251 /* XFunnyEditor */, 147 | ); 148 | }; 149 | /* End PBXProject section */ 150 | 151 | /* Begin PBXResourcesBuildPhase section */ 152 | BAAC24BC17A3755800C31251 /* Resources */ = { 153 | isa = PBXResourcesBuildPhase; 154 | buildActionMask = 2147483647; 155 | files = ( 156 | BA8A875017F40AAF00A20250 /* PreferenceWindowController.xib in Resources */, 157 | BAAC24CA17A3755800C31251 /* InfoPlist.strings in Resources */, 158 | ); 159 | runOnlyForDeploymentPostprocessing = 0; 160 | }; 161 | /* End PBXResourcesBuildPhase section */ 162 | 163 | /* Begin PBXSourcesBuildPhase section */ 164 | BAAC24BA17A3755800C31251 /* Sources */ = { 165 | isa = PBXSourcesBuildPhase; 166 | buildActionMask = 2147483647; 167 | files = ( 168 | BAAC24CD17A3755800C31251 /* XFunnyEditor.m in Sources */, 169 | BA7A2A2D17F420F5007052DD /* XFunnyBackgroundView.m in Sources */, 170 | BA8A874F17F40AAF00A20250 /* PreferenceWindowController.m in Sources */, 171 | ); 172 | runOnlyForDeploymentPostprocessing = 0; 173 | }; 174 | /* End PBXSourcesBuildPhase section */ 175 | 176 | /* Begin PBXVariantGroup section */ 177 | BAAC24C817A3755800C31251 /* InfoPlist.strings */ = { 178 | isa = PBXVariantGroup; 179 | children = ( 180 | BAAC24C917A3755800C31251 /* en */, 181 | ); 182 | name = InfoPlist.strings; 183 | sourceTree = ""; 184 | }; 185 | /* End PBXVariantGroup section */ 186 | 187 | /* Begin XCBuildConfiguration section */ 188 | BAAC24CF17A3755800C31251 /* Debug */ = { 189 | isa = XCBuildConfiguration; 190 | buildSettings = { 191 | ALWAYS_SEARCH_USER_PATHS = NO; 192 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 193 | CLANG_CXX_LIBRARY = "libc++"; 194 | CLANG_WARN_CONSTANT_CONVERSION = YES; 195 | CLANG_WARN_EMPTY_BODY = YES; 196 | CLANG_WARN_ENUM_CONVERSION = YES; 197 | CLANG_WARN_INT_CONVERSION = YES; 198 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 199 | COPY_PHASE_STRIP = NO; 200 | GCC_C_LANGUAGE_STANDARD = gnu99; 201 | GCC_DYNAMIC_NO_PIC = NO; 202 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 203 | GCC_OPTIMIZATION_LEVEL = 0; 204 | GCC_PREPROCESSOR_DEFINITIONS = ( 205 | "DEBUG=1", 206 | "$(inherited)", 207 | ); 208 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 209 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 210 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 211 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 212 | GCC_WARN_UNUSED_VARIABLE = YES; 213 | MACOSX_DEPLOYMENT_TARGET = 10.8; 214 | ONLY_ACTIVE_ARCH = YES; 215 | SDKROOT = macosx; 216 | }; 217 | name = Debug; 218 | }; 219 | BAAC24D017A3755800C31251 /* Release */ = { 220 | isa = XCBuildConfiguration; 221 | buildSettings = { 222 | ALWAYS_SEARCH_USER_PATHS = NO; 223 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 224 | CLANG_CXX_LIBRARY = "libc++"; 225 | CLANG_WARN_CONSTANT_CONVERSION = YES; 226 | CLANG_WARN_EMPTY_BODY = YES; 227 | CLANG_WARN_ENUM_CONVERSION = YES; 228 | CLANG_WARN_INT_CONVERSION = YES; 229 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 230 | COPY_PHASE_STRIP = YES; 231 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 232 | GCC_C_LANGUAGE_STANDARD = gnu99; 233 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 234 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 235 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 236 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 237 | GCC_WARN_UNUSED_VARIABLE = YES; 238 | MACOSX_DEPLOYMENT_TARGET = 10.8; 239 | SDKROOT = macosx; 240 | }; 241 | name = Release; 242 | }; 243 | BAAC24D217A3755800C31251 /* Debug */ = { 244 | isa = XCBuildConfiguration; 245 | buildSettings = { 246 | COMBINE_HIDPI_IMAGES = YES; 247 | DEPLOYMENT_LOCATION = YES; 248 | DSTROOT = "$(HOME)"; 249 | FRAMEWORK_SEARCH_PATHS = ( 250 | "$(inherited)", 251 | "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/SharedFrameworks\"", 252 | ); 253 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 254 | GCC_PREFIX_HEADER = "XFunnyEditor/XFunnyEditor-Prefix.pch"; 255 | INFOPLIST_FILE = "XFunnyEditor/XFunnyEditor-Info.plist"; 256 | INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins"; 257 | PRODUCT_NAME = "$(TARGET_NAME)"; 258 | WRAPPER_EXTENSION = xcplugin; 259 | }; 260 | name = Debug; 261 | }; 262 | BAAC24D317A3755800C31251 /* Release */ = { 263 | isa = XCBuildConfiguration; 264 | buildSettings = { 265 | COMBINE_HIDPI_IMAGES = YES; 266 | DEPLOYMENT_LOCATION = YES; 267 | DSTROOT = "$(HOME)"; 268 | FRAMEWORK_SEARCH_PATHS = ( 269 | "$(inherited)", 270 | "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/SharedFrameworks\"", 271 | ); 272 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 273 | GCC_PREFIX_HEADER = "XFunnyEditor/XFunnyEditor-Prefix.pch"; 274 | INFOPLIST_FILE = "XFunnyEditor/XFunnyEditor-Info.plist"; 275 | INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins"; 276 | PRODUCT_NAME = "$(TARGET_NAME)"; 277 | WRAPPER_EXTENSION = xcplugin; 278 | }; 279 | name = Release; 280 | }; 281 | /* End XCBuildConfiguration section */ 282 | 283 | /* Begin XCConfigurationList section */ 284 | BAAC24B917A3755800C31251 /* Build configuration list for PBXProject "XFunnyEditor" */ = { 285 | isa = XCConfigurationList; 286 | buildConfigurations = ( 287 | BAAC24CF17A3755800C31251 /* Debug */, 288 | BAAC24D017A3755800C31251 /* Release */, 289 | ); 290 | defaultConfigurationIsVisible = 0; 291 | defaultConfigurationName = Release; 292 | }; 293 | BAAC24D117A3755800C31251 /* Build configuration list for PBXNativeTarget "XFunnyEditor" */ = { 294 | isa = XCConfigurationList; 295 | buildConfigurations = ( 296 | BAAC24D217A3755800C31251 /* Debug */, 297 | BAAC24D317A3755800C31251 /* Release */, 298 | ); 299 | defaultConfigurationIsVisible = 0; 300 | defaultConfigurationName = Release; 301 | }; 302 | /* End XCConfigurationList section */ 303 | }; 304 | rootObject = BAAC24B617A3755800C31251 /* Project object */; 305 | } 306 | -------------------------------------------------------------------------------- /XFunnyEditor/XFunnyEditor.m: -------------------------------------------------------------------------------- 1 | // 2 | // XFunnyEditor.m 3 | // XFunnyEditor 4 | // 5 | // Created by Kenji Abe on 2013/07/27. 6 | // Copyright (c) 2013年 STAR-ZERO. All rights reserved. 7 | // 8 | 9 | #import "XFunnyEditor.h" 10 | 11 | @interface XFunnyEditor() 12 | @end 13 | 14 | @implementation XFunnyEditor 15 | { 16 | PreferenceWindowController *_preferenceWindow; 17 | NSImage *_image; 18 | NSUInteger _position; 19 | float _opacity; 20 | BOOL _scaleFit; 21 | NSRect _sidebarRect; 22 | DVTSourceTextView *_currentTextView; 23 | NSColor *_originalColor; 24 | 25 | BOOL _isXVimInstalled; 26 | CGFloat _editorViewHeight; 27 | } 28 | 29 | NSString * const kUserDefaultsKeyImagePath = @"XFunnyEditoryImagePath"; 30 | NSString * const kUserDefaultsKeyImagePosition = @"XFunnyEditoryImagePosition"; 31 | NSString * const kUserDefaultsKeyImageOpcity = @"XFunnyEditoryImageOpacity"; 32 | NSString * const kUserDefaultsKeyImageScaleFit = @"XFunnyEditoryImageScaleFit"; 33 | NSString * const kXVimInstallPath = @"Library/Application Support/Developer/Shared/Xcode/Plug-ins/XVim.xcplugin"; 34 | CGFloat const kXVimCommandLineHeight = 18.0; 35 | 36 | + (void)pluginDidLoad:(NSBundle *)plugin 37 | { 38 | NSLog(@"XFunnyEditor Plugin loaded"); 39 | static id sharedPlugin = nil; 40 | static dispatch_once_t onceToken; 41 | dispatch_once(&onceToken, ^{ 42 | sharedPlugin = [[self alloc] init]; 43 | }); 44 | } 45 | 46 | - (id)init 47 | { 48 | if (self = [super init]) { 49 | 50 | [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 51 | [self createMenuItem]; 52 | }]; 53 | 54 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 55 | NSString *imagePath = [userDefaults objectForKey:kUserDefaultsKeyImagePath]; 56 | 57 | if (imagePath) { 58 | NSFileManager *fileManager = [NSFileManager defaultManager]; 59 | if ([fileManager fileExistsAtPath:imagePath]) { 60 | _image = [[NSImage alloc] initWithContentsOfFile:imagePath]; 61 | } else { 62 | [self removeUserDefaults]; 63 | } 64 | } 65 | 66 | _position = [userDefaults integerForKey:kUserDefaultsKeyImagePosition]; 67 | _opacity = [userDefaults floatForKey:kUserDefaultsKeyImageOpcity]; 68 | _scaleFit = [userDefaults boolForKey:kUserDefaultsKeyImageScaleFit]; 69 | _isXVimInstalled = [self isXVimInstalled]; 70 | 71 | if (_opacity == 0) { 72 | _opacity = 1; 73 | } 74 | 75 | [[NSNotificationCenter defaultCenter] addObserver:self 76 | selector:@selector(applicationDidFinishLaunching:) 77 | name:NSApplicationDidFinishLaunchingNotification 78 | object:nil]; 79 | 80 | } 81 | return self; 82 | } 83 | 84 | - (void)applicationDidFinishLaunching:(NSNotification *)notification 85 | { 86 | [[NSNotificationCenter defaultCenter] addObserver:self 87 | selector:@selector(viewFrameDidChangeNotification:) 88 | name:NSViewFrameDidChangeNotification 89 | object:nil]; 90 | } 91 | 92 | - (void)viewFrameDidChangeNotification:(NSNotification *)notification 93 | { 94 | // keep current object 95 | if ([[notification object] isKindOfClass:[DVTSourceTextView class]]) { 96 | _currentTextView = (DVTSourceTextView *)[notification object]; 97 | } else if ([[notification object] isKindOfClass:[DVTTextSidebarView class]]) { 98 | _sidebarRect = ((DVTTextSidebarView *)[notification object]).frame; 99 | } 100 | 101 | if (_image == nil) { 102 | return; 103 | } 104 | 105 | if ([[notification object] isKindOfClass:[DVTSourceTextView class]]) { 106 | DVTSourceTextView *textView = (DVTSourceTextView *)[notification object]; 107 | DVTSourceTextScrollView *scrollView = (DVTSourceTextScrollView *)[textView enclosingScrollView]; 108 | 109 | if (![self isSourceTextView:scrollView]) { 110 | return; 111 | } 112 | 113 | NSView *view = [scrollView superview]; 114 | if (view) { 115 | if (NSEqualRects(_sidebarRect, NSZeroRect)) { 116 | return; 117 | } 118 | 119 | NSImageView *imageView = [self getImageViewFromParentView:view]; 120 | XFunnyBackgroundView *backgroundView = [self getBackgroundViewFromaParentView:view]; 121 | if (imageView) { 122 | // exist image 123 | [self setFrameImageView:imageView backgroundView:backgroundView scrollView:scrollView]; 124 | [imageView setImage:_image]; 125 | return; 126 | } 127 | 128 | NSColor *color = [textView backgroundColor]; 129 | _originalColor = color; 130 | [scrollView setDrawsBackground:NO]; 131 | [textView setBackgroundColor:[NSColor clearColor]]; 132 | 133 | _editorViewHeight = view.frame.size.height; 134 | if (_isXVimInstalled) { 135 | _editorViewHeight -= kXVimCommandLineHeight; 136 | } 137 | 138 | // create ImageView 139 | imageView = [[[NSImageView alloc] initWithFrame:[self getImageViewFrame:scrollView]] autorelease]; 140 | 141 | backgroundView = [[[XFunnyBackgroundView alloc] initWithFrame:[self getImageViewFrame:scrollView] color:color] autorelease]; 142 | 143 | [imageView setImage:_image]; 144 | imageView.alphaValue = _opacity; 145 | imageView.imageAlignment = _position; 146 | if (_scaleFit) { 147 | [imageView setImageScaling:NSScaleToFit]; 148 | } 149 | [view addSubview:imageView positioned:NSWindowBelow relativeTo:nil]; 150 | [view addSubview:backgroundView positioned:NSWindowBelow relativeTo:nil]; 151 | } 152 | 153 | } else if ([[notification object] isKindOfClass:[DVTSourceTextScrollView class]]) { 154 | // resize editor 155 | DVTSourceTextScrollView *scrollView = [notification object]; 156 | 157 | if (![self isSourceTextView:scrollView]) { 158 | return; 159 | } 160 | 161 | NSView *view = [scrollView superview]; 162 | 163 | NSImageView *imageView = [self getImageViewFromParentView:view]; 164 | XFunnyBackgroundView *backgroundView = [self getBackgroundViewFromaParentView:view]; 165 | 166 | _editorViewHeight = view.frame.size.height; 167 | if (_isXVimInstalled) { 168 | _editorViewHeight -= kXVimCommandLineHeight; 169 | } 170 | 171 | // set frame 172 | [self setFrameImageView:imageView backgroundView:backgroundView scrollView:scrollView]; 173 | } 174 | } 175 | 176 | - (NSImageView *)getImageViewFromParentView:(NSView *)parentView 177 | { 178 | for (NSView *subView in [parentView subviews]) { 179 | if ([subView isKindOfClass:[NSImageView class]]) { 180 | return (NSImageView *) subView; 181 | } 182 | } 183 | return nil; 184 | } 185 | 186 | - (NSImageView *)getImageViewFromTextView 187 | { 188 | 189 | DVTSourceTextScrollView *scrollView = (DVTSourceTextScrollView *)[_currentTextView enclosingScrollView]; 190 | NSView *view = [scrollView superview]; 191 | if (view) { 192 | return [self getImageViewFromParentView:view]; 193 | } 194 | 195 | return nil; 196 | } 197 | 198 | - (XFunnyBackgroundView *)getBackgroundViewFromaParentView:(NSView *)parentView 199 | { 200 | for (NSView *subView in [parentView subviews]) { 201 | if ([subView isKindOfClass:[XFunnyBackgroundView class]]) { 202 | return (XFunnyBackgroundView *) subView; 203 | } 204 | } 205 | return nil; 206 | } 207 | 208 | - (NSRect)getImageViewFrame:(NSView *)scrollView 209 | { 210 | CGFloat y = 0; 211 | if (_isXVimInstalled) { 212 | y += kXVimCommandLineHeight; 213 | } 214 | 215 | return NSMakeRect(_sidebarRect.size.width, 216 | y, 217 | scrollView.bounds.size.width - _sidebarRect.size.width, 218 | _editorViewHeight); 219 | } 220 | 221 | - (void)setFrameImageView:(NSImageView *)imageView backgroundView:(XFunnyBackgroundView *)backgroundView scrollView:(DVTSourceTextScrollView *)scrollView 222 | { 223 | if (imageView && backgroundView) { 224 | [imageView setFrame:[self getImageViewFrame:scrollView]]; 225 | [backgroundView setFrame:[self getImageViewFrame:scrollView]]; 226 | 227 | if (_isXVimInstalled) { 228 | CGRect scrollViewFrame = scrollView.frame; 229 | [scrollView setFrame:CGRectMake(scrollViewFrame.origin.x, 230 | kXVimCommandLineHeight, 231 | scrollViewFrame.size.width, 232 | _editorViewHeight)]; 233 | } 234 | } 235 | } 236 | 237 | - (void)createMenuItem 238 | { 239 | NSMenuItem *menuItem = [[NSApp mainMenu] itemWithTitle:@"Edit"]; 240 | if (menuItem) { 241 | [[menuItem submenu] addItem:[NSMenuItem separatorItem]]; 242 | NSMenuItem *actionMenuItem = [[NSMenuItem alloc] initWithTitle:@"XFunnyEditor" action:@selector(doMenuAction:) keyEquivalent:@""]; 243 | [actionMenuItem setTarget:self]; 244 | 245 | if (_image) { 246 | [actionMenuItem setState:NSOnState]; 247 | } else { 248 | [actionMenuItem setState:NSOffState]; 249 | } 250 | 251 | [[menuItem submenu] addItem:actionMenuItem]; 252 | [actionMenuItem release]; 253 | } 254 | } 255 | 256 | // menu action 257 | - (void)doMenuAction:(id)sender 258 | { 259 | NSMenuItem *menuItem = (NSMenuItem *)sender; 260 | if ([menuItem state] == NSOnState){ 261 | [self disableBackgroundImage:menuItem]; 262 | } else { 263 | [self enableBackgroundImage:menuItem]; 264 | } 265 | } 266 | 267 | // disable background image 268 | - (void)disableBackgroundImage:(NSMenuItem *)menuItem 269 | { 270 | DVTSourceTextScrollView *scrollView = (DVTSourceTextScrollView *)[_currentTextView enclosingScrollView]; 271 | NSView *view = [scrollView superview]; 272 | NSImageView *imageView = [self getImageViewFromParentView:view]; 273 | XFunnyBackgroundView *backgroundView = [self getBackgroundViewFromaParentView:view]; 274 | if (imageView) { 275 | // remove image 276 | [_currentTextView setBackgroundColor:_originalColor]; 277 | [imageView removeFromSuperview]; 278 | [backgroundView removeFromSuperview]; 279 | } 280 | 281 | [self removeUserDefaults]; 282 | 283 | if (_image) { 284 | [_image release]; 285 | _image = nil; 286 | } 287 | _position = 0; 288 | _opacity = 1; 289 | [menuItem setState:NSOffState]; 290 | } 291 | 292 | // selection image file 293 | - (void)enableBackgroundImage:(NSMenuItem *)menuItem 294 | { 295 | 296 | if (!_preferenceWindow) { 297 | _preferenceWindow = [[PreferenceWindowController alloc] initWithWindowNibName:@"PreferenceWindowController"]; 298 | _preferenceWindow.delegate = self; 299 | } 300 | [_preferenceWindow.textFile setStringValue:@""]; 301 | [_preferenceWindow.comboPosition selectItemAtIndex:0]; 302 | [_preferenceWindow.sliderOpacity setIntValue:100]; 303 | [_preferenceWindow.labelOpacity setStringValue:@"100"]; 304 | 305 | NSInteger result = [[NSApplication sharedApplication] runModalForWindow:[_preferenceWindow window]]; 306 | [[_preferenceWindow window] orderOut:self]; 307 | 308 | if (result == 0) { 309 | [menuItem setState:NSOnState]; 310 | 311 | // save userdefaults 312 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 313 | [userDefaults setObject:_preferenceWindow.textFile.stringValue forKey:kUserDefaultsKeyImagePath]; 314 | [userDefaults setInteger:_position forKey:kUserDefaultsKeyImagePosition]; 315 | [userDefaults setFloat:_opacity forKey:kUserDefaultsKeyImageOpcity]; 316 | [userDefaults setBool:_scaleFit forKey:kUserDefaultsKeyImageScaleFit]; 317 | [userDefaults synchronize]; 318 | } 319 | 320 | } 321 | 322 | - (void)removeUserDefaults 323 | { 324 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 325 | [userDefaults removeObjectForKey:kUserDefaultsKeyImagePath]; 326 | [userDefaults removeObjectForKey:kUserDefaultsKeyImagePosition]; 327 | [userDefaults removeObjectForKey:kUserDefaultsKeyImageOpcity]; 328 | [userDefaults removeObjectForKey:kUserDefaultsKeyImageScaleFit]; 329 | [userDefaults synchronize]; 330 | 331 | } 332 | 333 | - (void)selectedImageFile:(NSString *)imagePath 334 | { 335 | _image = [[NSImage alloc] initWithContentsOfFile:imagePath]; 336 | if (_currentTextView) { 337 | // post notification 338 | [[NSNotificationCenter defaultCenter] postNotificationName:NSViewFrameDidChangeNotification object:_currentTextView]; 339 | } 340 | } 341 | 342 | - (void)selectedPosition:(NSImageAlignment)position 343 | { 344 | _position = position; 345 | NSImageView *imageView = [self getImageViewFromTextView]; 346 | if (imageView) { 347 | imageView.imageAlignment = position; 348 | } 349 | 350 | } 351 | - (void)selectedOpacity:(float)opacity 352 | { 353 | _opacity = opacity; 354 | NSImageView *imageView = [self getImageViewFromTextView]; 355 | if (imageView) { 356 | imageView.alphaValue = opacity; 357 | } 358 | } 359 | 360 | - (void)selectedScaleFit:(BOOL)scaleFit 361 | { 362 | _scaleFit = scaleFit; 363 | NSImageView *imageView = [self getImageViewFromTextView]; 364 | if (imageView) { 365 | if (scaleFit) { 366 | [imageView setImageScaling:NSScaleToFit]; 367 | } else { 368 | [imageView setImageScaling:NSScaleProportionally]; 369 | } 370 | } 371 | } 372 | 373 | - (BOOL)isXVimInstalled 374 | { 375 | NSString *pluginsInstallPath = [NSHomeDirectory() stringByAppendingPathComponent:kXVimInstallPath]; 376 | NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease]; 377 | 378 | return [fileManager fileExistsAtPath:pluginsInstallPath]; 379 | } 380 | 381 | - (BOOL)isSourceTextView:(NSView *)scrollView 382 | { 383 | NSString *superViewClass = NSStringFromClass([[scrollView superview] class]); 384 | return [superViewClass isEqualToString:@"IDESourceCodeEditorContainerView"]; 385 | } 386 | 387 | - (void)dealloc 388 | { 389 | [_image release]; 390 | [_currentTextView release]; 391 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 392 | [super dealloc]; 393 | } 394 | 395 | @end 396 | --------------------------------------------------------------------------------