diff options
author | Minh Nguyễn <mxn@1ec5.org> | 2016-12-31 14:52:11 -0800 |
---|---|---|
committer | Minh Nguyễn <mxn@1ec5.org> | 2016-12-31 14:52:11 -0800 |
commit | 631f2c981ffb0479fd780b09e47b7e3959c46589 (patch) | |
tree | b4414fbf6f123a769714a52a0276add6c41e5965 | |
parent | ff0c583949e7bb327f322135809bdf431a17e3cb (diff) | |
download | qtlocation-mapboxgl-upstream/1ec5-style-record.tar.gz |
[macos] Record style mutationsupstream/1ec5-style-record
Track changes to the style while recording, then insert Objective-C, Swift, or AppleScript code into the nearest available Xcode source code editor that replays the changes.
-rw-r--r-- | platform/macos/app/Base.lproj/MapDocument.xib | 18 | ||||
-rw-r--r-- | platform/macos/app/MapDocument.m | 73 | ||||
-rw-r--r-- | platform/macos/macos.xcodeproj/project.pbxproj | 23 |
3 files changed, 114 insertions, 0 deletions
diff --git a/platform/macos/app/Base.lproj/MapDocument.xib b/platform/macos/app/Base.lproj/MapDocument.xib index fe4762402d..b82c51616c 100644 --- a/platform/macos/app/Base.lproj/MapDocument.xib +++ b/platform/macos/app/Base.lproj/MapDocument.xib @@ -431,9 +431,26 @@ <action selector="toggleLayers:" target="-1" id="NHT-rn-BuG"/> </connections> </toolbarItem> + <toolbarItem implicitItemIdentifier="998D85AC-B477-4DB9-81BB-859D5DB0D60C" label="Record" paletteLabel="Record" image="NSStatusUnavailable" id="bBI-JB-B5E" customClass="ValidatedToolbarItem"> + <nil key="toolTip"/> + <size key="minSize" width="47" height="32"/> + <size key="maxSize" width="48" height="32"/> + <button key="view" verticalHuggingPriority="750" id="pCQ-OY-G48"> + <rect key="frame" x="0.0" y="14" width="47" height="32"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSStatusUnavailable" imagePosition="only" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="y9R-H0-zRJ"> + <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/> + <font key="font" metaFont="system"/> + </buttonCell> + </button> + <connections> + <action selector="toggleRecording:" target="-2" id="Au9-wH-hdr"/> + </connections> + </toolbarItem> </allowedToolbarItems> <defaultToolbarItems> <toolbarItem reference="THR-Dm-mn8"/> + <toolbarItem reference="bBI-JB-B5E"/> <toolbarItem reference="XJT-Ho-tuZ"/> <toolbarItem reference="z4l-5x-MzK"/> <toolbarItem reference="u23-0z-Otl"/> @@ -502,6 +519,7 @@ <resources> <image name="NSListViewTemplate" width="14" height="10"/> <image name="NSShareTemplate" width="11" height="16"/> + <image name="NSStatusUnavailable" width="16" height="16"/> <image name="symbol" width="13" height="13"/> </resources> </document> diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m index 0a8883c473..94fef2c11c 100644 --- a/platform/macos/app/MapDocument.m +++ b/platform/macos/app/MapDocument.m @@ -3,6 +3,7 @@ #import "AppDelegate.h" #import "LimeGreenStyleLayer.h" #import "DroppedPinAnnotation.h" +#import "Xcode.h" #import "MGLVectorSource+MBXAdditions.h" @@ -69,11 +70,16 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio NSNumberFormatter *_spellOutNumberFormatter; BOOL _isLocalizingLabels; + BOOL _isRecording; BOOL _showsToolTipsOnDroppedPins; BOOL _randomizesCursorsOnDroppedPins; BOOL _isTouringWorld; BOOL _isShowingPolygonAndPolylineAnnotations; BOOL _isShowingAnimatedAnnotation; + + NSMutableString *_recordedObjectiveCCode; + NSMutableString *_recordedSwiftCode; + NSMutableString *_recordedAppleScriptCode; } #pragma mark Lifecycle @@ -279,6 +285,14 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio for (MGLStyleLayer *layer in layers) { layer.visible = !isVisible; + + NSString *identifier = layer.identifier; + [_recordedObjectiveCCode appendFormat:@"[self.mapView.style layerWithIdentifier:@\"%@\"].visible = %@;\n", + identifier, !isVisible ? @"@YES" : @"@NO"]; + [_recordedSwiftCode appendFormat:@"mapView.style.layer(withIdentifier: \"%@\")?.isVisible = %@\n", + identifier, !isVisible ? @"true" : @"false"]; + [_recordedAppleScriptCode appendFormat:@"set the visibility of (mapView's style's layerWithIdentifier:\"%@\") to %@\n", + identifier, !isVisible ? @"true" : @"false"]; } NSIndexSet *columnIndices = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 2)]; @@ -344,6 +358,62 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio } completionHandler:nil]; } +- (IBAction)toggleRecording:(id)sender { + _isRecording = !_isRecording; + + if (!_isRecording) { + XcodeApplication *xcodeApp = [SBApplication applicationWithBundleIdentifier:@"com.apple.dt.xcode"]; + if (xcodeApp.running) { + XcodeWindow *window = xcodeApp.windows.firstObject; + XcodeSourceDocument *document = [xcodeApp.sourceDocuments objectWithName:window.name]; + NSString *path = document.path; + NSArray *selectedCharacterIndices = document.selectedCharacterRange; + + NSMutableString *recordedCode; + if ([path.pathExtension isEqualToString:@"m"] || [path.pathExtension isEqualToString:@"mm"]) { + recordedCode = _recordedObjectiveCCode; + } else if ([path.pathExtension isEqualToString:@"swift"]) { + recordedCode = _recordedSwiftCode; + } else if ([path.pathExtension isEqualToString:@"applescript"]) { + recordedCode = _recordedAppleScriptCode; + } else { + recordedCode = [NSMutableString string]; + } + NSUInteger start = MIN([selectedCharacterIndices[1] unsignedIntegerValue], [selectedCharacterIndices[0] unsignedIntegerValue]); + NSUInteger end = MAX([selectedCharacterIndices[1] unsignedIntegerValue], [selectedCharacterIndices[0] unsignedIntegerValue]); + NSRange selectedCharacterRange = NSMakeRange(start, end - start); + + NSError *error; + NSMutableString *code = [[NSString stringWithContentsOfFile:path + encoding:NSUTF8StringEncoding + error:&error] mutableCopy]; + if (!error) { + NSRange lineRange = [code lineRangeForRange:NSMakeRange(selectedCharacterRange.location, 0)]; + NSString *line = [code substringWithRange:lineRange]; + NSUInteger indentation = [line rangeOfCharacterFromSet:[NSCharacterSet whitespaceCharacterSet].invertedSet].location; + if (indentation != NSNotFound) { + NSString *indentationString = [line substringWithRange:NSMakeRange(0, indentation)]; + [recordedCode replaceOccurrencesOfString:@"\n" + withString:[NSString stringWithFormat:@"\n%@", indentationString] + options:0 + range:NSMakeRange(0, recordedCode.length)]; + } + selectedCharacterIndices = @[@(selectedCharacterRange.location + recordedCode.length)]; + [recordedCode appendString:@"\n"]; + [code replaceCharactersInRange:selectedCharacterRange withString:recordedCode]; + [code writeToFile:path + atomically:YES + encoding:NSUTF8StringEncoding + error:NULL]; + document.selectedCharacterRange = selectedCharacterIndices; + } + } + } + _recordedObjectiveCCode = [NSMutableString string]; + _recordedSwiftCode = [NSMutableString string]; + _recordedAppleScriptCode = [NSMutableString string]; +} + - (IBAction)setLabelLanguage:(NSMenuItem *)sender { _isLocalizingLabels = sender.tag; [self reload:sender]; @@ -1005,6 +1075,9 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio BOOL isShown = ![self.styleLayersSplitView isSubviewCollapsed:self.styleLayersSplitView.arrangedSubviews.firstObject]; [(NSButton *)toolbarItem.view setState:isShown ? NSOnState : NSOffState]; } + if (action == @selector(toggleRecording:)) { + [(NSButton *)toolbarItem.view setState:_isRecording ? NSOnState : NSOffState]; + } return NO; } diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj index 7a1cd80305..ed1699990a 100644 --- a/platform/macos/macos.xcodeproj/project.pbxproj +++ b/platform/macos/macos.xcodeproj/project.pbxproj @@ -130,6 +130,7 @@ DAA578331E11FD46009B2566 /* FeatureAttributePredicateEditorRowTemplate.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA578321E11FD46009B2566 /* FeatureAttributePredicateEditorRowTemplate.m */; }; DAB2CCE51DF632ED001B2FE1 /* LimeGreenStyleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = DAB2CCE41DF632ED001B2FE1 /* LimeGreenStyleLayer.m */; }; DAC2ABC51CC6D343006D18C4 /* MGLAnnotationImage_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC2ABC41CC6D343006D18C4 /* MGLAnnotationImage_Private.h */; }; + DACB0C2A1E17C50D005DDBEA /* ScriptingBridge.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DACB0C291E17C50D005DDBEA /* ScriptingBridge.framework */; }; DACC22141CF3D3E200D220D9 /* MGLFeature.h in Headers */ = {isa = PBXBuildFile; fileRef = DACC22121CF3D3E200D220D9 /* MGLFeature.h */; settings = {ATTRIBUTES = (Public, ); }; }; DACC22151CF3D3E200D220D9 /* MGLFeature.mm in Sources */ = {isa = PBXBuildFile; fileRef = DACC22131CF3D3E200D220D9 /* MGLFeature.mm */; }; DACC22181CF3D4F700D220D9 /* MGLFeature_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DACC22171CF3D4F700D220D9 /* MGLFeature_Private.h */; }; @@ -394,6 +395,7 @@ DAB2CCE31DF632ED001B2FE1 /* LimeGreenStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LimeGreenStyleLayer.h; sourceTree = "<group>"; }; DAB2CCE41DF632ED001B2FE1 /* LimeGreenStyleLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LimeGreenStyleLayer.m; sourceTree = "<group>"; }; DAC2ABC41CC6D343006D18C4 /* MGLAnnotationImage_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationImage_Private.h; sourceTree = "<group>"; }; + DACB0C291E17C50D005DDBEA /* ScriptingBridge.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ScriptingBridge.framework; path = System/Library/Frameworks/ScriptingBridge.framework; sourceTree = SDKROOT; }; DACC22121CF3D3E200D220D9 /* MGLFeature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLFeature.h; sourceTree = "<group>"; }; DACC22131CF3D3E200D220D9 /* MGLFeature.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLFeature.mm; sourceTree = "<group>"; }; DACC22171CF3D4F700D220D9 /* MGLFeature_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLFeature_Private.h; sourceTree = "<group>"; }; @@ -497,6 +499,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DACB0C2A1E17C50D005DDBEA /* ScriptingBridge.framework in Frameworks */, DAE6C33D1CC30DB200DB3429 /* Mapbox.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -854,6 +857,7 @@ DAE6C31E1CC308BC00DB3429 /* Frameworks */ = { isa = PBXGroup; children = ( + DACB0C291E17C50D005DDBEA /* ScriptingBridge.framework */, 558F18211D0B13B000123F46 /* libmbgl-loop.a */, 5548BE7B1D0ACBBD005DDE81 /* libmbgl-loop-darwin.a */, 5548BE791D0ACBB2005DDE81 /* libmbgl-loop-darwin.a */, @@ -1090,6 +1094,7 @@ isa = PBXNativeTarget; buildConfigurationList = DA839EA91CC2E3400062CAFB /* Build configuration list for PBXNativeTarget "macosapp" */; buildPhases = ( + DACB0C2E1E186A3C005DDBEA /* Generate Xcode Scripting Bridge Header */, DA839E8E1CC2E3400062CAFB /* Sources */, DA839E8F1CC2E3400062CAFB /* Frameworks */, DA839E901CC2E3400062CAFB /* Resources */, @@ -1226,6 +1231,24 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + DACB0C2E1E186A3C005DDBEA /* Generate Xcode Scripting Bridge Header */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Generate Xcode Scripting Bridge Header"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Xcode.h", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cd \"${DERIVED_FILE_DIR}\";\nsdef /Applications/Xcode.app | sdp -fh --basename Xcode;\n"; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ DA839E8E1CC2E3400062CAFB /* Sources */ = { isa = PBXSourcesBuildPhase; |