diff options
author | Minh Nguyễn <mxn@1ec5.org> | 2016-12-27 11:58:20 -0800 |
---|---|---|
committer | Minh Nguyễn <mxn@1ec5.org> | 2017-10-26 12:32:44 -0700 |
commit | c3b17357f91f768ba7b0fa17254bbd7cccdb8300 (patch) | |
tree | 55f7e442fa77979e5f15b52ebf3b724e24e87e95 | |
parent | ab3547a21614605f8acef606226b33c874b4c2dd (diff) | |
download | qtlocation-mapboxgl-c3b17357f91f768ba7b0fa17254bbd7cccdb8300.tar.gz |
[macos] Layer filter editorupstream/1ec5-predicate-editor
Added a Layer Filter panel to the bottom of the macosapp document window that edits the selected layer’s predicate. Subclassed NSPredicateEditorRowTemplate to allow for arbitrary key paths in a single template and also to represent an aggregate value as a token field.
-rw-r--r-- | platform/macos/app/Base.lproj/MainMenu.xib | 6 | ||||
-rw-r--r-- | platform/macos/app/Base.lproj/MapDocument.xib | 230 | ||||
-rw-r--r-- | platform/macos/app/FeatureAttributePredicateEditorRowTemplate.h | 5 | ||||
-rw-r--r-- | platform/macos/app/FeatureAttributePredicateEditorRowTemplate.m | 147 | ||||
-rw-r--r-- | platform/macos/app/MapDocument.m | 34 | ||||
-rw-r--r-- | platform/macos/macos.xcodeproj/project.pbxproj | 6 |
6 files changed, 407 insertions, 21 deletions
diff --git a/platform/macos/app/Base.lproj/MainMenu.xib b/platform/macos/app/Base.lproj/MainMenu.xib index 3243838848..1c7ff6871c 100644 --- a/platform/macos/app/Base.lproj/MainMenu.xib +++ b/platform/macos/app/Base.lproj/MainMenu.xib @@ -451,6 +451,12 @@ <action selector="toggleLayers:" target="-1" id="YdA-Mr-MHi"/> </connections> </menuItem> + <menuItem title="Show Layer Filter" id="q0e-JO-Xth"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="toggleLayerFilter:" target="-1" id="6FD-mU-yq3"/> + </connections> + </menuItem> <menuItem isSeparatorItem="YES" id="8aO-Nm-fxF"/> <menuItem title="Labels In" id="M7v-B1-vo3"> <modifierMask key="keyEquivalentModifierMask"/> diff --git a/platform/macos/app/Base.lproj/MapDocument.xib b/platform/macos/app/Base.lproj/MapDocument.xib index 0394f38533..3a593e6686 100644 --- a/platform/macos/app/Base.lproj/MapDocument.xib +++ b/platform/macos/app/Base.lproj/MapDocument.xib @@ -9,8 +9,9 @@ <connections> <outlet property="mapView" destination="q4d-kF-8Hi" id="7hI-dS-A5R"/> <outlet property="mapViewContextMenu" destination="XbX-6a-Mgy" id="YD0-1r-5N2"/> - <outlet property="splitView" destination="IPR-fm-vk8" id="9xt-ar-uad"/> + <outlet property="predicateSplitView" destination="PMo-HJ-OR3" id="WjV-ED-5fD"/> <outlet property="styleLayersArrayController" destination="GXW-3J-Gff" id="Ygs-7o-juz"/> + <outlet property="styleLayersSplitView" destination="IPR-fm-vk8" id="Yf4-cR-W29"/> <outlet property="styleLayersTableView" destination="Mm4-6F-qEb" id="TB5-ha-JJE"/> <outlet property="window" destination="cSv-fg-MAQ" id="TBu-Mu-79N"/> </connections> @@ -38,6 +39,7 @@ <declaredKeys> <string>identifier</string> <string>visible</string> + <string>predicate</string> </declaredKeys> <connections> <binding destination="Xji-k6-iQ4" name="contentArray" keyPath="selection.reversedLayers" id="wtL-d8-GNd"/> @@ -57,14 +59,14 @@ <rect key="frame" x="0.0" y="0.0" width="642" height="480"/> <subviews> <scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="sMc-vT-RwH"> - <rect key="frame" x="0.0" y="0.0" width="163" height="480"/> + <rect key="frame" x="0.0" y="0.0" width="185" height="480"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <clipView key="contentView" id="bSc-hK-bzQ"> - <rect key="frame" x="0.0" y="0.0" width="163" height="480"/> + <rect key="frame" x="0.0" y="0.0" width="185" height="480"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnResizing="NO" autosaveColumns="NO" id="Mm4-6F-qEb"> - <rect key="frame" x="0.0" y="0.0" width="163" height="480"/> + <rect key="frame" x="0.0" y="0.0" width="185" height="480"/> <autoresizingMask key="autoresizingMask"/> <size key="intercellSpacing" width="3" height="2"/> <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> @@ -87,7 +89,7 @@ </binding> </connections> </tableColumn> - <tableColumn editable="NO" width="141" minWidth="40" maxWidth="1000" id="BwD-ww-7uw"> + <tableColumn editable="NO" width="163" minWidth="40" maxWidth="1000" id="BwD-ww-7uw"> <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border"> <font key="font" metaFont="smallSystem"/> <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/> @@ -128,21 +130,223 @@ <autoresizingMask key="autoresizingMask"/> </scroller> <scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="0vt-rI-sHB"> - <rect key="frame" x="147" y="480" width="16" height="0.0"/> + <rect key="frame" x="169" y="480" width="16" height="0.0"/> <autoresizingMask key="autoresizingMask"/> </scroller> </scrollView> - <customView id="q4d-kF-8Hi" customClass="MGLMapView"> - <rect key="frame" x="164" y="0.0" width="478" height="480"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <splitView autosaveName="MBXFilterSplitView" dividerStyle="thin" id="PMo-HJ-OR3"> + <rect key="frame" x="186" y="0.0" width="456" height="480"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <subviews> + <customView fixedFrame="YES" id="q4d-kF-8Hi" customClass="MGLMapView"> + <rect key="frame" x="0.0" y="0.0" width="456" height="379"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <connections> + <outlet property="delegate" destination="-2" id="dh2-0H-jFZ"/> + <outlet property="menu" destination="XbX-6a-Mgy" id="dSu-HR-Kq2"/> + </connections> + </customView> + <scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" id="Kft-Ar-3PQ"> + <rect key="frame" x="0.0" y="380" width="456" height="100"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <clipView key="contentView" id="BcG-vk-Now"> + <rect key="frame" x="0.0" y="0.0" width="456" height="100"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <predicateEditor verticalHuggingPriority="750" nestingMode="compound" canRemoveAllRows="YES" rowHeight="25" id="6vE-YI-Rel"> + <rect key="frame" x="0.0" y="0.0" width="456" height="100"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/> + <rowTemplates> + <predicateEditorRowTemplate rowType="compound" id="BxM-Fk-fTN"> + <popUpMenus> + <menu id="Xs9-mi-bFL"> + <items> + <menuItem title="Any" state="on" id="Nco-tn-b7s"> + <integer key="representedObject" value="2"/> + </menuItem> + <menuItem title="All" id="o2p-g4-agW"> + <integer key="representedObject" value="1"/> + </menuItem> + <menuItem title="None" id="BBM-Mi-bFU"> + <integer key="representedObject" value="0"/> + </menuItem> + </items> + </menu> + <menu id="DB6-uo-x9N"> + <items> + <menuItem title="of the following are true" state="on" id="3zs-VD-nVg"/> + </items> + </menu> + </popUpMenus> + </predicateEditorRowTemplate> + <predicateEditorRowTemplate rowType="simple" id="Wqv-mw-4vY" customClass="FeatureAttributePredicateEditorRowTemplate"> + <array key="leftExpressionObject"> + <expression type="keyPath"> + <string key="keyPath">string</string> + </expression> + </array> + <integer key="rightExpressionObject" value="700"/> + <popUpMenus> + <menu id="hg7-Gg-kDR"> + <items> + <menuItem title="string" state="on" id="yqb-0B-JIn"> + <expression key="representedObject" type="keyPath"> + <string key="keyPath">string</string> + </expression> + </menuItem> + </items> + </menu> + <menu id="OzK-Yl-gzs"> + <items> + <menuItem title="is" state="on" id="EXt-Ii-58I"> + <integer key="representedObject" value="4"/> + </menuItem> + <menuItem title="is at least" id="diA-te-oP7"> + <integer key="representedObject" value="3"/> + </menuItem> + <menuItem title="is at most" id="DVP-hh-cti"> + <integer key="representedObject" value="1"/> + </menuItem> + <menuItem title="is less than" id="gjD-eE-5Qf"> + <integer key="representedObject" value="0"/> + </menuItem> + <menuItem title="is more than" id="BLw-cg-dS8"> + <integer key="representedObject" value="2"/> + </menuItem> + <menuItem title="is not" id="fZA-gd-2YX"> + <integer key="representedObject" value="5"/> + </menuItem> + <menuItem title="is one of" id="eNT-km-TxV"> + <integer key="representedObject" value="10"/> + </menuItem> + </items> + </menu> + </popUpMenus> + </predicateEditorRowTemplate> + <predicateEditorRowTemplate rowType="simple" id="wrH-hN-KkV" customClass="FeatureAttributePredicateEditorRowTemplate"> + <array key="leftExpressionObject"> + <expression type="keyPath"> + <string key="keyPath">integer</string> + </expression> + </array> + <integer key="rightExpressionObject" value="300"/> + <popUpMenus> + <menu id="mxx-PF-Uk1"> + <items> + <menuItem title="integer" state="on" id="zjg-iH-ldw"> + <expression key="representedObject" type="keyPath"> + <string key="keyPath">integer</string> + </expression> + </menuItem> + </items> + </menu> + <menu id="t3G-Iv-PWh"> + <items> + <menuItem title="is" state="on" id="W2j-4q-nL1"> + <integer key="representedObject" value="4"/> + </menuItem> + <menuItem title="is at least" id="Uau-vm-9w4"> + <integer key="representedObject" value="3"/> + </menuItem> + <menuItem title="is at most" id="IwP-IA-Eoa"> + <integer key="representedObject" value="1"/> + </menuItem> + <menuItem title="is less than" id="lYG-3r-SnX"> + <integer key="representedObject" value="0"/> + </menuItem> + <menuItem title="is more than" id="9Gl-9d-mz9"> + <integer key="representedObject" value="2"/> + </menuItem> + <menuItem title="is not" id="fEN-ap-aE2"> + <integer key="representedObject" value="5"/> + </menuItem> + <menuItem title="is one of" id="AXf-Fk-T65"> + <integer key="representedObject" value="10"/> + </menuItem> + </items> + </menu> + </popUpMenus> + </predicateEditorRowTemplate> + <predicateEditorRowTemplate rowType="simple" id="CmU-AF-UCD" customClass="FeatureAttributePredicateEditorRowTemplate"> + <array key="leftExpressionObject"> + <expression type="keyPath"> + <string key="keyPath">float</string> + </expression> + </array> + <integer key="rightExpressionObject" value="500"/> + <popUpMenus> + <menu id="0DE-A3-bYf"> + <items> + <menuItem title="float" state="on" id="Bx4-8s-246"> + <expression key="representedObject" type="keyPath"> + <string key="keyPath">float</string> + </expression> + </menuItem> + </items> + </menu> + <menu id="Isc-aI-S9W"> + <items> + <menuItem title="is" state="on" id="z20-CG-WD6"> + <integer key="representedObject" value="4"/> + </menuItem> + <menuItem title="is at least" id="e0a-Hk-IlW"> + <integer key="representedObject" value="3"/> + </menuItem> + <menuItem title="is at most" id="Glf-GN-6we"> + <integer key="representedObject" value="1"/> + </menuItem> + <menuItem title="is less than" id="9DD-gB-6AB"> + <integer key="representedObject" value="0"/> + </menuItem> + <menuItem title="is more than" id="N0b-pS-QEU"> + <integer key="representedObject" value="2"/> + </menuItem> + <menuItem title="is not" id="J6J-f0-hll"> + <integer key="representedObject" value="5"/> + </menuItem> + <menuItem title="is one of" id="5G0-1Q-S2B"> + <integer key="representedObject" value="10"/> + </menuItem> + </items> + </menu> + </popUpMenus> + </predicateEditorRowTemplate> + </rowTemplates> + <connections> + <binding destination="GXW-3J-Gff" name="value" keyPath="selection.predicate" id="xc2-AY-P22"> + <dictionary key="options"> + <bool key="NSRaisesForNotApplicableKeys" value="NO"/> + </dictionary> + </binding> + </connections> + </predicateEditor> + </subviews> + <color key="backgroundColor" white="0.91000002619999998" alpha="1" colorSpace="calibratedWhite"/> + </clipView> + <constraints> + <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="100" id="hGB-sT-MZ9"/> + </constraints> + <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="svL-nO-cey"> + <rect key="frame" x="-100" y="-100" width="360" height="15"/> + <autoresizingMask key="autoresizingMask"/> + </scroller> + <scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="Die-wi-C47"> + <rect key="frame" x="440" y="130" width="16" height="0.0"/> + <autoresizingMask key="autoresizingMask"/> + </scroller> + </scrollView> + </subviews> <constraints> - <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="200" id="kg3-4h-7Hl"/> + <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="200" id="afd-SL-SjN"/> </constraints> + <holdingPriorities> + <real value="250"/> + <real value="250"/> + </holdingPriorities> <connections> - <outlet property="delegate" destination="-2" id="dh2-0H-jFZ"/> - <outlet property="menu" destination="XbX-6a-Mgy" id="dSu-HR-Kq2"/> + <outlet property="delegate" destination="-2" id="HeW-CX-0V0"/> </connections> - </customView> + </splitView> </subviews> <holdingPriorities> <real value="250"/> diff --git a/platform/macos/app/FeatureAttributePredicateEditorRowTemplate.h b/platform/macos/app/FeatureAttributePredicateEditorRowTemplate.h new file mode 100644 index 0000000000..6fe6b1b911 --- /dev/null +++ b/platform/macos/app/FeatureAttributePredicateEditorRowTemplate.h @@ -0,0 +1,5 @@ +#import <Cocoa/Cocoa.h> + +@interface FeatureAttributePredicateEditorRowTemplate : NSPredicateEditorRowTemplate + +@end diff --git a/platform/macos/app/FeatureAttributePredicateEditorRowTemplate.m b/platform/macos/app/FeatureAttributePredicateEditorRowTemplate.m new file mode 100644 index 0000000000..0d19bd1635 --- /dev/null +++ b/platform/macos/app/FeatureAttributePredicateEditorRowTemplate.m @@ -0,0 +1,147 @@ +#import "FeatureAttributePredicateEditorRowTemplate.h" + +#import <Mapbox/Mapbox.h> + +@implementation MGLStyleLayer (MBXAdditions) + +- (NSPredicate *)predicate { + return nil; +} + +- (void)setPredicate:(NSPredicate *)predicate { +} + +@end + +@implementation FeatureAttributePredicateEditorRowTemplate { + NSTextField *_keyPathTextField; + NSPopUpButton *_operatorPopUpButton; + NSTextField *_valueTextField; + NSTokenField *_valueTokenField; +} + +- (double)matchForPredicate:(NSComparisonPredicate *)predicate { + if (![predicate isKindOfClass:[NSComparisonPredicate class]]) { + return 0; + } + + id constantValue = predicate.rightExpression.constantValue; + if ([constantValue isKindOfClass:[NSArray class]]) { + constantValue = [[constantValue firstObject] constantValue]; + } + switch (self.rightExpressionAttributeType) { + case NSBooleanAttributeType: + return ([constantValue isKindOfClass:[NSNumber class]] + && (strcmp([constantValue objCType], @encode(char)) == 0 + || strcmp([constantValue objCType], @encode(BOOL)) == 0)) ? 1 : 0; + + case NSDoubleAttributeType: + case NSFloatAttributeType: + return ([constantValue isKindOfClass:[NSNumber class]] + && (strcmp([constantValue objCType], @encode(double)) == 0 + || strcmp([constantValue objCType], @encode(float)) == 0)) ? 1 : 0; + + case NSInteger16AttributeType: + case NSInteger32AttributeType: + case NSInteger64AttributeType: + return ([constantValue isKindOfClass:[NSNumber class]] + && strcmp([constantValue objCType], @encode(double)) != 0 + && strcmp([constantValue objCType], @encode(float)) != 0 + && strcmp([constantValue objCType], @encode(char)) != 0 + && strcmp([constantValue objCType], @encode(BOOL)) != 0) ? 1 : 0; + + case NSStringAttributeType: + return [constantValue isKindOfClass:[NSString class]] ? 0.8 : 0; + + default: + return [super matchForPredicate:predicate]; + } +} + +- (NS_ARRAY_OF(NSView *) *)templateViews { + NSMutableArray *views = super.templateViews.mutableCopy; + views[0] = self.keyPathTextField; + _operatorPopUpButton = views[1]; + _valueTextField = views[2]; + + BOOL isInPredicate = [_operatorPopUpButton.selectedItem.representedObject unsignedIntegerValue] == NSInPredicateOperatorType; + if (isInPredicate) { + [views insertObject:self.valueTokenField atIndex:2]; + } else { + [views addObject:self.valueTokenField]; + } + [views[2] setHidden:NO]; + [views[3] setHidden:YES]; + + return views; +} + +- (NSTextField *)keyPathTextField { + if (!_keyPathTextField) { + _keyPathTextField = [[NSTextField alloc] initWithFrame:NSZeroRect]; + _keyPathTextField.editable = NO; + _keyPathTextField.bordered = NO; + _keyPathTextField.backgroundColor = nil; + _keyPathTextField.font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]; + } + [_keyPathTextField sizeToFit]; + return _keyPathTextField; +} + +- (NSTokenField *)valueTokenField { + if (!_valueTokenField) { + _valueTokenField = [[NSTokenField alloc] initWithFrame:NSZeroRect]; + _valueTokenField.font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]; + } + [_valueTokenField sizeToFit]; + NSRect frame = _valueTokenField.frame; + frame.size.width = _valueTextField.frame.size.width; + _valueTokenField.frame = frame; + return _valueTokenField; +} + +- (NSPredicate *)predicateWithSubpredicates:(NS_ARRAY_OF(NSPredicate *) *)subpredicates { + NSComparisonPredicate *predicate = (NSComparisonPredicate *)[super predicateWithSubpredicates:subpredicates]; + NSAssert([predicate isKindOfClass:[NSComparisonPredicate class]], @"FeatureAttributePredicateEditorRowTemplate only works with comparison predicates."); + + NSExpression *leftExpression = [NSExpression expressionForKeyPath:self.keyPathTextField.stringValue]; + NSExpression *rightExpression = predicate.rightExpression; + if (predicate.predicateOperatorType == NSInPredicateOperatorType) { + rightExpression = [NSExpression expressionForAggregate: + [_valueTokenField.stringValue componentsSeparatedByString:@","]]; + } + return [NSComparisonPredicate predicateWithLeftExpression:leftExpression + rightExpression:rightExpression + modifier:predicate.comparisonPredicateModifier + type:predicate.predicateOperatorType + options:predicate.options]; +} + +- (void)setPredicate:(NSComparisonPredicate *)predicate { + NSAssert([predicate isKindOfClass:[NSComparisonPredicate class]], @"FeatureAttributePredicateEditorRowTemplate only works with comparison predicates."); + + self.keyPathTextField.stringValue = predicate.leftExpression.keyPath; + [self.keyPathTextField sizeToFit]; + + BOOL isInPredicate = predicate.predicateOperatorType == NSInPredicateOperatorType; + _operatorPopUpButton.enabled = !isInPredicate; + _valueTextField.hidden = isInPredicate; + self.valueTokenField.hidden = !isInPredicate; + NSExpression *rightExpression = predicate.rightExpression; + if (isInPredicate) { + NSArray *values = [rightExpression.constantValue valueForKeyPath:@"constantValue"]; + self.valueTokenField.stringValue = [values componentsJoinedByString:@","]; + rightExpression = [NSExpression expressionForConstantValue:nil]; + } else { + self.valueTokenField.stringValue = @""; + } + + predicate = [NSComparisonPredicate predicateWithLeftExpression:self.leftExpressions.firstObject + rightExpression:rightExpression + modifier:predicate.comparisonPredicateModifier + type:predicate.predicateOperatorType + options:predicate.options]; + [super setPredicate:predicate]; +} + +@end diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m index feef53062b..5c69dbe0c0 100644 --- a/platform/macos/app/MapDocument.m +++ b/platform/macos/app/MapDocument.m @@ -55,7 +55,8 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio @property (weak) IBOutlet NSArrayController *styleLayersArrayController; @property (weak) IBOutlet NSTableView *styleLayersTableView; @property (weak) IBOutlet NSMenu *mapViewContextMenu; -@property (weak) IBOutlet NSSplitView *splitView; +@property (weak) IBOutlet NSSplitView *styleLayersSplitView; +@property (weak) IBOutlet NSSplitView *predicateSplitView; @end @@ -108,9 +109,10 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio NSPressGestureRecognizer *pressGestureRecognizer = [[NSPressGestureRecognizer alloc] initWithTarget:self action:@selector(handlePressGesture:)]; [self.mapView addGestureRecognizer:pressGestureRecognizer]; - - [self.splitView setPosition:0 ofDividerAtIndex:0]; - + + [self.styleLayersSplitView setPosition:0 ofDividerAtIndex:0]; + [self.predicateSplitView setPosition:DBL_MAX ofDividerAtIndex:0]; + [self applyPendingState]; } @@ -306,10 +308,10 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio Show or hide the Layers sidebar. */ - (IBAction)toggleLayers:(id)sender { - BOOL isShown = ![self.splitView isSubviewCollapsed:self.splitView.arrangedSubviews.firstObject]; + BOOL isShown = ![self.styleLayersSplitView isSubviewCollapsed:self.styleLayersSplitView.arrangedSubviews.firstObject]; [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) { context.allowsImplicitAnimation = YES; - [self.splitView setPosition:isShown ? 0 : 100 ofDividerAtIndex:0]; + [self.styleLayersSplitView setPosition:isShown ? 0 : 100 ofDividerAtIndex:0]; [self.window.toolbar validateVisibleItems]; } completionHandler:nil]; } @@ -402,6 +404,17 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio [self.styleLayersArrayController removeObjectsAtArrangedObjectIndexes:indices]; } +/** + Show or hide the Layer Filter pane. + */ +- (IBAction)toggleLayerFilter:(id)sender { + BOOL isShown = ![self.predicateSplitView isSubviewCollapsed:self.predicateSplitView.arrangedSubviews.lastObject]; + [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) { + context.allowsImplicitAnimation = YES; + [self.predicateSplitView setPosition:isShown ? DBL_MAX : self.mapView.frame.size.height - 100 ofDividerAtIndex:0]; + } completionHandler:nil]; +} + - (IBAction)setLabelLanguage:(NSMenuItem *)sender { _isLocalizingLabels = sender.tag; [self reload:sender]; @@ -901,7 +914,7 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio return YES; } if (menuItem.action == @selector(toggleLayers:)) { - BOOL isShown = ![self.splitView isSubviewCollapsed:self.splitView.arrangedSubviews.firstObject]; + BOOL isShown = ![self.styleLayersSplitView isSubviewCollapsed:self.styleLayersSplitView.arrangedSubviews.firstObject]; menuItem.title = isShown ? @"Hide Layers" : @"Show Layers"; return YES; } @@ -921,6 +934,11 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio if (menuItem.action == @selector(deleteStyleLayers:)) { return self.styleLayersTableView.clickedRow >= 0 || self.styleLayersTableView.selectedRow >= 0; } + if (menuItem.action == @selector(toggleLayerFilter:)) { + BOOL isShown = ![self.predicateSplitView isSubviewCollapsed:self.predicateSplitView.arrangedSubviews.lastObject]; + menuItem.title = isShown ? @"Hide Layer Filter" : @"Show Layer Filter"; + return YES; + } if (menuItem.action == @selector(setLabelLanguage:)) { menuItem.state = menuItem.tag == _isLocalizingLabels ? NSOnState: NSOffState; if (menuItem.tag) { @@ -1079,7 +1097,7 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio } } if (action == @selector(toggleLayers:)) { - BOOL isShown = ![self.splitView isSubviewCollapsed:self.splitView.arrangedSubviews.firstObject]; + BOOL isShown = ![self.styleLayersSplitView isSubviewCollapsed:self.styleLayersSplitView.arrangedSubviews.firstObject]; [(NSButton *)toolbarItem.view setState:isShown ? NSOnState : NSOffState]; } return NO; diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj index 34f8860686..957b417d77 100644 --- a/platform/macos/macos.xcodeproj/project.pbxproj +++ b/platform/macos/macos.xcodeproj/project.pbxproj @@ -156,6 +156,7 @@ DAA998FB1E9F545C002E6EA6 /* MGLFillExtrusionStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = DAA998F91E9F545C002E6EA6 /* MGLFillExtrusionStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; DAA998FC1E9F545C002E6EA6 /* MGLFillExtrusionStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = DAA998FA1E9F545C002E6EA6 /* MGLFillExtrusionStyleLayer.mm */; }; DAA999011E9F5EC5002E6EA6 /* MGLFillExtrusionStyleLayerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = DAA999001E9F5EC5002E6EA6 /* MGLFillExtrusionStyleLayerTests.mm */; }; + 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 */; }; DACB0C391E18DFFD005DDBEA /* MGLStyle+MBXAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = DACB0C381E18DFFD005DDBEA /* MGLStyle+MBXAdditions.m */; }; @@ -489,6 +490,8 @@ DAA998F91E9F545C002E6EA6 /* MGLFillExtrusionStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLFillExtrusionStyleLayer.h; sourceTree = "<group>"; }; DAA998FA1E9F545C002E6EA6 /* MGLFillExtrusionStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLFillExtrusionStyleLayer.mm; sourceTree = "<group>"; }; DAA999001E9F5EC5002E6EA6 /* MGLFillExtrusionStyleLayerTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLFillExtrusionStyleLayerTests.mm; sourceTree = "<group>"; }; + DAA578311E11FD46009B2566 /* FeatureAttributePredicateEditorRowTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FeatureAttributePredicateEditorRowTemplate.h; sourceTree = "<group>"; }; + DAA578321E11FD46009B2566 /* FeatureAttributePredicateEditorRowTemplate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FeatureAttributePredicateEditorRowTemplate.m; sourceTree = "<group>"; }; 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>"; }; @@ -756,6 +759,8 @@ DA839E961CC2E3400062CAFB /* AppDelegate.m */, DAE6C2E31CC3050F00DB3429 /* DroppedPinAnnotation.h */, DAE6C2E41CC3050F00DB3429 /* DroppedPinAnnotation.m */, + DAA578311E11FD46009B2566 /* FeatureAttributePredicateEditorRowTemplate.h */, + DAA578321E11FD46009B2566 /* FeatureAttributePredicateEditorRowTemplate.m */, DAB2CCE31DF632ED001B2FE1 /* LimeGreenStyleLayer.h */, DAB2CCE41DF632ED001B2FE1 /* LimeGreenStyleLayer.m */, DAE6C2E51CC3050F00DB3429 /* LocationCoordinate2DTransformer.h */, @@ -1413,6 +1418,7 @@ DACB0C391E18DFFD005DDBEA /* MGLStyle+MBXAdditions.m in Sources */, DA839E9A1CC2E3400062CAFB /* main.m in Sources */, DA839E971CC2E3400062CAFB /* AppDelegate.m in Sources */, + DAA578331E11FD46009B2566 /* FeatureAttributePredicateEditorRowTemplate.m in Sources */, DAE6C2F01CC3050F00DB3429 /* OfflinePackNameValueTransformer.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; |