Beispiel #1
0
        void SetElementExpanded(ILiveElement element, bool expand)
        {
            var expandState = _expandMap.GetOrCreateValue(element);

            expandState.IsExpanded = expand;
            _expandToggled.OnNext(Unit.Default);
        }
        public static IEnumerable <ILiveElement> DescendantsAndSelf(this ILiveElement element)
        {
            yield return(element);

            foreach (var descendant in element.Children.Value.SelectMany(DescendantsAndSelf))
            {
                yield return(descendant);
            }
        }
Beispiel #3
0
        bool GetElementExpanded(ILiveElement element, bool fallback)
        {
            ElementExpandState expandState;

            if (_expandMap.TryGetValue(element, out expandState))
            {
                return(expandState.IsExpanded);
            }

            return(fallback);
        }
Beispiel #4
0
 public void Update(
     ILiveElement element,
     int depth,
     int rowOffset,
     int expandedDescendantCount,
     bool expandToggleEnabled,
     bool isExpanded,
     bool isSelected,
     bool isAncestorSelected,
     bool isDescendantSelected)
 {
     _element.OnNextDistinct(Optional.Some(element));
     _rowOffset.OnNextDistinct(rowOffset);
     _expandedDescendantCount.OnNextDistinct(expandedDescendantCount);
     _depth.OnNextDistinct(depth);
     _isExpanded.OnNextDistinct(isExpanded);
     _expandToggleEnabled.OnNextDistinct(expandToggleEnabled);
     _isSelected.OnNextDistinct(isSelected);
     _isAncestorSelected.OnNextDistinct(isAncestorSelected);
     _isDescendantSelected = isDescendantSelected;
 }
Beispiel #5
0
            static ILiveElement[] GetSelectionPath(ILiveElement root, Optional <ILiveElement> selectedElement)
            {
                if (!selectedElement.HasValue)
                {
                    return new ILiveElement[] { }
                }
                ;

                // First we count depth and see if selection is descendant of our root
                var selected = selectedElement.Value;
                var current  = selected;
                int depth    = 0;

                while (current != root)
                {
                    var liveParent = current.Parent as ILiveElement;

                    if (liveParent == null)
                    {
                        return(new ILiveElement[] { });
                    }
                    depth++;
                    current = liveParent;
                }

                // Then we walk down again and build the selection array
                var selectionPath = new ILiveElement[depth + 1];

                current = selected;
                do
                {
                    selectionPath[depth] = current;
                    current = current.Parent as ILiveElement;
                } while (depth-- > 0);

                return(selectionPath);
            }
        }
Beispiel #6
0
            State ScanElementTree(
                ILiveElement root,
                int visibleRowCount,
                int visibleRowOffset,
                Optional <ILiveElement> selectedElement,
                Optional <ILiveElement> previewElement)
            {
                // Update visible rows  ake sure we have enough
                var updates             = new Dictionary <ILiveElement, Action <RowModel> >();
                var allExpandedElements = new List <ILiveElement>(_allExpandedElements.Count * 2);

                var selectedElementRowOffset = Optional.None <int>();
                var previewElementRowOffset  = Optional.None <int>();

                ScanElementTree(
                    treeModel: this._tree,
                    element: root,
                    updates: updates,
                    allExpandedElements: allExpandedElements,
                    visibleRowCount: visibleRowCount,
                    visibleRowOffset: visibleRowOffset,
                    depth: 0,
                    selectionPath: GetSelectionPath(root, selectedElement),
                    previewElement: previewElement,
                    isAncestorSelected: false,
                    selectedElementRowOffset: ref selectedElementRowOffset,
                    previewElementRowOffset: ref previewElementRowOffset);

                return(new State(
                           _tree,
                           VisibleRows,
                           allExpandedElements.Count,
                           visibleRows => UpdateRows(visibleRows, updates),
                           selectedElementRowOffset,
                           visibleRowOffset,
                           visibleRowCount,
                           allExpandedElements));
            }
