~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/xwt/Xwt.WPF/Xwt.WPFBackend/TreeViewBackend.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
ļ»æ//
 
2
// TreeViewBackend.cs
 
3
//
 
4
// Author:
 
5
//       Eric Maupin <ermau@xamarin.com>
 
6
//
 
7
// Copyright (c) 2012 Xamarin, Inc.
 
8
//
 
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
10
// of this software and associated documentation files (the "Software"), to deal
 
11
// in the Software without restriction, including without limitation the rights
 
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
13
// copies of the Software, and to permit persons to whom the Software is
 
14
// furnished to do so, subject to the following conditions:
 
15
//
 
16
// The above copyright notice and this permission notice shall be included in
 
17
// all copies or substantial portions of the Software.
 
18
//
 
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
25
// THE SOFTWARE.
 
26
 
 
27
using System;
 
28
using System.Collections.Generic;
 
29
using System.Linq;
 
30
using System.Windows.Data;
 
31
using System.Windows.Documents;
 
32
using System.Windows.Markup;
 
33
using System.Windows.Media;
 
34
using System.Windows.Shapes;
 
35
using Xwt.Engine;
 
36
using Xwt.Backends;
 
37
using Xwt.WPFBackend.Utilities;
 
38
using System.Windows;
 
39
using SWC=System.Windows.Controls;
 
40
using System.Windows.Controls;
 
41
 
 
42
namespace Xwt.WPFBackend
 
