summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2016-12-27 11:58:20 -0800
committerMinh Nguyễn <mxn@1ec5.org>2017-10-26 12:32:44 -0700
commitc3b17357f91f768ba7b0fa17254bbd7cccdb8300 (patch)
tree55f7e442fa77979e5f15b52ebf3b724e24e87e95
parentab3547a21614605f8acef606226b33c874b4c2dd (diff)
downloadqtlocation-mapboxgl-upstream/1ec5-predicate-editor.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.xib6
-rw-r--r--platform/macos/app/Base.lproj/MapDocument.xib230
-rw-r--r--platform/macos/app/FeatureAttributePredicateEditorRowTemplate.h5
-rw-r--r--platform/macos/app/FeatureAttributePredicateEditorRowTemplate.m147
-rw-r--r--platform/macos/app/MapDocument.m34
-rw-r--r--platform/macos/macos.xcodeproj/project.pbxproj6
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;