Beispiel #7
0
            Optional <Action> GetDropAction(ILiveElement thisElement, DropPosition position, object dragged)
            {
                var draggedElement = dragged as ILiveElement;
                var sourceFragment = dragged as SourceFragment;
                var bytes          = dragged as byte[];

                Func <SourceFragment> cut;

                if (draggedElement != null)
                {
                    var node = thisElement;
                    while (node != null)
                    {
                        if (node.Equals(draggedElement))
                        {
                            return(Optional.None());
                        }
                        node = node.Parent as ILiveElement;
                    }

                    cut = () => draggedElement.Cut().Result;
                }
                else if (bytes != null)
                {
                    cut = () => SourceFragment.FromBytes(bytes);
                }
                else if (sourceFragment != null)
                {
                    cut = () => sourceFragment;
                }
                else
                {
                    return(Optional.None());
                }

                switch (position)
                {
                case DropPosition.Inside:
                    if (!_isExpanded.Value)
                    {
                        return((Action)(
                                   () =>
                        {
                            var src = cut();
                            var element = thisElement.Paste(src);
                            _tree._context.Select(element);
                        }));
                    }
                    break;

                case DropPosition.After:
                case DropPosition.Before:
                    if (_depth.Value > 0)
                    {
                        return((Action)(() =>
                        {
                            var src = cut();
                            var element = position == DropPosition.Before ? thisElement.PasteBefore(src) : thisElement.PasteAfter(src);
                            _tree._context.Select(element);
                        }));
                    }
                    break;
                }

                return(Optional.None());
            }
Beispiel #8
0
 static bool CanExpand(ILiveElement element, int depth)
 {
     return(element.Children.Value.Any() && (depth == 0 || !element.UxClass().Value.HasValue));
 }
Beispiel #9
0
            /// <summary>
            /// Walks through all expanded elements of tree, adding actions to updates for pending row updates.
            /// Returns index of selected element
            /// </summary>
            static void ScanElementTree(
                TreeViewModel treeModel,
                ILiveElement element,
                Dictionary <ILiveElement, Action <RowModel> > updates,
                List <ILiveElement> allExpandedElements,
                int visibleRowCount,
                int visibleRowOffset,
                int depth,
                ILiveElement[] selectionPath,
                Optional <ILiveElement> previewElement,
                bool isAncestorSelected,
                ref Optional <int> selectedElementRowOffset,
                ref Optional <int> previewElementRowOffset)
            {
                var rowOffset = allExpandedElements.Count;

                allExpandedElements.Add(element);

                // A node with children can expand, unless it has a "ux:Class" attribute
                var canExpand = CanExpand(element, depth);

                // We expand up to 2 levels by default
                var expandByDefault = depth < 2;

                // Check if this element is an ancestor of selection
                var isDescendantSelected = depth < (selectionPath.Length - 1) && selectionPath[depth].Equals(element);

                // This is the selected element when we're at the end of the selection path
                var isSelected = depth == (selectionPath.Length - 1) && selectionPath[depth].Equals(element);

                var isExpanded = canExpand && (isDescendantSelected || treeModel.GetElementExpanded(element, expandByDefault));

                if (previewElement.Select(pe => pe == element).Or(false))
                {
                    previewElementRowOffset = rowOffset;
                }

                if (isSelected)
                {
                    selectedElementRowOffset = rowOffset;
                }

                var children = element.Children.Value;


                if (isExpanded)
                {
                    foreach (var child in children)
                    {
                        ScanElementTree(
                            treeModel: treeModel,
                            element: child,
                            updates: updates,
                            allExpandedElements: allExpandedElements,
                            visibleRowCount: visibleRowCount,
                            visibleRowOffset: visibleRowOffset,
                            depth: depth + 1,
                            selectionPath: selectionPath,
                            previewElement: previewElement,
                            isAncestorSelected: isSelected | isAncestorSelected,
                            selectedElementRowOffset: ref selectedElementRowOffset,
                            previewElementRowOffset: ref previewElementRowOffset);
                    }
                }

                var lastDescendantRowOffset = allExpandedElements.Count - 1;

                if ((rowOffset >= visibleRowOffset && rowOffset < visibleRowOffset + visibleRowCount) ||
                    (rowOffset < visibleRowOffset && lastDescendantRowOffset >= visibleRowOffset))
                {
                    updates[element] = rowModel => rowModel.Update(
                        element: element,
                        depth: depth,
                        rowOffset: rowOffset,
                        expandedDescendantCount: lastDescendantRowOffset - rowOffset,
                        expandToggleEnabled: depth > 0 && canExpand,                         // Don't allow collapse of root
                        isExpanded: isExpanded,
                        isSelected: isSelected,
                        isAncestorSelected: isAncestorSelected,
                        isDescendantSelected: isDescendantSelected);
                }
            }
 public static IBehaviorProperty <Optional <string> > UxClass(this ILiveElement element)
 {
     return(element["ux:Class"]);
 }