43
{
 
44
        public class TreeViewBackend
 
45
                : WidgetBackend, ITreeViewBackend
 
46
        {
 
47
                private static readonly ResourceDictionary TreeResourceDictionary;
 
48
                static TreeViewBackend()
 
49
                {
 
50
                        Uri uri = new Uri ("pack://application:,,,/Xwt.WPF;component/XWT.WPFBackend/TreeView.xaml");
 
51
                        TreeResourceDictionary = (ResourceDictionary)XamlReader.Load (System.Windows.Application.GetResourceStream (uri).Stream);
 
52
                }
 
53
 
 
54
                public TreeViewBackend ()
 
55
                {
 
56
                        Tree = new ExTreeView();
 
57
                        Tree.Resources.MergedDictionaries.Add (TreeResourceDictionary);
 
58
                        Tree.ItemTemplate = new HierarchicalDataTemplate { ItemsSource = new Binding ("Children") };
 
59
                        Tree.SetValue (VirtualizingStackPanel.IsVirtualizingProperty, true);
 
60
                }
 
61
                
 
62
                public ScrollPolicy VerticalScrollPolicy {
 
63
                        get { return ScrollViewer.GetVerticalScrollBarVisibility (Tree).ToXwtScrollPolicy (); }
 
64
                        set { ScrollViewer.SetVerticalScrollBarVisibility (Tree, value.ToWpfScrollBarVisibility ()); }
 
65
                }
 
66
 
 
67
                public ScrollPolicy HorizontalScrollPolicy {
 
68
                        get { return ScrollViewer.GetHorizontalScrollBarVisibility (Tree).ToXwtScrollPolicy (); }
 
69
                        set { ScrollViewer.SetHorizontalScrollBarVisibility (Tree, value.ToWpfScrollBarVisibility ()); }
 
70
                }
 
71
 
 
72
                public TreePosition[] SelectedRows {
 
73
                        get { return Tree.SelectedItems.Cast<TreePosition> ().ToArray (); }
 
74
                }
 
75
 
 
76
                private bool headersVisible = true;
 
77
                public bool HeadersVisible {
 
78
                        get { return this.headersVisible; }
 
79
                        set
 
80
                        {
 
81
                                this.headersVisible = value;
 
82
                                if (value) {
 
83
                                        if (Tree.View.ColumnHeaderContainerStyle != null)
 
84
                                                Tree.View.ColumnHeaderContainerStyle.Setters.Remove (HideHeaderSetter);
 
85
                                } else {
 
86
                                        if (Tree.View.ColumnHeaderContainerStyle == null)
 
87
                                                Tree.View.ColumnHeaderContainerStyle = new Style();
 
88
 
 
89
                                    Tree.View.ColumnHeaderContainerStyle.Setters.Add (HideHeaderSetter);
 
90
                                }
 
91
                        }
 
92
                }
 
93
 
 
94
                public void SelectRow (TreePosition pos)
 
95
                {
 
96
                        Tree.SelectedItems.Add (pos);
 
97
                }
 
98
 
 
99
                public void UnselectRow (TreePosition pos)
 
100
                {
 
101
                        Tree.SelectedItems.Remove (pos);
 
102
                }
 
103
 
 
104
                public bool IsRowSelected (TreePosition row)
 
105
                {
 
106
                        return Tree.SelectedItems.Contains (row);
 
107
                }
 
108
 
 
109
                public bool IsRowExpanded (TreePosition row)
 
110
                {
 
111
                        return ((TreeStoreNode) row).IsExpanded;
 
112
                }
 
113
 
 
114
                public void ExpandToRow (TreePosition pos)
 
115
                {
 
116
                        TreeStoreNode parent = ((TreeStoreNode) pos).Parent;
 
117
                        if (parent != null)
 
118
                            parent.IsExpanded = true;
 
119
                }
 
120
 
 
121
                public void ExpandRow (TreePosition row, bool expandChildren)
 
122
                {
 
123
                        TreeStoreNode node = ((TreeStoreNode) row);
 
124
                        node.IsExpanded = true;
 
125
 
 
126
                        if (expandChildren) {
 
127
                            foreach (TreeStoreNode childNode in node.Children)
 
128
                                childNode.IsExpanded = true;
 
129
                        }
 
130
                }
 
131
 
 
132
                public void CollapseRow (TreePosition row)
 
133
                {
 
134
                        ((TreeStoreNode) row).IsExpanded = false;
 
135
                }
 
136
 
 
137
                public void ScrollToRow (TreePosition pos)
 
138
                {
 
139
                        GetVisibleTreeItem (pos).BringIntoView();
 
140
                }
 
141
 
 
142
                public void SetSelectionMode (SelectionMode mode)
 
143
                {
 
144
                        Tree.SelectionMode = (mode == SelectionMode.Single)
 
145
                                                ? SWC.SelectionMode.Single
 
146
                                                : SWC.SelectionMode.Extended;
 
147
                }
 
148
 
 
149
                public void SelectAll ()
 
150
                {
 
151
                        Tree.SelectAllExpanded();
 
152
                }
 
153
 
 
154
                public void UnselectAll ()
 
155
                {
 
156
                        Tree.UnselectAll();
 
157
                }
 
158
 
 
159
                public void SetSource (ITreeDataSource source, IBackend sourceBackend)
 
160
                {
 
161
                        Tree.ItemsSource = (TreeStoreBackend) sourceBackend;
 
162
                }
 
163
 
 
164
                public object AddColumn (ListViewColumn column)
 
165
                {
 
166
                        var col = new GridViewColumn ();
 
167
 
 
168
                        UpdateColumn (column, col, ListViewColumnChange.Title);
 
169
 
 
170
                        Tree.View.Columns.Add (col);
 
171
                        
 
172
                        UpdateColumn (column, col, ListViewColumnChange.Cells);
 
173
 
 
174
                        return col;
 
175
                }
 
176
 
 
177
                public void UpdateColumn (ListViewColumn column, object handle, ListViewColumnChange change)
 
178
                {
 
179
                        var col = ((GridViewColumn) handle);
 
180
                        switch (change) {
 
181
                        case ListViewColumnChange.Title:
 
182
                                col.Header = column.Title;
 
183
                                break;
 
184
 
 
185
                        case ListViewColumnChange.Cells:
 
186
                                var cellTemplate = CellUtil.CreateBoundColumnTemplate (column.Views);
 
187
 
 
188
                                col.CellTemplate = new DataTemplate { VisualTree = cellTemplate };
 
189
 
 
190
                                int index = Tree.View.Columns.IndexOf (col);
 
191
                                if (index == 0) {
 
192
                                        var dockFactory = CreateExpanderDock ();
 
193
                                        dockFactory.AppendChild (cellTemplate);
 
194
 
 
195
                                        col.CellTemplate.VisualTree = dockFactory;
 
196
                                }
 
197
 
 
198
                                break;
 
199
                        }
 
200
                }
 
201
 
 
202
                public void RemoveColumn (ListViewColumn column, object handle)
 
203
                {
 
204
                        Tree.View.Columns.Remove ((GridViewColumn) handle);
 
205
                }
 
206
 
 
207
                private RowDropPosition dropPosition;
 
208
                private ExTreeViewItem dropTarget;
 
209
                private Adorner dropAdorner;
 
210
                public bool GetDropTargetRow (double x, double y, out RowDropPosition pos, out TreePosition nodePosition)
 
211
                {
 
212
                        nodePosition = null;
 
213
                        this.dropPosition = pos = RowDropPosition.Into;
 
214
 
 
215
                        x *= WidthPixelRatio;
 
216
                        y *= HeightPixelRatio;
 
217
 
 
218
                        var result = VisualTreeHelper.HitTest (Tree, new System.Windows.Point (x, y)) as PointHitTestResult;
 
219
 
 
220
                        var element = (result != null) ? result.VisualHit as FrameworkElement : null;
 
221
                        while (element != null) {
 
222
                                if (element is ExTreeViewItem)
 
223
                                        break;
 
224
                                if (element is ExTreeView) // We can't succeed past this point
 
225
                                        return false;
 
226
 
 
227
                                element = VisualTreeHelper.GetParent (element) as FrameworkElement;
 
228
                        }
 
229
                        
 
230
                        this.dropTarget = (ExTreeViewItem)element;
 
231
                        
 
232
                        if (element == null)
 
233
                                return false;
 
234
 
 
235
                        var point = ((UIElement)result.VisualHit).TranslatePoint (result.PointHit, element);
 
236
 
 
237
                        double edge = element.ActualHeight * 0.15;
 
238
                        if (point.Y <= edge)
 
239
                                this.dropPosition = pos = RowDropPosition.Before;
 
240
                        else if (point.Y >= element.ActualHeight - edge)
 
241
                                this.dropPosition = pos = RowDropPosition.After;
 
242
 
 
243
                        nodePosition = element.DataContext as TreeStoreNode;
 
244
                        return true;
 
245
                }
 
246
 
 
247
                public override void EnableEvent (object eventId)
 
248
                {
 
249
                        base.EnableEvent (eventId);
 
250
                        if (eventId is TableViewEvent) {
 
251
                                switch ((TableViewEvent)eventId) {
 
252
                                case TableViewEvent.SelectionChanged:
 
253
                                        Tree.SelectedItemsChanged += OnSelectedItemsChanged;
 
254
                                        break;
 
255
                                }
 
256
                        }
 
257
                }
 
258
 
 
259
                public override void DisableEvent (object eventId)
 
260
                {
 
261
                        base.DisableEvent (eventId);
 
262
                        if (eventId is TableViewEvent) {
 
263
                                switch ((TableViewEvent)eventId) {
 
264
                                case TableViewEvent.SelectionChanged:
 
265
                                        Tree.SelectedItemsChanged -= OnSelectedItemsChanged;
 
266
                                        break;
 
267
                                }
 
268
                        }
 
269
                }
 
270
 
 
271
                protected ExTreeView Tree {
 
272
                        get { return (ExTreeView)Widget; }
 
273
                        set { Widget = value; }
 
274
                }
 
275
 
 
276
                protected ITreeViewEventSink TreeViewEventSink {
 
277
                        get { return (ITreeViewEventSink)EventSink; }
 
278
                }
 
279
 
 
280
                protected override double DefaultNaturalHeight {
 
281
                        get { return -1; }
 
282
                }
 
283
 
 
284
                protected override double DefaultNaturalWidth {
 
285
                        get { return -1; }
 
286
                }
 
287
 
 
288
                public override WidgetSize GetPreferredHeight()
 
289
                {
 
290
                        return new WidgetSize (0);
 
291
                }
 
292
 
 
293
                public override WidgetSize GetPreferredHeightForWidth(double width)
 
294
                {
 
295
                        return GetPreferredHeight ();
 
296
                }
 
297
 
 
298
                public override WidgetSize GetPreferredWidth()
 
299
                {
 
300
                        return new WidgetSize (0);
 
301
                }
 
302
 
 
303
                public override WidgetSize GetPreferredWidthForHeight(double height)
 
304
                {
 
305
                        return GetPreferredWidth ();
 
306
                }
 
307
 
 
308
                private void OnSelectedItemsChanged (object sender, EventArgs e)
 
309
                {
 
310
                        Toolkit.Invoke (TreeViewEventSink.OnSelectionChanged);
 
311
                }
 
312
 
 
313
                protected override void OnDragOver (object sender, DragOverEventArgs e)
 
314
                {
 
315
                        AdornerLayer layer = AdornerLayer.GetAdornerLayer (Widget);
 
316
                        if (this.dropAdorner != null)
 
317
                            layer.Remove (this.dropAdorner);
 
318
 
 
319
                        base.OnDragOver (sender, e);
 
320
 
 
321
                        if (this.dropTarget != null)
 
322
                            layer.Add (this.dropAdorner = new TreeViewDropAdorner (this.dropTarget, this.dropPosition));
 
323
                }
 
324
 
 
325
                protected override void OnDragLeave (object sender, EventArgs e)
 
326
                {
 
327
                        base.OnDragLeave (sender, e);
 
328
 
 
329
                        if (this.dropAdorner != null)
 
330
                                AdornerLayer.GetAdornerLayer (Widget).Remove (this.dropAdorner);
 
331
                }
 
332
 
 
333
                protected override void OnDragFinished (object sender, DragFinishedEventArgs e)
 
334
                {
 
335
                        base.OnDragFinished (sender, e);
 
336
 
 
337
                        if (this.dropAdorner != null)
 
338
                                AdornerLayer.GetAdornerLayer (Widget).Remove (this.dropAdorner);
 
339
                }
 
340
 
 
341
                private ExTreeViewItem GetVisibleTreeItem (TreePosition pos, Action<ExTreeViewItem> walk = null)
 
342
                {
 
343
                        Tree.UpdateLayout();
 
344
                        Stack<TreeStoreNode> nodes = new Stack<TreeStoreNode> ();
 
345
 
 
346
                        TreeStoreNode node = (TreeStoreNode) pos;
 
347
                        do {
 
348
                                nodes.Push (node);
 
349
                                node = node.Parent;
 
350
                        } while (node != null);
 
351
 
 
352
                        ExTreeViewItem treeItem = null;
 
353
                        ItemContainerGenerator g = Tree.ItemContainerGenerator;
 
354
                        while (nodes.Count > 0) {
 
355
                                node = nodes.Pop ();
 
356
                                treeItem = (ExTreeViewItem) g.ContainerFromItem (node);
 
357
                                treeItem.UpdateLayout ();
 
358
                                g = treeItem.ItemContainerGenerator;
 
359
 
 
360
                                if (walk != null)
 
361
                                        walk (treeItem);
 
362
                        }
 
363
 
 
364
                        return treeItem;
 
365
                }
 
366
 
 
367
                private FrameworkElementFactory CreateExpanderDock ()
 
368
                {
 
369
                        var dockFactory = new FrameworkElementFactory (typeof (DockPanel));
 
370
 
 
371
                        var source = new RelativeSource (RelativeSourceMode.FindAncestor, typeof (ExTreeViewItem), 1);
 
372
 
 
373
                        Style expanderStyle = new Style (typeof (SWC.Primitives.ToggleButton));
 
374
                        expanderStyle.Setters.Add (new Setter (UIElement.FocusableProperty, false));
 
375
                        expanderStyle.Setters.Add (new Setter (FrameworkElement.WidthProperty, 19d));
 
376
                        expanderStyle.Setters.Add (new Setter (FrameworkElement.HeightProperty, 13d));
 
377
 
 
378
                        var expanderTemplate = new ControlTemplate (typeof (SWC.Primitives.ToggleButton));
 
379
 
 
380
                        var outerBorderFactory = new FrameworkElementFactory (typeof (Border));
 
381
                        outerBorderFactory.SetValue (FrameworkElement.WidthProperty, 19d);
 
382
                        outerBorderFactory.SetValue (FrameworkElement.HeightProperty, 13d);
 
383
                        outerBorderFactory.SetValue (Control.BackgroundProperty, Brushes.Transparent);
 
384
                        outerBorderFactory.SetBinding (UIElement.VisibilityProperty,
 
385
                                new Binding ("HasItems") { RelativeSource = source, Converter = BoolVisibilityConverter });
 
386
 
 
387
                        var innerBorderFactory = new FrameworkElementFactory (typeof (Border));
 
388
                        innerBorderFactory.SetValue (FrameworkElement.WidthProperty, 9d);
 
389
                        innerBorderFactory.SetValue (FrameworkElement.HeightProperty, 9d);
 
390
                        innerBorderFactory.SetValue (Control.BorderThicknessProperty, new Thickness (1));
 
391
                        innerBorderFactory.SetValue (Control.BorderBrushProperty, new SolidColorBrush (Color.FromRgb (120, 152, 181)));
 
392
                        innerBorderFactory.SetValue (Border.CornerRadiusProperty, new CornerRadius (1));
 
393
                        innerBorderFactory.SetValue (UIElement.SnapsToDevicePixelsProperty, true);
 
394
 
 
395
                        innerBorderFactory.SetValue (Control.BackgroundProperty, ExpanderBackgroundBrush);
 
396
 
 
397
                        var pathFactory = new FrameworkElementFactory (typeof (Path));
 
398
                        pathFactory.SetValue (FrameworkElement.MarginProperty, new Thickness (1));
 
399
                        pathFactory.SetValue (Shape.FillProperty, Brushes.Black);
 
400
                        pathFactory.SetBinding (Path.DataProperty, 
 
401
                                new Binding ("IsChecked") {
 
402
                                        RelativeSource = new RelativeSource (RelativeSourceMode.FindAncestor, typeof (SWC.Primitives.ToggleButton), 1),
 
403
                                        Converter = BooleanGeometryConverter
 
404
                        });
 
405
 
 
406
                        innerBorderFactory.AppendChild (pathFactory);
 
407
                        outerBorderFactory.AppendChild (innerBorderFactory);
 
408
 
 
409
                        expanderTemplate.VisualTree = outerBorderFactory;
 
410
 
 
411
                        expanderStyle.Setters.Add (new Setter (Control.TemplateProperty, expanderTemplate));
 
412
 
 
413
                        var toggleFactory = new FrameworkElementFactory (typeof (SWC.Primitives.ToggleButton));
 
414
                        toggleFactory.SetValue (FrameworkElement.StyleProperty, expanderStyle);
 
415
                        toggleFactory.SetBinding (FrameworkElement.MarginProperty,
 
416
                                new Binding ("Level") { RelativeSource = source, Converter = LevelConverter });
 
417
                        toggleFactory.SetBinding (SWC.Primitives.ToggleButton.IsCheckedProperty,
 
418
                                new Binding ("IsExpanded") { RelativeSource = source });
 
419
                        toggleFactory.SetValue (SWC.Primitives.ButtonBase.ClickModeProperty, ClickMode.Press);
 
420
 
 
421
                        dockFactory.AppendChild (toggleFactory);
 
422
                        return dockFactory;
 
423
                }
 
424
 
 
425
                private static readonly LevelToIndentConverter LevelConverter = new LevelToIndentConverter();
 
426
                private static readonly BooleanToVisibilityConverter BoolVisibilityConverter = new BooleanToVisibilityConverter();
 
427
 
 
428
                private static readonly LinearGradientBrush ExpanderBackgroundBrush = new LinearGradientBrush {
 
429
                        StartPoint = new System.Windows.Point (0, 0),
 
430
                        EndPoint = new System.Windows.Point (1, 1),
 
431
                        GradientStops = new GradientStopCollection {
 
432
                                new GradientStop (Colors.White, 0.2),
 
433
                                new GradientStop (Color.FromRgb (192, 183, 166), 1)
 
434
                        }
 
435
                };
 
436
 
 
437
                private static readonly Geometry Plus = Geometry.Parse ("M 0 2 L 0 3 L 2 3 L 2 5 L 3 5 L 3 3 L 5 3 L 5 2 L 3 2 L 3 0 L 2 0 L 2 2 Z");
 
438
                private static readonly Geometry Minus = Geometry.Parse ("M 0 2 L 0 3 L 5 3 L 5 2 Z");
 
439
 
 
440
                private static readonly BooleanToValueConverter BooleanGeometryConverter = 
 
441
                        new BooleanToValueConverter { TrueValue = Minus, FalseValue = Plus };
 
442
 
 
443
                private static readonly Setter HideHeaderSetter = new Setter (UIElement.VisibilityProperty, Visibility.Collapsed);
 
444
        }
 
445
}