private void UpdateTopNode() { if (!inUpdateTopNode) { inUpdateTopNode = true; try { lock ( _nodeCollection ) { _topNode = null; int delta = _scrollOffset; IVisibleNodeEnumerator enumerator = _visibleNodeCollection.GetFullEnumerator(); while (enumerator.MoveNext()) { int height = GetRowHeight(enumerator.CurrentNode); if (delta < height) { _topNode = enumerator.CurrentNode; _topNodeOffset = delta; break; } delta -= height; } } } finally { inUpdateTopNode = false; } } }
public int GetWheelScrollDistance(int lines) { // the wheel scroll can be requested between BeginUpdate() and EndUpdate(), // when the node which was _topNode has already been removed from the collection // but UpdateTopNode() was not yet called (OM-10633) int result = 0; lock ( _nodeCollection ) { IViewNode topNode = _topNode; // avoid race condition (OM-11963) if (topNode != null && _visibleNodeCollection.IsNodeVisible(topNode)) { IVisibleNodeEnumerator enumerator = _visibleNodeCollection.GetDirectionalEnumerator(topNode, (lines < 0) ? MoveDirection.Up : MoveDirection.Down); while (enumerator.MoveNext() && lines != 0) { int rowHeight = GetRowHeight(enumerator.CurrentNode); if (lines > 0) { result += rowHeight; lines--; } else { result -= rowHeight; lines++; } } } } return(result); }
private void HandleMultipleNodesChanged(object sender, MultipleNodesChangedEventArgs e) { // ensure correct lock ordering - lock node collection before selection lock ( _nodeCollection ) { lock ( SelectionLock ) { if (Count > 0) { if (_nodeCollection.IsEmpty) { Clear(); } else { IViewNode[] selNodes = SelectionToArray(); foreach (IViewNode selNode in selNodes) { if (!_visibleNodeCollection.IsNodeVisible(selNode)) { UnselectNode(selNode); } } if (Count == 0) { IVisibleNodeEnumerator enumerator = _visibleNodeCollection.GetFullEnumerator(); if (enumerator.MoveNext()) { SelectAndFocusNode(enumerator.CurrentNode); } } } } } } }
private void RemoveNodeFromSelection(IViewNode viewNode) { if ((UnselectNode(viewNode) && Count == 0) || viewNode == _focusNode) { IViewNode nextNode = null, prevNode = null; IVisibleNodeEnumerator enumerator = _visibleNodeCollection.GetDirectionalEnumerator(viewNode, MoveDirection.Down); enumerator.MoveNext(); // make sure we don't move the selection to the node being deleted if we delete // the node and its group in one VisibleNodeRemoving operation if (enumerator.MoveNext() && enumerator.CurrentNode != _lastRemovedNode) { nextNode = enumerator.CurrentNode; } enumerator = _visibleNodeCollection.GetDirectionalEnumerator(viewNode, MoveDirection.Up); enumerator.MoveNext(); if (enumerator.MoveNext() && enumerator.CurrentNode != _lastRemovedNode) { prevNode = enumerator.CurrentNode; } if (nextNode == null) { if (prevNode != null) { SelectAndFocusNode(prevNode); } else { SetFocusNode(null); } } else if (prevNode != null && viewNode is JetListViewNode) { JetListViewNode prevLvNode = prevNode as JetListViewNode; JetListViewNode nextLvNode = nextNode as JetListViewNode; int removedNodeLevel = (viewNode as JetListViewNode).Level; if (prevLvNode != null && nextLvNode != null && prevLvNode.Level == removedNodeLevel && nextLvNode.Level != removedNodeLevel) { SelectAndFocusNode(prevNode); } else if (prevLvNode != null && nextLvNode != null && prevLvNode.Level != removedNodeLevel && nextLvNode.Level == removedNodeLevel) { SelectAndFocusNode(nextNode); } else if (prevNode == (viewNode as JetListViewNode).Parent) { SelectAndFocusNode(prevNode); } else if (prevLvNode != null && nextLvNode == null) { SelectAndFocusNode(prevNode); } else { SelectAndFocusNode(nextNode); } } else { SelectAndFocusNode(nextNode); } } _lastRemovedNode = viewNode; }
private void AdjustTopNode(int delta) { lock ( _nodeCollection ) { IViewNode topNode = _topNode; // avoid race conditions (OM-12038) if (topNode == null || !_visibleNodeCollection.IsNodeVisible(topNode)) { UpdateTopNode(); return; } try { IVisibleNodeEnumerator enumerator = _visibleNodeCollection.GetDirectionalEnumerator(topNode, (delta > 0) ? MoveDirection.Down : MoveDirection.Up); if (_topNodeOffset != 0) { if (delta > 0) { int curNodeDelta = GetRowHeight(topNode) - _topNodeOffset; if (delta < curNodeDelta) { _topNodeOffset += delta; return; } delta -= curNodeDelta; enumerator.MoveNext(); } else { if (_topNodeOffset >= -delta) { _topNodeOffset += delta; return; } delta += _topNodeOffset; } } if (delta < 0) { enumerator.MoveNext(); } int absDelta = Math.Abs(delta); _topNodeOffset = 0; while (enumerator.MoveNext()) { int curRowHeight = GetRowHeight(enumerator.CurrentNode); if (absDelta < curRowHeight) { if (delta > 0 || absDelta == 0) { _topNodeOffset = absDelta; } else { _topNodeOffset = curRowHeight - absDelta; } break; } absDelta -= curRowHeight; if (delta < 0 && absDelta == 0) { break; } } _topNode = enumerator.CurrentNode; } catch (ArgumentOutOfRangeException ex) // mega-hacky crappy fix for OM-11090 { Trace.WriteLine("Exception in UpdateTopNode: " + ex.ToString()); UpdateTopNode(); } } }