private Dock GetHitSide(MetroStartPage targetPage, MetroTile hitTile, MetroTile dragTile, Point pos) { // For vertically oriented pages, if dragging a small tile and the hit tile is also small, // treat as if horizontal oriented. if (targetPage.Orientation == Orientation.Vertical && !(hitTile.Type == MetroTileType.Small && dragTile.Type == MetroTileType.Small)) { double dY = (hitTile.RenderSize.Height / 2) - pos.Y; if (dY > 0) { return(Dock.Top); } return(Dock.Bottom); } else { double dX = (hitTile.RenderSize.Width / 2) - pos.X; if (dX > 0) { return(Dock.Left); } return(Dock.Right); } }
private void ClearDropTargetState(MetroTile tile) { VisualStateManager.GoToState(tile, "NoDrop", true); }
private void UpdateDropTargetTiles(MetroTile newDropTarget, MetroTile newDropTarget2, MetroTile newSecondary, MetroTile newSecondary2, Dock side) { if (!IsOneOfOrNull(_DropTargetTile, newDropTarget, newDropTarget2, newSecondary, newSecondary2)) { ClearDropTargetState(_DropTargetTile); } if (!IsOneOfOrNull(_DropTargetTile2, newDropTarget, newDropTarget2, newSecondary, newSecondary2)) { ClearDropTargetState(_DropTargetTile2); } if (!IsOneOfOrNull(_SecondaryDropTargetTile, newDropTarget, newDropTarget2, newSecondary, newSecondary2)) { ClearDropTargetState(_SecondaryDropTargetTile); } if (!IsOneOfOrNull(_SecondaryDropTargetTile2, newDropTarget, newDropTarget2, newSecondary, newSecondary2)) { ClearDropTargetState(_SecondaryDropTargetTile2); } _DropTargetTile = newDropTarget; _DropTargetTile2 = newDropTarget2; _SecondaryDropTargetTile = newSecondary; _SecondaryDropTargetTile2 = newSecondary2; if (_DropTargetTile != null) { SetDropTargetState(_DropTargetTile, side); } if (_DropTargetTile2 != null) { SetDropTargetState(_DropTargetTile2, side); } if (_SecondaryDropTargetTile != null) { SetDropTargetState(_SecondaryDropTargetTile, OppositeSide(side)); } if (_SecondaryDropTargetTile2 != null) { SetDropTargetState(_SecondaryDropTargetTile2, OppositeSide(side)); } }
private MetroTile FindSecondaryTargetTile(MetroStartPage targetPage, MetroTile targetTile, MetroTile dragTile, Dock hitSide, out int dropIndex) { int targetIndex = targetPage.ItemContainerGenerator.IndexFromContainer(targetTile); dropIndex = targetIndex; if (targetTile == _DragHelper._DragTile) { return(null); } int sourceIndex = targetPage.ItemContainerGenerator.IndexFromContainer(dragTile); if (sourceIndex < 0) { sourceIndex = int.MaxValue; } int secondaryIndex = -1; if (hitSide == Dock.Top) { if (!IsTileOnPageTop(targetPage, targetTile)) { secondaryIndex = targetIndex - 1; } if (sourceIndex < targetIndex) { dropIndex--; } } else if (hitSide == Dock.Bottom) { if (!IsTileOnPageBottom(targetPage, targetTile)) { secondaryIndex = targetIndex + 1; } if (sourceIndex > targetIndex) { dropIndex++; } } else if (hitSide == Dock.Left) { if (!IsTileOnPageLeft(targetPage, targetTile)) { secondaryIndex = targetIndex - 1; } if (sourceIndex < targetIndex) { dropIndex--; } } else if (hitSide == Dock.Right) { if (!IsTileOnPageRight(targetPage, targetTile)) { secondaryIndex = targetIndex + 1; } if (sourceIndex > targetIndex) { dropIndex++; } } MetroTile secondary = null; if (secondaryIndex >= 0 && secondaryIndex < targetPage.Items.Count) { secondary = targetPage.ItemContainerGenerator.ContainerFromIndex(secondaryIndex) as MetroTile; // special case handling for when dropping small tile into empty space beside another small tile, // in this situation there should be no secondary. if (secondary != null && secondary.Type != MetroTileType.Small && secondary != dragTile && targetTile.Type == MetroTileType.Small && dragTile.Type == MetroTileType.Small) { secondary = null; } } return(secondary); }
private void SetDropTargetTiles(Point position, MetroStartPage dropTargetPage) { var dragTile = _DragHelper._DragTile; bool suppressAnimation = false; MetroTile secondaryTarget = null, target2 = null, secondaryTarget2 = null; var target = dropTargetPage.HitTestForOne <MetroTile>(position, _DragHelper._DragTile.Margin); if (target == null && dragTile.Type == MetroTileType.Small) { target = dropTargetPage.HitTestForOne <MetroTile>(position, new Thickness(0, 0, dragTile.Width, 0)); if (target != null && target.Type == MetroTileType.Large) { target = null; } suppressAnimation = true; } Dock hitSide = Dock.Left; if (target != null) { hitSide = GetHitSide(dropTargetPage, target, dragTile, dropTargetPage.TranslatePoint(position, target)); // If vertical orientation, and hitting a small tile, there might be another small tile beside it which also needs to be animated. if (_DropPage.Orientation == Orientation.Vertical && target.Type == MetroTileType.Small && dragTile.Type == MetroTileType.Large) { int index, adjacentIndex; target2 = FindAdjacentSmallTile(target, out index, out adjacentIndex); if (target2 != null) { // Might need to switch target and target2 because target defines the insertion index. if ((hitSide == Dock.Top && adjacentIndex < index) || (hitSide == Dock.Bottom && adjacentIndex > index)) { var temp = target; target = target2; target2 = temp; } } } // Look for secondary drop target if not dropping onto self or not dropping one small tile onto another small tile. secondaryTarget = FindSecondaryTargetTile(dropTargetPage, target, dragTile, hitSide, out _DropIndex); if (secondaryTarget != null && _DropPage.Orientation == Orientation.Vertical && secondaryTarget.Type == MetroTileType.Small && dragTile.Type == MetroTileType.Large) { int index, adjacentIndex; secondaryTarget2 = FindAdjacentSmallTile(secondaryTarget, out index, out adjacentIndex); } } else { _DropIndex = _DropPage.Items.Count; if (_DragHelper._DragSourcePage == _DropPage) { _DropIndex--; } } if (!suppressAnimation) { UpdateDropTargetTiles(target, target2, secondaryTarget, secondaryTarget2, hitSide); } else { UpdateDropTargetTiles(null, null, null, null, Dock.Left); } }