-
Notifications
You must be signed in to change notification settings - Fork 124
/
Copy pathLegend.cs
244 lines (215 loc) · 10.9 KB
/
Legend.cs
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
// /*******************************************************************************
// * Copyright 2012-2018 Esri
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// ******************************************************************************/
using Esri.ArcGISRuntime.Mapping;
namespace Esri.ArcGISRuntime.Toolkit.Maui;
/// <summary>
/// The Legend control is used to display symbology and description for a set of <see cref="Layer"/>s
/// in a <see cref="Map"/> or <see cref="Scene"/> contained in a <see cref="GeoView"/>.
/// </summary>
public class Legend : TemplatedView
{
private static DataTemplate s_DefaultLayerItemTemplate;
private static DataTemplate s_DefaultSublayerItemTemplate;
private static DataTemplate s_DefaultLegendInfoItemTemplate;
private static ControlTemplate s_DefaultControlTemplate;
static Legend()
{
s_DefaultLayerItemTemplate = new DataTemplate(() =>
{
var nameLabel = new Label { FontSize = 18, VerticalOptions = LayoutOptions.Center };
nameLabel.SetBinding(Label.TextProperty, static (LegendEntry entry) => ((Layer)entry.Content).Name);
return nameLabel;
});
s_DefaultSublayerItemTemplate = new DataTemplate(() =>
{
var nameLabel = new Label { FontSize = 14, VerticalOptions = LayoutOptions.Center };
nameLabel.SetBinding(Label.TextProperty, static (LegendEntry entry) => ((ILayerContent)entry.Content).Name);
return nameLabel;
});
s_DefaultLegendInfoItemTemplate = new DataTemplate(() =>
{
StackLayout sl = new StackLayout() { Orientation = StackOrientation.Horizontal };
var symbol = new SymbolDisplay { WidthRequest = 40, HeightRequest = 40, VerticalOptions = LayoutOptions.Center, Margin = new Thickness(0, 0, 5, 0) };
symbol.SetBinding(SymbolDisplay.SymbolProperty, static (LegendEntry entry) => ((LegendInfo)entry.Content).Symbol);
sl.Children.Add(symbol);
var nameLabel = new Label { FontSize = 12, VerticalOptions = LayoutOptions.Center };
nameLabel.SetBinding(Label.TextProperty, static (LegendEntry entry) => ((LegendInfo)entry.Content).Name);
sl.Children.Add(nameLabel);
return sl;
});
string template = @"<ControlTemplate xmlns=""http://schemas.microsoft.com/dotnet/2021/maui"" xmlns:x=""http://schemas.microsoft.com/winfx/2009/xaml"" xmlns:esriTK=""clr-namespace:Esri.ArcGISRuntime.Toolkit.Maui"">
<CollectionView x:Name=""ListView"" HorizontalOptions=""Fill"" VerticalOptions=""Fill"" />
</ControlTemplate>";
s_DefaultControlTemplate = Microsoft.Maui.Controls.Xaml.Extensions.LoadFromXaml<ControlTemplate>(new ControlTemplate(), template);
}
private readonly LegendDataSource _datasource;
/// <summary>
/// Initializes a new instance of the <see cref="Legend"/> class.
/// </summary>
public Legend()
{
_datasource = new LegendDataSource(this);
HorizontalOptions = LayoutOptions.Fill;
VerticalOptions = LayoutOptions.Fill;
LayerItemTemplate = s_DefaultLayerItemTemplate;
SublayerItemTemplate = s_DefaultSublayerItemTemplate;
LegendInfoItemTemplate = s_DefaultLegendInfoItemTemplate;
ControlTemplate = s_DefaultControlTemplate;
}
/// <inheritdoc />
protected override void OnApplyTemplate()
{
var list = GetTemplateChild("ListView") as ItemsView;
if (list != null)
{
list.ItemTemplate = new LegendItemTemplateSelector(this);
list.ItemsSource = _datasource;
}
base.OnApplyTemplate();
}
/// <summary>
/// Identifies the <see cref="GeoView"/> bindable property.
/// </summary>
public static readonly BindableProperty GeoViewProperty =
BindableProperty.Create(nameof(GeoView), typeof(GeoView), typeof(Legend), null, BindingMode.OneWay, propertyChanged: OnGeoViewPropertyChanged);
private static void OnGeoViewPropertyChanged(BindableObject bindable, object? oldValue, object? newValue)
{
((Legend)bindable)._datasource.SetGeoView(newValue as GeoView);
}
/// <summary>
/// Gets or sets the geoview that contain the layers whose symbology and description will be displayed.
/// </summary>
/// <seealso cref="MapView"/>
/// <seealso cref="SceneView"/>
/// <seealso cref="GeoViewProperty"/>
public GeoView? GeoView
{
get { return (GeoView)GetValue(GeoViewProperty); }
set { SetValue(GeoViewProperty, value); }
}
/// <summary>
/// Identifies the <see cref="FilterByVisibleScaleRange"/> bindable property.
/// </summary>
public static readonly BindableProperty FilterByVisibleScaleRangeProperty =
BindableProperty.Create(nameof(FilterByVisibleScaleRange), typeof(bool), typeof(Legend), true, BindingMode.OneWay, propertyChanged: OnFilterByVisibleScaleRangePropertyChanged);
private static void OnFilterByVisibleScaleRangePropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
((Legend)bindable)._datasource.FilterByVisibleScaleRange = (bool)newValue;
}
/// <summary>
/// Gets or sets a value indicating whether the scale of <see cref="GeoView"/> and any scale ranges on the <see cref="Layer"/>s
/// are used to determine when legend for layer is displayed.
/// </summary>
/// <value>
/// If <c>true</c>, legend for layer is displayed only when layer is in visible scale range;
/// otherwise, <c>false</c>, legend for layer is displayed regardless of its scale range.
/// </value>
public bool FilterByVisibleScaleRange
{
get { return (bool)GetValue(FilterByVisibleScaleRangeProperty); }
set { SetValue(FilterByVisibleScaleRangeProperty, value); }
}
/// <summary>
/// Identifies the <see cref="FilterHiddenLayers"/> bindable property.
/// </summary>
public static readonly BindableProperty FilterHiddenLayersProperty =
BindableProperty.Create(nameof(FilterHiddenLayers), typeof(bool), typeof(Legend), true, BindingMode.OneWay, propertyChanged: OnFilterHiddenLayersPropertyChanged);
private static void OnFilterHiddenLayersPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
((Legend)bindable)._datasource.FilterHiddenLayers = (bool)newValue;
}
/// <summary>
/// Gets or sets a value indicating whether the visibility of a <see cref="Layer"/>
/// is used to determine when the legend for the layer is displayed.
/// </summary>
/// <value>
/// If <c>true</c>, legend for the layer and sublayers is displayed only when the layer's <see cref="ILayerContent.IsVisible"/> property is true.
/// </value>
public bool FilterHiddenLayers
{
get { return (bool)GetValue(FilterHiddenLayersProperty); }
set { SetValue(FilterHiddenLayersProperty, value); }
}
/// <summary>
/// Identifies the <see cref="ReverseLayerOrder"/> bindable property.
/// </summary>
public static readonly BindableProperty ReverseLayerOrderProperty =
BindableProperty.Create(nameof(ReverseLayerOrder), typeof(bool), typeof(Legend), true, BindingMode.OneWay, propertyChanged: OnReverseLayerOrderPropertyChanged);
private static void OnReverseLayerOrderPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
((Legend)bindable)._datasource.ReverseLayerOrder = (bool)newValue;
}
/// <summary>
/// Gets or sets a value indicating whether the order of layers in the <see cref="GeoView"/> are displayed top to bottom.
/// </summary>
/// <value>
/// If <c>true</c>, legend for layers is displayed from top to bottom order;
/// otherwise, <c>false</c>, legend for layers is displayed from bottom to top order.
/// </value>
public bool ReverseLayerOrder
{
get { return (bool)GetValue(ReverseLayerOrderProperty); }
set { SetValue(ReverseLayerOrderProperty, value); }
}
/// <summary>
/// Identifies the <see cref="LayerItemTemplate"/> bindable property.
/// </summary>
public static readonly BindableProperty LayerItemTemplateProperty =
BindableProperty.Create(nameof(LayerItemTemplate), typeof(DataTemplate), typeof(Legend), s_DefaultLayerItemTemplate, BindingMode.OneWay, null);
/// <summary>
/// Gets or sets the item template for each <see cref="Layer" /> entry.
/// </summary>
/// <remarks>
/// If this is set to null, the <see cref="SublayerItemTemplate"/> will be used instead.
/// </remarks>
/// <seealso cref="SublayerItemTemplate"/>
/// <seealso cref="LegendInfoItemTemplate"/>
public DataTemplate? LayerItemTemplate
{
get { return GetValue(LayerItemTemplateProperty) as DataTemplate; }
set { SetValue(LayerItemTemplateProperty, value); }
}
/// <summary>
/// Identifies the <see cref="SublayerItemTemplate"/> bindable property.
/// </summary>
public static readonly BindableProperty SublayerItemTemplateProperty =
BindableProperty.Create(nameof(SublayerItemTemplate), typeof(DataTemplate), typeof(Legend), s_DefaultSublayerItemTemplate, BindingMode.OneWay, null);
/// <summary>
/// Gets or sets the item template for each <see cref="ILayerContent"/> entry that is not a <see cref="Layer"/>.
/// </summary>
/// <seealso cref="LegendInfoItemTemplate"/>
/// <seealso cref="LayerItemTemplate"/>
public DataTemplate? SublayerItemTemplate
{
get { return GetValue(SublayerItemTemplateProperty) as DataTemplate; }
set { SetValue(SublayerItemTemplateProperty, value); }
}
/// <summary>
/// Identifies the <see cref="LegendInfoItemTemplate"/> bindable property.
/// </summary>
public static readonly BindableProperty LegendInfoItemTemplateProperty =
BindableProperty.Create(nameof(LegendInfoItemTemplate), typeof(DataTemplate), typeof(Legend), s_DefaultLegendInfoItemTemplate, BindingMode.OneWay, null);
/// <summary>
/// Gets or sets the item template for each <see cref="LegendInfo"/> content entry.
/// </summary>
/// <seealso cref="SublayerItemTemplate"/>
/// <seealso cref="LayerItemTemplate"/>
public DataTemplate? LegendInfoItemTemplate
{
get { return GetValue(LegendInfoItemTemplateProperty) as DataTemplate; }
set { SetValue(LegendInfoItemTemplateProperty, value); }
}
}