private static LabelSizeInfo GetLabelSize(FrameworkElement visual) { RadSize visualSize = GetVisualDesiredSize(visual); LabelSizeInfo sizeInfo = new LabelSizeInfo() { UntransformedSize = visualSize }; GeneralTransform transform = visual.RenderTransform; if (transform != null) { Rect labelRect = new Rect(0, 0, visualSize.Width, visualSize.Height); labelRect = transform.TransformBounds(labelRect); sizeInfo.TransformOffset = new RadPoint(labelRect.X, labelRect.Y); sizeInfo.Size = new RadSize(labelRect.Width, labelRect.Height); } else { sizeInfo.Size = visualSize; } return(sizeInfo); }
protected override void Invoke(object parameter) { if (Target != null) { if (DetailsPopup.AssociatedUIElement == _associatedElement) { return; } DetailsPopup.AssociatedUIElement = _associatedElement; if (PopupDataContext != null) { Target.DataContext = PopupDataContext; } //get the center y coordinate of the list item GeneralTransform gt = _associatedElement.TransformToVisual(Application.Current.RootVisual); Point topLeft = gt.Transform(new Point(0, 0)); double centerY = topLeft.Y + _associatedElement.ActualHeight / 2; double xOffset = GetXOffset(_currentMousePos); DetailsPopup.Show(Target, new Point(_currentMousePos.X, centerY), (int)xOffset, PopupContentContainerStyle, PopupLeaderStyle); } }
/// <summary> /// The get translated points. /// </summary> /// <param name="frameworkElement"> /// The framework element. /// </param> /// <returns> /// The <see><cref>Point[]</cref></see>. /// </returns> private static Point[] GetTranslatedPoints(FrameworkElement frameworkElement) { var pointArray = new Point[4]; var tooltip = frameworkElement as PinnableTooltip; if (tooltip == null || tooltip.IsOpen) { GeneralTransform generalTransform = frameworkElement.TransformToVisual( tooltip != null ? tooltip.adornerLayer : PinnableTooltipService.RootVisual); pointArray[0] = generalTransform.Transform(new Point(0.0, 0.0)); pointArray[1] = generalTransform.Transform(new Point(frameworkElement.ActualWidth, 0.0)); pointArray[1].X--; pointArray[2] = generalTransform.Transform(new Point(0.0, frameworkElement.ActualHeight)); pointArray[2].Y--; pointArray[3] = generalTransform.Transform(new Point(frameworkElement.ActualWidth, frameworkElement.ActualHeight)); pointArray[3].X--; pointArray[3].Y--; } return(pointArray); }
internal bool IsOnCurrentPage(ListBoxItem item) { var itemsHostRect = Rect.Empty; var listBoxItemRect = Rect.Empty; if (_visual == null) { Helpers.ItemsControlHelper ich = new Helpers.ItemsControlHelper(ListBox); ScrollContentPresenter scp = ich.ScrollHost == null ? null : ich.ScrollHost.GetVisualDescendants().OfType <ScrollContentPresenter>().FirstOrDefault(); _visual = (ich.ScrollHost == null) ? null : ((scp == null) ? ((FrameworkElement)ich.ScrollHost) : ((FrameworkElement)scp)); } if (_visual == null) { return(true); } itemsHostRect = new Rect(0.0, 0.0, _visual.ActualWidth, _visual.ActualHeight); //ListBoxItem item = ListBox.ItemContainerGenerator.ContainerFromIndex(index) as ListBoxItem; if (item == null) { listBoxItemRect = Rect.Empty; return(false); } GeneralTransform transform = item.TransformToVisual(_visual); listBoxItemRect = new Rect(transform.Transform(new Point()), transform.Transform(new Point(item.ActualWidth, item.ActualHeight))); if (!this.IsVerticalOrientation()) { return((itemsHostRect.Left <= listBoxItemRect.Left) && (listBoxItemRect.Right <= itemsHostRect.Right)); } return((listBoxItemRect.Bottom + 100 >= itemsHostRect.Top) && (listBoxItemRect.Top - 100 <= itemsHostRect.Bottom)); //return ((itemsHostRect.Top <= listBoxItemRect.Bottom) && (listBoxItemRect.Top <= itemsHostRect.Bottom)); }
private Point[] GetTransformedPoints(FrameworkElement element, bool isRTL, FrameworkElement relativeTo) { Point[] pointArray = new Point[4]; if ((element != null) && (relativeTo != null)) { GeneralTransform gt = relativeTo.TransformToVisual(_rootVisual); pointArray[0] = gt.TransformPoint(new Point(0.0, 0.0)); pointArray[1] = gt.TransformPoint(new Point(element.ActualWidth, 0.0)); pointArray[2] = gt.TransformPoint(new Point(0.0, element.ActualHeight)); pointArray[3] = gt.TransformPoint(new Point(element.ActualWidth, element.ActualHeight)); FrameworkElement _el = _rootVisual as FrameworkElement; bool flag = (_el != null) ? (_el.FlowDirection == FlowDirection.RightToLeft) : false; if (isRTL != flag) { // TODO: Handle RTL - GetTransformedPoints //for (int i = 0; i < pointArray.Length; i++) //{ // pointArray[i].X = _windowBounds.Width - pointArray[i].X; //} } } return(pointArray); }
private void MyDrawObject_DrawComplete(object sender, DrawEventArgs args) { ESRI.ArcGIS.Client.Geometry.MapPoint point = args.Geometry as ESRI.ArcGIS.Client.Geometry.MapPoint; point.SpatialReference = MyMap.SpatialReference; System.Windows.Point screenPnt = MyMap.MapToScreen(point); // Account for difference between Map and application origin GeneralTransform generalTransform = MyMap.TransformToVisual(null); System.Windows.Point transformScreenPnt = generalTransform.Transform(screenPnt); IEnumerable <Graphic> selected = parcelGraphicsLayer.FindGraphicsInHostCoordinates(transformScreenPnt); foreach (Graphic g in selected) { if (g.Selected) { g.UnSelect(); selectedGraphics.Remove(g); } else { g.Select(); selectedGraphics.Add(g); } } if (selectedGraphics.Count > 1) { UnionButton.IsEnabled = true; MyDrawObject.IsEnabled = false; } else { UnionButton.IsEnabled = false; } }
public ViewportInformation(Visual3DCollection children, Camera camera, Size bounds, GeneralTransform transform) { this.children = children; this.camera = camera; this.bounds = bounds; this.transform = transform; }
// If return false, nothing has been modified, which implies out of page boundary // The input of suggestedX is in the VisualRoot's cooridnate system private bool _GetNextLineGlyphs(ref FixedPosition fixedp, ref LogicalDirection edge, double suggestedX, LogicalDirection scanDir) { int count = 1; int pageIndex = fixedp.Page; bool moved = false; FixedNode[] fixedNodes = Container.FixedTextBuilder.GetNextLine(fixedp.Node, (scanDir == LogicalDirection.Forward), ref count); if (fixedNodes != null && fixedNodes.Length > 0) { FixedPage page = Container.FixedDocument.SyncGetPage(pageIndex, false); // This line contains multiple Glyhs. Scan backward // util we hit the first one whose OriginX is smaller // then suggestedX; if (Double.IsInfinity(suggestedX)) { suggestedX = 0; } Point topOfPage = new Point(suggestedX, 0); Point secondPoint = new Point(suggestedX, 1000); FixedNode hitNode = fixedNodes[0]; Glyphs hitGlyphs = null; double closestDistance = Double.MaxValue; double xoffset = 0; for (int i = fixedNodes.Length - 1; i >= 0; i--) { FixedNode node = fixedNodes[i]; Glyphs g = page.GetGlyphsElement(node); if (g != null) { GeneralTransform transform = page.TransformToDescendant(g); Point pt1 = topOfPage; Point pt2 = secondPoint; if (transform != null) { transform.TryTransform(pt1, out pt1); transform.TryTransform(pt2, out pt2); } double invSlope = (pt2.X - pt1.X) / (pt2.Y - pt1.Y); double xoff, distance; GlyphRun run = g.ToGlyphRun(); Rect box = run.ComputeAlignmentBox(); box.Offset(g.OriginX, g.OriginY); if (invSlope > 1000 || invSlope < -1000) { // special case for vertical text xoff = 0; distance = (pt1.Y > box.Y) ? (pt1.Y - box.Bottom) : (box.Y - pt1.Y); } else { double centerY = (box.Top + box.Bottom) / 2; xoff = pt1.X + invSlope * (centerY - pt1.Y); distance = (xoff > box.X) ? (xoff - box.Right) : (box.X - xoff); } if (distance < closestDistance) { closestDistance = distance; xoffset = xoff; hitNode = node; hitGlyphs = g; if (distance <= 0) { break; } } } } Debug.Assert(hitGlyphs != null); int charIdx; _GlyphRunHitTest(hitGlyphs, xoffset, out charIdx, out edge); fixedp = new FixedPosition(hitNode, charIdx); moved = true; } return(moved); }
/// <summary> /// Retrieves the height and offset, in pixels, of the edge of /// the object/character represented by position. /// </summary> /// <param name="position"> /// Position of an object/character. /// </param> /// <param name="transform"> /// Transform to be applied to returned rect /// </param> /// <returns> /// The height, in pixels, of the edge of the object/character /// represented by position. /// </returns> /// <exception cref="System.InvalidOperationException"> /// Throws InvalidOperationException if IsValid is false. /// If IsValid returns false, Validate method must be called before /// calling this method. /// </exception> /// <remarks> /// Rect.Width is always 0. /// Output parameter Transform is always Identity. It is not expected that editing scenarios /// will require speparate transform with raw rectangle for this case. /// If the document is empty, then this method returns the expected /// height of a character, if placed at the specified position. /// </remarks> internal override Rect GetRawRectangleFromTextPosition(ITextPointer position, out Transform transform) { #if DEBUG DocumentsTrace.FixedTextOM.TextView.Trace(string.Format("GetRectFromTextPosition {0}, {1}", (FixedTextPointer)position, position.LogicalDirection)); #endif FixedTextPointer ftp = Container.VerifyPosition(position); FixedPosition fixedp; // need a default caret size, otherwise infinite corners cause text editor and MultiPageTextView problems. // Initialize transform to Identity. This function always returns Identity transform. Rect designRect = new Rect(0, 0, 0, 10); transform = Transform.Identity; Debug.Assert(ftp != null); if (ftp.FlowPosition.IsBoundary) { if (!_GetFirstFixedPosition(ftp, out fixedp)) { return(designRect); } } else if (!_GetFixedPosition(ftp, out fixedp)) { // // This is the start/end element, we need to find out the next element and return the next element // start offset/height. // if (position.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.None) { ITextPointer psNext = position.CreatePointer(1); FixedTextPointer ftpNext = Container.VerifyPosition(psNext); if (!_GetFixedPosition(ftpNext, out fixedp)) { return(designRect); } } else { return(designRect); } } if (fixedp.Page != this.PageIndex) { return(designRect); } DependencyObject element = this.FixedPage.GetElement(fixedp.Node); if (element is Glyphs) { Glyphs g = (Glyphs)element; designRect = _GetGlyphRunDesignRect(g, fixedp.Offset, fixedp.Offset); // need to do transform GeneralTransform tran = g.TransformToAncestor(this.FixedPage); designRect = _GetTransformedCaretRect(tran, designRect.TopLeft, designRect.Height); } else if (element is Image) { Image image = (Image)element; GeneralTransform tran = image.TransformToAncestor(this.FixedPage); Point offset = new Point(0, 0); if (fixedp.Offset > 0) { offset.X += image.ActualWidth; } designRect = _GetTransformedCaretRect(tran, offset, image.ActualHeight); } else if (element is Path) { Path path = (Path)element; GeneralTransform tran = path.TransformToAncestor(this.FixedPage); Rect bounds = path.Data.Bounds; Point offset = bounds.TopLeft; if (fixedp.Offset > 0) { offset.X += bounds.Width; } designRect = _GetTransformedCaretRect(tran, offset, bounds.Height); } return(designRect); }
public override GeneralTransform GetDesiredTransform(GeneralTransform transform) { return(base.GetDesiredTransform(transform)); }
/// <summary> /// UpdateElementBounds: /// Called by InkCanvasSelection.UpdateElementBounds /// ClipboardProcessor.CopySelectionInXAML /// </summary> /// <param name="originalElement"></param> /// <param name="updatedElement"></param> /// <param name="transform"></param> internal void UpdateElementBounds(UIElement originalElement, UIElement updatedElement, Matrix transform) { if (originalElement.DependencyObjectType.Id == updatedElement.DependencyObjectType.Id) { // Get the transform from element to Canvas GeneralTransform elementToCanvas = originalElement.TransformToAncestor(_inkCanvas.InnerCanvas); //cast to a FrameworkElement, nothing inherits from UIElement besides it right now FrameworkElement frameworkElement = originalElement as FrameworkElement; Size size; Thickness thickness = new Thickness(); if (frameworkElement == null) { // Get the element's render size. size = originalElement.RenderSize; } else { size = new Size(frameworkElement.ActualWidth, frameworkElement.ActualHeight); thickness = frameworkElement.Margin; } Rect elementBounds = new Rect(0, 0, size.Width, size.Height); // Rect in element space elementBounds = elementToCanvas.TransformBounds(elementBounds); // Rect in Canvas space // Now apply the matrix to the element bounds Rect newBounds = Rect.Transform(elementBounds, transform); if (!DoubleUtil.AreClose(elementBounds.Width, newBounds.Width)) { if (frameworkElement == null) { Size newSize = originalElement.RenderSize; newSize.Width = newBounds.Width; updatedElement.RenderSize = newSize; } else { ((FrameworkElement)updatedElement).Width = newBounds.Width; } } if (!DoubleUtil.AreClose(elementBounds.Height, newBounds.Height)) { if (frameworkElement == null) { Size newSize = originalElement.RenderSize; newSize.Height = newBounds.Height; updatedElement.RenderSize = newSize; } else { ((FrameworkElement)updatedElement).Height = newBounds.Height; } } double left = InkCanvas.GetLeft(originalElement); double top = InkCanvas.GetTop(originalElement); double right = InkCanvas.GetRight(originalElement); double bottom = InkCanvas.GetBottom(originalElement); Point originalPosition = new Point(); // Default as (0, 0) if (!double.IsNaN(left)) { originalPosition.X = left; } else if (!double.IsNaN(right)) { originalPosition.X = right; } if (!double.IsNaN(top)) { originalPosition.Y = top; } else if (!double.IsNaN(bottom)) { originalPosition.Y = bottom; } Point newPosition = originalPosition * transform; if (!double.IsNaN(left)) { InkCanvas.SetLeft(updatedElement, newPosition.X - thickness.Left); // Left wasn't auto } else if (!double.IsNaN(right)) { // NOTICE-2005/05/05-WAYNEZEN // Canvas.RightProperty means the distance between element right side and its parent Canvas // right side. The same definition is applied to Canvas.BottomProperty InkCanvas.SetRight(updatedElement, (right - (newPosition.X - originalPosition.X))); // Right wasn't not auto } else { InkCanvas.SetLeft(updatedElement, newPosition.X - thickness.Left); // Both Left and Right were aut. Modify Left by default. } if (!double.IsNaN(top)) { InkCanvas.SetTop(updatedElement, newPosition.Y - thickness.Top); // Top wasn't auto } else if (!double.IsNaN(bottom)) { InkCanvas.SetBottom(updatedElement, (bottom - (newPosition.Y - originalPosition.Y))); // Bottom wasn't not auto } else { InkCanvas.SetTop(updatedElement, newPosition.Y - thickness.Top); // Both Top and Bottom were aut. Modify Left by default. } } else { Debug.Assert(false, "The updatedElement has to be the same type as the originalElement."); } }
public static Point GetPosition(UIElement uiElement, UIElement relativeToUIElement) { GeneralTransform generalTransform = uiElement.TransformToVisual(relativeToUIElement); return(generalTransform.Transform(new Point(0, 0))); }
internal void ScrollIntoView(FrameworkElement element) { // Get the ScrollHost ScrollViewer scrollHost = ScrollHost; if (scrollHost == null) { return; } // Get the position of the element relative to the ScrollHost GeneralTransform transform = null; try { transform = element.TransformToVisual(scrollHost); } catch (ArgumentException) { // Ignore failures when not in the visual tree return; } Rect itemRect = new Rect( transform.Transform(new Point()), transform.Transform(new Point(element.ActualWidth, element.ActualHeight))); // Scroll vertically double verticalOffset = scrollHost.VerticalOffset; double verticalDelta = 0; double hostBottom = scrollHost.ViewportHeight; double itemBottom = itemRect.Bottom; if (hostBottom < itemBottom) { verticalDelta = itemBottom - hostBottom; verticalOffset += verticalDelta; } double itemTop = itemRect.Top; if (itemTop - verticalDelta < 0) { verticalOffset -= verticalDelta - itemTop; } scrollHost.ScrollToVerticalOffset(verticalOffset); // Scroll horizontally double horizontalOffset = scrollHost.HorizontalOffset; double horizontalDelta = 0; double hostRight = scrollHost.ViewportWidth; double itemRight = itemRect.Right; if (hostRight < itemRight) { horizontalDelta = itemRight - hostRight; horizontalOffset += horizontalDelta; } double itemLeft = itemRect.Left; if (itemLeft - horizontalDelta < 0) { horizontalOffset -= horizontalDelta - itemLeft; } scrollHost.ScrollToHorizontalOffset(horizontalOffset); }
private async void ThumbnailList_ItemClick(object sender, ItemClickEventArgs e) { Thumbnail thumbnail = (Thumbnail)e.ClickedItem; ListView listView = (ListView)sender; ListViewItem listItem = (ListViewItem)listView.ContainerFromItem(e.ClickedItem); // // Calculate the absolute offset to the item that was clicked. We will use that for centering // the zoom in. // GeneralTransform coordinate = listItem.TransformToVisual(listView); Vector2 clickedItemCenterPosition = coordinate.TransformPoint(new Point(0, 0)).ToVector2() + new Vector2((float)listItem.ActualWidth / 2, (float)listItem.ActualHeight / 2); // // Calculate the offset we want to animate up/down/in for the zoom based on the center point of the target and the // size of the panel/viewport. // Vector2 targetOffset = new Vector2((float)listView.ActualWidth / 2, (float)listView.ActualHeight / 2) - clickedItemCenterPosition; // // Get the root panel and set it up for the rotation animation. We're rotating the listview around the Y-axis relative // to the center point of the panel. // Visual root = ElementCompositionPreview.GetElementVisual(ThumbnailList); root.Size = new Vector2((float)ThumbnailList.ActualWidth, (float)ThumbnailList.ActualHeight); root.CenterPoint = new Vector3(root.Size.X / 2, root.Size.Y / 2, 0); root.RotationAxis = new Vector3(0, 1, 0); // Kick off the rotation animation ScalarKeyFrameAnimation rotationAnimation = _compositor.CreateScalarKeyFrameAnimation(); rotationAnimation.InsertKeyFrame(0, 0); rotationAnimation.InsertKeyFrame(1, targetOffset.X > 0 ? -45f : 45f); rotationAnimation.Duration = TimeSpan.FromMilliseconds(1000); root.StartAnimation("RotationAngleInDegrees", rotationAnimation); // Calcuate the offset for the point we are zooming towards const float zoomFactor = .8f; Vector3 zoomedOffset = new Vector3(targetOffset.X, targetOffset.Y, (float)PerspectivePanel.ActualWidth * zoomFactor) * zoomFactor; Vector3KeyFrameAnimation offsetAnimaton = _compositor.CreateVector3KeyFrameAnimation(); offsetAnimaton.InsertKeyFrame(0, new Vector3(0, 0, 0)); offsetAnimaton.InsertKeyFrame(1, zoomedOffset); offsetAnimaton.Duration = TimeSpan.FromMilliseconds(1000); root.StartAnimation("Offset", offsetAnimaton); // Create the dialog var messageDialog = new MessageDialog(thumbnail.Name); messageDialog.Commands.Add(new UICommand("Close", new UICommandInvokedHandler(DialogDismissedHandler))); // Show the message dialog await messageDialog.ShowAsync(); }
/// <summary> /// Renders a bitmap using any affine transformation and transparency into this bitmap /// Unlike Silverlight's Render() method, this one uses 2-3 times less memory, and is the same or better quality /// The algorithm is simple dx/dy (bresenham-like) step by step painting, optimized with fixed point and fast bilinear filtering /// It's used in Fantasia Painter for drawing stickers and 3D objects on screen /// </summary> /// <param name="bmp">Destination bitmap.</param> /// <param name="source">The source WriteableBitmap.</param> /// <param name="shouldClear">If true, the the destination bitmap will be set to all clear (0) before rendering.</param> /// <param name="opacity">opacity of the source bitmap to render, between 0 and 1 inclusive</param> /// <param name="transform">Transformation to apply</param> public static void BlitRender(this WriteableBitmap bmp, WriteableBitmap source, bool shouldClear = true, float opacity = 1f, GeneralTransform transform = null) { const int PRECISION_SHIFT = 10; const int PRECISION_VALUE = (1 << PRECISION_SHIFT); const int PRECISION_MASK = PRECISION_VALUE - 1; using (BitmapContext destContext = bmp.GetBitmapContext()) { if (transform == null) transform = new MatrixTransform(); var destPixels = destContext.Pixels; int destWidth = destContext.Width; int destHeight = destContext.Height; var inverse = transform.Inverse; if(shouldClear) destContext.Clear(); using (BitmapContext sourceContext = source.GetBitmapContext()) { var sourcePixels = sourceContext.Pixels; int sourceWidth = sourceContext.Width; int sourceHeight = sourceContext.Height; Rect sourceRect = new Rect(0, 0, sourceWidth, sourceHeight); Rect destRect = new Rect(0, 0, destWidth, destHeight); Rect bounds = transform.TransformBounds(sourceRect); bounds.Intersect(destRect); int startX = (int)bounds.Left; int startY = (int)bounds.Top; int endX = (int)bounds.Right; int endY = (int)bounds.Bottom; #if NETFX_CORE Point zeroZero = inverse.TransformPoint(new Point(startX, startY)); Point oneZero = inverse.TransformPoint(new Point(startX + 1, startY)); Point zeroOne = inverse.TransformPoint(new Point(startX, startY + 1)); #else Point zeroZero = inverse.Transform(new Point(startX, startY)); Point oneZero = inverse.Transform(new Point(startX + 1, startY)); Point zeroOne = inverse.Transform(new Point(startX, startY + 1)); #endif float sourceXf = ((float)zeroZero.X); float sourceYf = ((float)zeroZero.Y); int dxDx = (int)((((float)oneZero.X) - sourceXf) * PRECISION_VALUE); // for 1 unit in X coord, how much does X change in source texture? int dxDy = (int)((((float)oneZero.Y) - sourceYf) * PRECISION_VALUE); // for 1 unit in X coord, how much does Y change in source texture? int dyDx = (int)((((float)zeroOne.X) - sourceXf) * PRECISION_VALUE); // for 1 unit in Y coord, how much does X change in source texture? int dyDy = (int)((((float)zeroOne.Y) - sourceYf) * PRECISION_VALUE); // for 1 unit in Y coord, how much does Y change in source texture? int sourceX = (int)(((float)zeroZero.X) * PRECISION_VALUE); int sourceY = (int)(((float)zeroZero.Y) * PRECISION_VALUE); int sourceWidthFixed = sourceWidth << PRECISION_SHIFT; int sourceHeightFixed = sourceHeight << PRECISION_SHIFT; int opacityInt = (int)(opacity * 255); int index = 0; for (int destY = startY; destY < endY; destY++) { index = destY * destWidth + startX; int savedSourceX = sourceX; int savedSourceY = sourceY; for (int destX = startX; destX < endX; destX++) { if ((sourceX >= 0) && (sourceX < sourceWidthFixed) && (sourceY >= 0) && (sourceY < sourceHeightFixed)) { // bilinear filtering int xFloor = sourceX >> PRECISION_SHIFT; int yFloor = sourceY >> PRECISION_SHIFT; if (xFloor < 0) xFloor = 0; if (yFloor < 0) yFloor = 0; int xCeil = xFloor + 1; int yCeil = yFloor + 1; if (xCeil >= sourceWidth) { xFloor = sourceWidth - 1; xCeil = 0; } else { xCeil = 1; } if (yCeil >= sourceHeight) { yFloor = sourceHeight - 1; yCeil = 0; } else { yCeil = sourceWidth; } int i1 = yFloor * sourceWidth + xFloor; int p1 = sourcePixels[i1]; int p2 = sourcePixels[i1 + xCeil]; int p3 = sourcePixels[i1 + yCeil]; int p4 = sourcePixels[i1 + yCeil + xCeil]; int xFrac = sourceX & PRECISION_MASK; int yFrac = sourceY & PRECISION_MASK; // alpha byte a1 = (byte)(p1 >> 24); byte a2 = (byte)(p2 >> 24); byte a3 = (byte)(p3 >> 24); byte a4 = (byte)(p4 >> 24); int comp1, comp2; byte a; if ((a1 == a2) && (a1 == a3) && (a1 == a4)) { if (a1 == 0) { destPixels[index] = 0; sourceX += dxDx; sourceY += dxDy; index++; continue; } a = a1; } else { comp1 = a1 + ((xFrac * (a2 - a1)) >> PRECISION_SHIFT); comp2 = a3 + ((xFrac * (a4 - a3)) >> PRECISION_SHIFT); a = (byte)(comp1 + ((yFrac * (comp2 - comp1)) >> PRECISION_SHIFT)); } // red comp1 = ((byte)(p1 >> 16)) + ((xFrac * (((byte)(p2 >> 16)) - ((byte)(p1 >> 16)))) >> PRECISION_SHIFT); comp2 = ((byte)(p3 >> 16)) + ((xFrac * (((byte)(p4 >> 16)) - ((byte)(p3 >> 16)))) >> PRECISION_SHIFT); byte r = (byte)(comp1 + ((yFrac * (comp2 - comp1)) >> PRECISION_SHIFT)); // green comp1 = ((byte)(p1 >> 8)) + ((xFrac * (((byte)(p2 >> 8)) - ((byte)(p1 >> 8)))) >> PRECISION_SHIFT); comp2 = ((byte)(p3 >> 8)) + ((xFrac * (((byte)(p4 >> 8)) - ((byte)(p3 >> 8)))) >> PRECISION_SHIFT); byte g = (byte)(comp1 + ((yFrac * (comp2 - comp1)) >> PRECISION_SHIFT)); // blue comp1 = ((byte)p1) + ((xFrac * (((byte)p2) - ((byte)p1))) >> PRECISION_SHIFT); comp2 = ((byte)p3) + ((xFrac * (((byte)p4) - ((byte)p3))) >> PRECISION_SHIFT); byte b = (byte)(comp1 + ((yFrac * (comp2 - comp1)) >> PRECISION_SHIFT)); // save updated pixel if (opacityInt != 255) { a = (byte)((a * opacityInt) >> 8); r = (byte)((r * opacityInt) >> 8); g = (byte)((g * opacityInt) >> 8); b = (byte)((b * opacityInt) >> 8); } destPixels[index] = (a << 24) | (r << 16) | (g << 8) | b; } sourceX += dxDx; sourceY += dxDy; index++; } sourceX = savedSourceX + dyDx; sourceY = savedSourceY + dyDy; } } } }
//Processes the Glyphs element, create one or more text runs out of it, add to containing text line and text box private void _ProcessGlyphsElement(Glyphs glyphs, FixedNode node) { Debug.Assert(glyphs != null); string s = glyphs.UnicodeString; if (s.Length == 0 || glyphs.FontRenderingEmSize <= 0) { return; } //Multiple table cells separated by wide spaces should be identified GlyphRun glyphRun = glyphs.ToGlyphRun(); if (glyphRun == null) { //Could not create a GlyphRun out of this Glyphs element //Some key properties might be missing/invalid return; } Rect alignmentBox = glyphRun.ComputeAlignmentBox(); alignmentBox.Offset(glyphs.OriginX, glyphs.OriginY); GlyphTypeface typeFace = glyphRun.GlyphTypeface; GeneralTransform trans = glyphs.TransformToAncestor(_fixedPage); int charIndex = -1; double advWidth = 0; double cumulativeAdvWidth = 0; int lastAdvWidthIndex = 0; int textRunStartIndex = 0; double lastX = alignmentBox.Left; int glyphIndex = charIndex; do { charIndex = s.IndexOf(" ", charIndex + 1, s.Length - charIndex - 1, StringComparison.Ordinal); if (charIndex >= 0) { if (glyphRun.ClusterMap != null && glyphRun.ClusterMap.Count > 0) { glyphIndex = glyphRun.ClusterMap[charIndex]; } else { glyphIndex = charIndex; } //Advance width of the space character in the font double advFont = typeFace.AdvanceWidths[glyphRun.GlyphIndices[glyphIndex]] * glyphRun.FontRenderingEmSize; double advSpecified = glyphRun.AdvanceWidths[glyphIndex]; if ((advSpecified / advFont) > 2) { //Are these seperated by a vertical line? advWidth = 0; for (int i = lastAdvWidthIndex; i < glyphIndex; i++) { advWidth += glyphRun.AdvanceWidths[i]; } cumulativeAdvWidth += advWidth; lastAdvWidthIndex = glyphIndex + 1; if (_lines.IsVerticallySeparated(glyphRun.BaselineOrigin.X + cumulativeAdvWidth, alignmentBox.Top, glyphRun.BaselineOrigin.X + cumulativeAdvWidth + advSpecified, alignmentBox.Bottom)) { //Create a new FixedTextRun Rect boundingRect = new Rect(lastX, alignmentBox.Top, advWidth + advFont, alignmentBox.Height); int endIndex = charIndex; if ((charIndex == 0 || s[charIndex - 1] == ' ') && (charIndex != s.Length - 1)) { endIndex = charIndex + 1; } _CreateTextRun(boundingRect, trans, glyphs, node, textRunStartIndex, endIndex); lastX = lastX + advWidth + advSpecified; textRunStartIndex = charIndex + 1; } cumulativeAdvWidth += advSpecified; } } } while (charIndex >= 0 && charIndex < s.Length - 1); if (textRunStartIndex < s.Length) { //Last text run //For non-partitioned elements this will be the whole Glyphs element Rect boundingRect = new Rect(lastX, alignmentBox.Top, alignmentBox.Right - lastX, alignmentBox.Height); _CreateTextRun(boundingRect, trans, glyphs, node, textRunStartIndex, s.Length); } }
private void RefreshSnapPoints(ScrollPresenter scrollPresenter, StackPanel stackPanel) { if (scrollPresenter != null && stackPanel != null && stackPanel.Children.Count > 0) { AppendAsyncEventMessage("Populating snap points for " + scrollPresenter.Name + ":"); ScrollSnapPoint scrollSnapPoint; GeneralTransform gt = stackPanel.TransformToVisual(scrollPresenter.Content); Point stackPanelOriginPoint = new Point(); stackPanelOriginPoint = gt.TransformPoint(stackPanelOriginPoint); if (stackPanel.Orientation == Orientation.Horizontal) { scrollPresenter.HorizontalSnapPoints.Clear(); scrollSnapPoint = new ScrollSnapPoint(stackPanelOriginPoint.X, ScrollSnapPointsAlignment.Near); AppendAsyncEventMessage("Adding horizontal snap point to " + scrollPresenter.Name + " at value " + stackPanelOriginPoint.X); scrollPresenter.HorizontalSnapPoints.Add(scrollSnapPoint); } else { scrollPresenter.VerticalSnapPoints.Clear(); scrollSnapPoint = new ScrollSnapPoint(stackPanelOriginPoint.Y, ScrollSnapPointsAlignment.Near); AppendAsyncEventMessage("Adding vertical snap point to " + scrollPresenter.Name + " at value " + stackPanelOriginPoint.Y); scrollPresenter.VerticalSnapPoints.Add(scrollSnapPoint); } foreach (UIElement child in stackPanel.Children) { FrameworkElement childAsFE = child as FrameworkElement; if (childAsFE != null) { gt = childAsFE.TransformToVisual(stackPanel); Point childOriginPoint = new Point(); childOriginPoint = gt.TransformPoint(childOriginPoint); double snapPointValue = 0.0; Thickness margin = childAsFE.Margin; if (stackPanel.Orientation == Orientation.Horizontal) { snapPointValue = margin.Right + childAsFE.ActualWidth + childOriginPoint.X; if (snapPointValue <= scrollPresenter.ScrollableWidth) { scrollSnapPoint = new ScrollSnapPoint(snapPointValue, ScrollSnapPointsAlignment.Near); AppendAsyncEventMessage("Adding horizontal snap point to " + scrollPresenter.Name + " at value " + snapPointValue); scrollPresenter.HorizontalSnapPoints.Add(scrollSnapPoint); } else { break; } } else { snapPointValue = margin.Bottom + childAsFE.ActualHeight + childOriginPoint.Y; if (snapPointValue <= scrollPresenter.ScrollableHeight) { scrollSnapPoint = new ScrollSnapPoint(snapPointValue, ScrollSnapPointsAlignment.Near); AppendAsyncEventMessage("Adding vertical snap point to " + scrollPresenter.Name + " at value " + snapPointValue); scrollPresenter.VerticalSnapPoints.Add(scrollSnapPoint); } else { break; } } } RefreshSnapPoints(scrollPresenter, child as StackPanel); } } }
public static Point GetPosition(UIElement uiElement) { GeneralTransform generalTransform = uiElement.TransformToVisual(Application.Current.RootVisual as UIElement); return(generalTransform.Transform(new Point(0, 0))); }
private void GetRootTransforms(IInputElement relativeTo, out GeneralTransform elementToRoot, out GeneralTransform rootToElement) { elementToRoot = rootToElement = null; DependencyObject containingVisual = InputElement.GetContainingVisual(relativeTo as DependencyObject); if (containingVisual != null) { PresentationSource relativePresentationSource = PresentationSource.CriticalFromVisual(containingVisual); Visual rootVisual = (relativePresentationSource != null) ? relativePresentationSource.RootVisual : null; Visual containingVisual2D = VisualTreeHelper.GetContainingVisual2D(containingVisual); if ((rootVisual != null) && (containingVisual2D != null)) { elementToRoot = containingVisual2D.TransformToAncestor(rootVisual); rootToElement = rootVisual.TransformToDescendant(containingVisual2D); } } }
public override void Begin(Action completionAction) { Storyboard = new Storyboard(); double liCounter = 0; var listBoxItems = ListBox.GetVisualDescendants().OfType <ListBoxItem>().Where(lbi => IsOnCurrentPage(lbi) && lbi.IsEnabled).ToList(); if (HoldSelectedItem && Direction == Directions.Out && ListBox.SelectedItem != null) { // move selected container to end var selectedContainer = ListBox.ItemContainerGenerator.ContainerFromItem(ListBox.SelectedItem); listBoxItems.Remove((ListBoxItem)selectedContainer); listBoxItems.Add((ListBoxItem)selectedContainer); } foreach (ListBoxItem li in listBoxItems) { GeneralTransform gt = li.TransformToVisual(RootElement); Point globalCoords = gt.Transform(new Point(0, 0)); double heightAdjustment = li.Content is FrameworkElement ? ((li.Content as FrameworkElement).ActualHeight / 2) : (li.ActualHeight / 2); //double yCoord = globalCoords.Y + ((((System.Windows.FrameworkElement)(((System.Windows.Controls.ContentControl)(li)).Content)).ActualHeight) / 2); double yCoord = globalCoords.Y + heightAdjustment; double offsetAmount = (RootElement.ActualHeight / 2) - yCoord; PlaneProjection pp = new PlaneProjection(); pp.GlobalOffsetY = offsetAmount * -1; pp.CenterOfRotationX = 0; li.Projection = pp; CompositeTransform ct = new CompositeTransform(); ct.TranslateY = offsetAmount; li.RenderTransform = ct; var beginTime = TimeSpan.FromMilliseconds((FeatherDelay * liCounter) + InitialDelay); if (Direction == Directions.In) { li.Opacity = 0; DoubleAnimationUsingKeyFrames daukf = new DoubleAnimationUsingKeyFrames(); EasingDoubleKeyFrame edkf1 = new EasingDoubleKeyFrame(); edkf1.KeyTime = beginTime; edkf1.Value = Angle; daukf.KeyFrames.Add(edkf1); EasingDoubleKeyFrame edkf2 = new EasingDoubleKeyFrame(); edkf2.KeyTime = TimeSpan.FromMilliseconds(Duration).Add(beginTime); edkf2.Value = 0; ExponentialEase ee = new ExponentialEase(); ee.EasingMode = EasingMode.EaseOut; ee.Exponent = 6; edkf2.EasingFunction = ee; daukf.KeyFrames.Add(edkf2); Storyboard.SetTarget(daukf, li); Storyboard.SetTargetProperty(daukf, new PropertyPath("(UIElement.Projection).(PlaneProjection.RotationY)")); Storyboard.Children.Add(daukf); DoubleAnimation da = new DoubleAnimation(); da.Duration = TimeSpan.FromMilliseconds(0); da.BeginTime = beginTime; da.To = 1; Storyboard.SetTarget(da, li); Storyboard.SetTargetProperty(da, new PropertyPath("(UIElement.Opacity)")); Storyboard.Children.Add(da); } else { li.Opacity = 1; DoubleAnimation da = new DoubleAnimation(); da.BeginTime = beginTime; da.Duration = TimeSpan.FromMilliseconds(Duration); da.To = Angle; ExponentialEase ee = new ExponentialEase(); ee.EasingMode = EasingMode.EaseIn; ee.Exponent = 6; da.EasingFunction = ee; Storyboard.SetTarget(da, li); Storyboard.SetTargetProperty(da, new PropertyPath("(UIElement.Projection).(PlaneProjection.RotationY)")); Storyboard.Children.Add(da); da = new DoubleAnimation(); da.Duration = TimeSpan.FromMilliseconds(10); da.To = 0; da.BeginTime = TimeSpan.FromMilliseconds(Duration).Add(beginTime); Storyboard.SetTarget(da, li); Storyboard.SetTargetProperty(da, new PropertyPath("(UIElement.Opacity)")); Storyboard.Children.Add(da); } liCounter++; } base.Begin(completionAction); }
//-------------------------------------------------------------------- // // Constructors // //--------------------------------------------------------------------- #region Constructors private FixedSOMTextRun(Rect boundingRect, GeneralTransform trans, FixedNode fixedNode, int startIndex, int endIndex) : base(fixedNode, startIndex, endIndex, trans) { _boundingRect = trans.TransformBounds(boundingRect); }
void ScrollPages_ScrollChanged(object sender, ScrollChangedEventArgs e) { // Weirdly, ScrollChanged is a bubbling event - not a callback on the very object // So you can receive a scroll event from ANY of your children?!!?!!!!! // Inside the reading page, there are scrollbars in the annotation popups, which cause this to fire. So ignore those... if (e.Source != ScrollPages) { return; } if (DateTime.MaxValue == first_scroll_timestamp) { first_scroll_timestamp = DateTime.UtcNow; if (remember_last_read_page) { if (0 < pdf_renderer_control_stats.pdf_document.PageLastRead) { //Logging.Info("**********************************Restoring page to page " + pdf_renderer_control_stats.pdf_document.PageLastRead); PDFRendererPageControl page_control = (PDFRendererPageControl)ObjPagesPanel.Children[pdf_renderer_control_stats.pdf_document.PageLastRead - 1]; page_control.BringIntoView(); } } } /* * Logging.Info( * "\n----------------------------------------------------------" + * "\nExtentHeight={0}," + * "\nExtentHeightChange={1}," + * "\nExtentWidth={2}," + * "\nExtentWidthChange={3}," + * "\nHorizontalChange={4}," + * "\nHorizontalOffset={5}," + * "\nVerticalChange={6}," + * "\nVerticalOffset={7}," + * "\nViewportHeight={8}," + * "\nViewportHeightChange={9}," + * "\nViewportWidth={10}," + * "\nViewportWidthChange={11}," + * "", * * e.ExtentHeight, * e.ExtentHeightChange, * e.ExtentWidth, * e.ExtentWidthChange, * e.HorizontalChange, * e.HorizontalOffset, * e.VerticalChange, * e.VerticalOffset, * e.ViewportHeight, * e.ViewportHeightChange, * e.ViewportWidth, * e.ViewportWidthChange * ); */ // Lets see which pages are in view PDFRendererPageControl first_page_in_view = null; List <PDFRendererPageControl> pages_in_view = new List <PDFRendererPageControl>(); List <PDFRendererPageControl> pages_not_in_view = new List <PDFRendererPageControl>(); foreach (PDFRendererPageControl page in ObjPagesPanel.Children.OfType <PDFRendererPageControl>().Reverse()) { GeneralTransform childTransform = page.TransformToAncestor(ScrollPages); Rect rectangle = childTransform.TransformBounds(new Rect(new Point(0, 0), page.RenderSize)); Rect result = Rect.Intersect(new Rect(new Point(0, 0), ScrollPages.RenderSize), rectangle); if (result != Rect.Empty) { if (null == first_page_in_view) { first_page_in_view = page; } pages_in_view.Add(page); } else { pages_not_in_view.Add(page); } } // Check if the selected page has gone off screen. If so, select the next page. if (null != SelectedPage) { if (!pages_in_view.Contains(SelectedPage)) { // IF this is the first time the selected page has gone off screen, record the moment if (DateTime.MaxValue == selected_page_first_offscreen_timestamp) { selected_page_first_offscreen_timestamp = DateTime.UtcNow; } // We wait for a few moments after it has gone off the screen...2 is arbitrary, but large enough that we can zoom without changing the selected page before the zoom gets time to move thesleected page back onto the screen... if (DateTime.UtcNow.Subtract(selected_page_first_offscreen_timestamp).TotalSeconds > 1) { if (null != first_page_in_view) { SelectedPage = first_page_in_view; selected_page_first_offscreen_timestamp = DateTime.MaxValue; } } } else { selected_page_first_offscreen_timestamp = DateTime.MaxValue; } } bool SKIP = false; if (SKIP) { // Lets pretend the pages just before and after the pages in view are in view - that way we dont have to wait for the render int min_page = Int32.MaxValue; int max_page = Int32.MinValue; foreach (PDFRendererPageControl page in pages_in_view) { min_page = Math.Min(min_page, page.PageNumber - 1); max_page = Math.Max(max_page, page.PageNumber + 1); } foreach (PDFRendererPageControl page in pages_not_in_view) { if (min_page == page.PageNumber || max_page == page.PageNumber) { pages_in_view.Add(page); } } foreach (PDFRendererPageControl page in pages_in_view) { pages_not_in_view.Remove(page); } } // Clear down the pages NOT in view foreach (PDFRendererPageControl page in pages_not_in_view) { page.SetPageNotInView(); } // Notify the new pages that are in view foreach (PDFRendererPageControl page in pages_in_view) { //Logging.Info("Page {0} is in view!!!!!!!!!!!!!!", page.PageNumber); page.SetPageInView(); } // If the page has been resized or rescaled, try keep the scrollbars in the same place... if (0 != e.ExtentHeightChange) { double prev_extent_height = e.ExtentHeight - e.ExtentHeightChange; double vertical_offset_ratio = e.VerticalOffset / prev_extent_height; double new_vertical_offset = vertical_offset_ratio * e.ExtentHeight; if (!Double.IsNaN(new_vertical_offset)) { //Logging.Info("Forcing vertical offset from {0} to {1}", e.VerticalOffset, new_vertical_offset); ScrollPages.ScrollToVerticalOffset(new_vertical_offset); return; } else { } } // Store the last seen page - but not right at the start if (DateTime.UtcNow.Subtract(first_scroll_timestamp).TotalSeconds > 1) { if (remember_last_read_page) { if (0 < pages_in_view.Count) { PDFRendererPageControl page = pages_in_view[0]; // Set the last read page pdf_renderer_control_stats.pdf_document.PageLastRead = page.Page; // Dont notify this now as it causes many writes of the metadata to be done, which is slow for large highlightlists //pdf_renderer_control_stats.pdf_document.Bindable.NotifyPropertyChanged(() => pdf_renderer_control_stats.pdf_document.PageLastRead); } } } }
//-------------------------------------------------------------------- // // Public Methods // //--------------------------------------------------------------------- #region public Methods public static FixedSOMTextRun Create(Rect boundingRect, GeneralTransform transform, Glyphs glyphs, FixedNode fixedNode, int startIndex, int endIndex, bool allowReverseGlyphs) { if (String.IsNullOrEmpty(glyphs.UnicodeString) || glyphs.FontRenderingEmSize <= 0) { return(null); } FixedSOMTextRun run = new FixedSOMTextRun(boundingRect, transform, fixedNode, startIndex, endIndex); run._fontUri = glyphs.FontUri; run._cultureInfo = glyphs.Language.GetCompatibleCulture(); run._bidiLevel = glyphs.BidiLevel; run._isSideways = glyphs.IsSideways; run._fontSize = glyphs.FontRenderingEmSize; GlyphRun glyphRun = glyphs.ToGlyphRun(); GlyphTypeface gtf = glyphRun.GlyphTypeface; // Find font family // glyphs.FontUri, glyphRun.glyphTypeface gtf.FamilyNames.TryGetValue(run._cultureInfo, out run._fontFamily); if (run._fontFamily == null) { //Try getting the English name gtf.FamilyNames.TryGetValue(System.Windows.Markup.TypeConverterHelper.InvariantEnglishUS, out run._fontFamily); } // Find font style (normal, italics, Oblique) // need to open Font file. run._fontStyle = gtf.Style; // Find font weight (bold, semibold, ExtraLight) run._fontWeight = gtf.Weight; // Find font stretch (UltraCondensed, SemiExpanded, etc) run._fontStretch = gtf.Stretch; //Height and width should be the same for x character run._defaultCharWidth = gtf.XHeight > 0 ? gtf.XHeight * glyphs.FontRenderingEmSize : glyphRun.AdvanceWidths[startIndex]; Transform trans = transform.AffineTransform; if (trans != null && !(trans.Value.IsIdentity)) { Matrix mat = trans.Value; double yScale = Math.Sqrt(mat.M12 * mat.M12 + mat.M22 * mat.M22); double xScale = Math.Sqrt(mat.M11 * mat.M11 + mat.M21 * mat.M21); run._fontSize *= yScale; run._defaultCharWidth *= xScale; } run._foreground = glyphs.Fill; String s = glyphs.UnicodeString; run.Text = s.Substring(startIndex, endIndex - startIndex); if (allowReverseGlyphs && run._bidiLevel == 0 && !run._isSideways && startIndex == 0 && endIndex == s.Length && String.IsNullOrEmpty(glyphs.CaretStops) && FixedTextBuilder.MostlyRTL(s)) { run._isReversed = true; run.Text = string.Create(run.Text.Length, run.Text, (destination, runText) => { for (int i = 0; i < destination.Length; i++) { destination[i] = runText[runText.Length - 1 - i]; } }); } if (s == "" && glyphs.Indices != null && glyphs.Indices.Length > 0) { run._isWhiteSpace = false; } else { run._isWhiteSpace = true; for (int i = 0; i < s.Length; i++) { if (!Char.IsWhiteSpace(s[i])) { run._isWhiteSpace = false; break; } } } return(run); }
private Geometry GetClipRegion(RowSelectorDecorator decorator, Rect arrangeRect, FrameworkElement referenceElement) { if (referenceElement == null) { return(null); } var rowSelector = decorator.RowSelector; if (rowSelector == null) { return(null); } GeneralTransform referenceElementToRowSelectorPaneTransform = referenceElement.TransformToVisual(this); Rect referenceElementRegion = referenceElementToRowSelectorPaneTransform.TransformBounds(new Rect(0, 0, referenceElement.ActualWidth, referenceElement.ActualHeight)); RectangleGeometry clipRegion = null; if (this.Orientation == Orientation.Vertical) { UIElement container = rowSelector.DataContext as UIElement; if ((container != null) && (container.Clip != null)) { Rect containerClipBounds = container.Clip.Bounds; // In this case, we will use the container's clip properties (Top and Bottom). clipRegion = new RectangleGeometry(new Rect(0d, containerClipBounds.Y, arrangeRect.Width, containerClipBounds.Height)); } else if ((arrangeRect.Top < referenceElementRegion.Top) || (arrangeRect.Bottom > referenceElementRegion.Bottom)) { double x = 0d; double y = Math.Max(referenceElementRegion.Top - arrangeRect.Top, 0); double width = arrangeRect.Width; double height = Math.Max(0, arrangeRect.Height - y - Math.Max(0, arrangeRect.Bottom - referenceElementRegion.Bottom)); clipRegion = new RectangleGeometry(new Rect(x, y, width, height)); } } else { UIElement container = rowSelector.DataContext as UIElement; if ((container != null) && (container.Clip != null)) { Rect containerClipBounds = container.Clip.Bounds; // In this case, we will use the container's clip properties (Left and Right). clipRegion = new RectangleGeometry(new Rect(containerClipBounds.X, 0d, containerClipBounds.Width, arrangeRect.Height)); } else if ((arrangeRect.Left < referenceElementRegion.Left) || (arrangeRect.Right > referenceElementRegion.Right)) { double x = Math.Max(referenceElementRegion.Left - arrangeRect.Left, 0); double y = 0d; double width = arrangeRect.Width - x - Math.Max(0, arrangeRect.Right - referenceElementRegion.Right); double height = arrangeRect.Height; clipRegion = new RectangleGeometry(new Rect(x, y, width, height)); } } return(clipRegion); }
/// <summary> /// Updates FirstItem and LastItem based on the /// Offset and Viewport properties. /// </summary> /// <param name="itemsControl">The ItemsControl that contains the data items.</param> /// <param name="vertical">True for vertical scrollbar</param> internal void UpdateItem(ItemsControl itemsControl, bool vertical) { if (itemsControl != null) { int numItems = itemsControl.Items.Count; if (numItems > 0) { if (VirtualizingStackPanel.GetIsVirtualizing(itemsControl)) { // Items scrolling (value == index) int firstIndex = (int)_offset; int lastIndex = (int)_offset + (int)_viewport - 1; if ((firstIndex >= 0) && (firstIndex < numItems)) { FirstItem = itemsControl.Items[firstIndex]; } else { FirstItem = null; } if ((lastIndex >= 0) && (lastIndex < numItems)) { LastItem = itemsControl.Items[lastIndex]; } else { LastItem = null; } } else { // Pixel scrolling (no virtualization) // This will do a linear search through all of the items. // It will assume that the first item encountered that is within view is // the first visible item and the last item encountered that is // within view is the last visible item. // Improvements could be made to this algorithm depending on the // number of items in the collection and the their order relative // to each other on-screen. ScrollContentPresenter scp = null; bool foundFirstItem = false; int bestLastItemIndex = -1; object firstVisibleItem = null; object lastVisibleItem = null; for (int i = 0; i < numItems; i++) { UIElement child = itemsControl.ItemContainerGenerator.ContainerFromIndex(i) as UIElement; if (child != null) { if (scp == null) { scp = child.GetParent <ScrollContentPresenter>(); if (scp == null) { // Not in a ScrollViewer that we understand return; } } // Transform the origin of the child element to see if it is within view GeneralTransform t = child.TransformToAncestor(scp); Point p = t.Transform(foundFirstItem ? new Point(child.RenderSize.Width, child.RenderSize.Height) : new Point()); if (!foundFirstItem && ((vertical ? p.Y : p.X) >= 0.0)) { // Found the first visible item firstVisibleItem = itemsControl.Items[i]; bestLastItemIndex = i; foundFirstItem = true; } else if (foundFirstItem && ((vertical ? p.Y : p.X) < scp.ActualHeight)) { // Found a candidate for the last visible item bestLastItemIndex = i; } } } if (bestLastItemIndex >= 0) { lastVisibleItem = itemsControl.Items[bestLastItemIndex]; } // Update the item properties FirstItem = firstVisibleItem; LastItem = lastVisibleItem; } } } }
private ITextPointer _SnapToText(Point point) { ITextPointer itp = null; FixedNode[] fixedNodes = Container.FixedTextBuilder.GetLine(this.PageIndex, point); if (fixedNodes != null && fixedNodes.Length > 0) { double closestDistance = Double.MaxValue; double xoffset = 0; Glyphs closestGlyphs = null; FixedNode closestNode = fixedNodes[0]; foreach (FixedNode node in fixedNodes) { Glyphs startGlyphs = this.FixedPage.GetGlyphsElement(node); GeneralTransform tranToGlyphs = this.FixedPage.TransformToDescendant(startGlyphs); Point transformedPt = point; if (tranToGlyphs != null) { tranToGlyphs.TryTransform(transformedPt, out transformedPt); } GlyphRun run = startGlyphs.ToGlyphRun(); Rect alignmentRect = run.ComputeAlignmentBox(); alignmentRect.Offset(startGlyphs.OriginX, startGlyphs.OriginY); double horizontalDistance = Math.Max(0, (transformedPt.X > alignmentRect.X) ? (transformedPt.X - alignmentRect.Right) : (alignmentRect.X - transformedPt.X)); double verticalDistance = Math.Max(0, (transformedPt.Y > alignmentRect.Y) ? (transformedPt.Y - alignmentRect.Bottom) : (alignmentRect.Y - transformedPt.Y)); double manhattanDistance = horizontalDistance + verticalDistance; if (closestGlyphs == null || manhattanDistance < closestDistance) { closestDistance = manhattanDistance; closestGlyphs = startGlyphs; closestNode = node; xoffset = transformedPt.X; } } int index; LogicalDirection dir; _GlyphRunHitTest(closestGlyphs, xoffset, out index, out dir); FixedPosition fixedp = new FixedPosition(closestNode, index); itp = _CreateTextPointer(fixedp, dir); Debug.Assert(itp != null); } else { // // That condition is only possible when there is no line in the page // if (point.Y < this.FixedPage.Height / 2) { itp = ((ITextPointer)this.Start).CreatePointer(LogicalDirection.Forward); itp.MoveToInsertionPosition(LogicalDirection.Forward); } else { itp = ((ITextPointer)this.End).CreatePointer(LogicalDirection.Backward); itp.MoveToInsertionPosition(LogicalDirection.Backward); } } return(itp); }
private void UpdateGroupHeaders() { var firstVisibleItemIndex = this.GetFirstVisibleIndex(); foreach (var item in visibleGroupHeaders) { //top header if (item.Key.FirstIndex <= firstVisibleItemIndex && (firstVisibleItemIndex <= item.Key.LastIndex || item.Key.LastIndex == -1)) { item.Value.Visibility = Visibility.Visible; item.Value.Margin = new Thickness(0); item.Value.Clip = null; currentTopGroupHeader = item.Value; } else { ListViewItem listViewItem = ContainerFromIndex(item.Key.FirstIndex) as ListViewItem; if (listViewItem == null && item.Key.LastIndex != -1) { listViewItem = ContainerFromIndex(item.Key.LastIndex) as ListViewItem; } if (listViewItem != null) { //handle moving header { //unloaded if (listViewItem.ActualHeight == 0 || listViewItem.ActualWidth == 0) { listViewItem.Loaded += ListViewItem_Loaded; } else { GeneralTransform gt = listViewItem.TransformToVisual(this); var rect = gt.TransformBounds(new Rect(0, 0, listViewItem.ActualWidth, listViewItem.ActualHeight)); groupHeaderDelta = item.Key.Height; //add delta,so that it does not look like suddenly if (rect.Bottom + groupHeaderDelta < 0 || rect.Top > this.ActualHeight + groupHeaderDelta) { item.Value.Visibility = Visibility.Collapsed; item.Value.Margin = new Thickness(0); item.Value.Clip = null; } //in view port else { item.Value.Visibility = Visibility.Visible; item.Value.Margin = new Thickness(0, rect.Top - groupHeaderDelta - defaultListViewItemMargin.Top, 0, 0); if (item.Value.Margin.Top < 0) { var clipHeight = groupHeaderDelta + item.Value.Margin.Top; //moving header has part in viewport if (clipHeight > 0) { item.Value.Clip = new RectangleGeometry() { Rect = new Rect(0, -item.Value.Margin.Top, this.ActualWidth, clipHeight) }; } //moving header not in viewport else { item.Value.Visibility = Visibility.Collapsed; item.Value.Clip = null; } } else if (item.Value.Margin.Top + groupHeaderDelta > this.ActualHeight) { var clipHeight = groupHeaderDelta - (groupHeaderDelta + item.Value.Margin.Top - this.ActualHeight); //moving header has part in viewport if (clipHeight > 0) { item.Value.Clip = new RectangleGeometry() { Rect = new Rect(0, 0, this.ActualWidth, clipHeight) }; } //moving header not in viewport else { item.Value.Visibility = Visibility.Collapsed; item.Value.Clip = null; } } //moving header all in viewport else { item.Value.Clip = null; } if (currentTopGroupHeader != null) { var delta = currentTopGroupHeader.ActualHeight - (item.Value.Margin.Top); if (delta > 0) { currentTopGroupHeader.Margin = new Thickness(0, -delta, 0, 0); currentTopGroupHeader.Clip = new RectangleGeometry() { Rect = new Rect(0, delta, currentTopGroupHeader.ActualWidth, currentTopGroupHeader.ActualHeight) }; } } } } } } else { if (item.Value != currentTopGroupHeader) { item.Value.Visibility = Visibility.Collapsed; item.Value.Margin = new Thickness(0); item.Value.Clip = null; } } } } }
public Viewport3DHitTestHelper(Viewport3D viewport, GeneralTransform viewportTransform) { this.viewports.Add(new Viewport3DHitTestHelper.ViewportInformation(viewport, viewportTransform)); }
private static bool DispatchLivePreviewBitmapMessage(ref System.Windows.Forms.Message m, TaskbarWindow taskbarWindow) { if (m.Msg == (int)TaskbarNativeMethods.WmDwmSendIconicLivePreviewBitmap) { // Try to get the width/height int width = (int)(((long)m.LParam) >> 16); int height = (int)(((long)m.LParam) & (0xFFFF)); // Default size for the thumbnail Size realWindowSize = new Size(200, 200); if (taskbarWindow.TabbedThumbnail.WindowHandle != IntPtr.Zero) { TabbedThumbnailNativeMethods.GetClientSize(taskbarWindow.TabbedThumbnail.WindowHandle, out realWindowSize); } else if (taskbarWindow.TabbedThumbnail.WindowsControl != null) { realWindowSize = new Size( Convert.ToInt32(taskbarWindow.TabbedThumbnail.WindowsControl.RenderSize.Width), Convert.ToInt32(taskbarWindow.TabbedThumbnail.WindowsControl.RenderSize.Height)); } // If we don't have a valid height/width, use the original window's size if (width <= 0) { width = realWindowSize.Width; } if (height <= 0) { height = realWindowSize.Height; } // Fire an event to let the user update their bitmap // Raise the event taskbarWindow.TabbedThumbnail.OnTabbedThumbnailBitmapRequested(); // capture the bitmap for the given control // If the user has already specified us a bitmap to use, use that. IntPtr hBitmap = taskbarWindow.TabbedThumbnail.CurrentHBitmap == IntPtr.Zero ? GrabBitmap(taskbarWindow, realWindowSize) : taskbarWindow.TabbedThumbnail.CurrentHBitmap; // If we have a valid parent window handle, // calculate the offset so we can place the "peek" bitmap // correctly on the app window if (taskbarWindow.TabbedThumbnail.ParentWindowHandle != IntPtr.Zero && taskbarWindow.TabbedThumbnail.WindowHandle != IntPtr.Zero) { System.Drawing.Point offset = new System.Drawing.Point(); // if we don't have a offset specified already by the user... if (!taskbarWindow.TabbedThumbnail.PeekOffset.HasValue) { offset = WindowUtilities.GetParentOffsetOfChild(taskbarWindow.TabbedThumbnail.WindowHandle, taskbarWindow.TabbedThumbnail.ParentWindowHandle); } else { offset = new System.Drawing.Point(Convert.ToInt32(taskbarWindow.TabbedThumbnail.PeekOffset.Value.X), Convert.ToInt32(taskbarWindow.TabbedThumbnail.PeekOffset.Value.Y)); } // Only set the peek bitmap if it's not null. // If it's null (either we didn't get the bitmap or size was 0), // let DWM handle it if (hBitmap != IntPtr.Zero) { if (offset.X >= 0 && offset.Y >= 0) { TabbedThumbnailNativeMethods.SetPeekBitmap( taskbarWindow.WindowToTellTaskbarAbout, hBitmap, offset, taskbarWindow.TabbedThumbnail.DisplayFrameAroundBitmap); } } // If the bitmap we have is not coming from the user (i.e. we created it here), // then make sure we delete it as we don't need it now. if (taskbarWindow.TabbedThumbnail.CurrentHBitmap == IntPtr.Zero) { ShellNativeMethods.DeleteObject(hBitmap); } return(true); } // Else, we don't have a valid window handle from the user. This is mostly likely because // we have a WPF UIElement control. If that's the case, use a different screen capture method // and also couple of ways to try to calculate the control's offset w.r.t it's parent. else if (taskbarWindow.TabbedThumbnail.ParentWindowHandle != IntPtr.Zero && taskbarWindow.TabbedThumbnail.WindowsControl != null) { System.Windows.Point offset; if (!taskbarWindow.TabbedThumbnail.PeekOffset.HasValue) { // Calculate the offset for a WPF UIElement control // For hidden controls, we can't seem to perform the transform. GeneralTransform objGeneralTransform = taskbarWindow.TabbedThumbnail.WindowsControl.TransformToVisual(taskbarWindow.TabbedThumbnail.WindowsControlParentWindow); offset = objGeneralTransform.Transform(new System.Windows.Point(0, 0)); } else { offset = new System.Windows.Point(taskbarWindow.TabbedThumbnail.PeekOffset.Value.X, taskbarWindow.TabbedThumbnail.PeekOffset.Value.Y); } // Only set the peek bitmap if it's not null. // If it's null (either we didn't get the bitmap or size was 0), // let DWM handle it if (hBitmap != IntPtr.Zero) { if (offset.X >= 0 && offset.Y >= 0) { TabbedThumbnailNativeMethods.SetPeekBitmap( taskbarWindow.WindowToTellTaskbarAbout, hBitmap, new System.Drawing.Point((int)offset.X, (int)offset.Y), taskbarWindow.TabbedThumbnail.DisplayFrameAroundBitmap); } else { TabbedThumbnailNativeMethods.SetPeekBitmap( taskbarWindow.WindowToTellTaskbarAbout, hBitmap, taskbarWindow.TabbedThumbnail.DisplayFrameAroundBitmap); } } // If the bitmap we have is not coming from the user (i.e. we created it here), // then make sure we delete it as we don't need it now. if (taskbarWindow.TabbedThumbnail.CurrentHBitmap == IntPtr.Zero) { ShellNativeMethods.DeleteObject(hBitmap); } return(true); } else { // Else (no parent specified), just set the bitmap. It would take over the entire // application window (would work only if you are a MDI app) // Only set the peek bitmap if it's not null. // If it's null (either we didn't get the bitmap or size was 0), // let DWM handle it if (hBitmap != null) { TabbedThumbnailNativeMethods.SetPeekBitmap(taskbarWindow.WindowToTellTaskbarAbout, hBitmap, taskbarWindow.TabbedThumbnail.DisplayFrameAroundBitmap); } // If the bitmap we have is not coming from the user (i.e. we created it here), // then make sure we delete it as we don't need it now. if (taskbarWindow.TabbedThumbnail.CurrentHBitmap == IntPtr.Zero) { ShellNativeMethods.DeleteObject(hBitmap); } return(true); } } return(false); }
public ViewportInformation(Viewport3D viewport, GeneralTransform transform) { this = new Viewport3DHitTestHelper.ViewportInformation(viewport.Children, viewport.Camera, new Size(viewport.ActualWidth, viewport.ActualHeight), transform); }
private void ArrangePopup() { if (((this.m_popup != null) && (this.m_popupRoot != null)) && this.m_popup.IsOpen) { System.Windows.Interop.Content content = Application.Current.Host.Content; double actualWidth = content.ActualWidth; double actualHeight = content.ActualHeight; double num3 = this.m_popupRoot.ActualWidth; double num4 = this.m_popupRoot.ActualHeight; if (((actualHeight != 0.0) && (actualWidth != 0.0)) && ((num3 != 0.0) && (num4 != 0.0))) { GeneralTransform transform = null; try { transform = this.m_popupRoot.TransformToVisual(null); } catch { //Don't need to do nothing. } if (transform != null) { Point point = new Point(0.0, 0.0); Point point2 = new Point(1.0, 0.0); Point point3 = new Point(0.0, 1.0); Point point4 = transform.Transform(point); Point point5 = transform.Transform(point2); Point point6 = transform.Transform(point3); double x = point4.X; double y = point4.Y; double num7 = base.ActualHeight; double num8 = base.ActualWidth; this.m_popup.HorizontalOffset = 0.0; this.m_popup.VerticalOffset = 0.0; this.m_canvasPopupOutside.Width = actualWidth; this.m_canvasPopupOutside.Height = actualHeight; Matrix identity = Matrix.Identity; identity.M11 = point5.X - point4.X; identity.M12 = point5.Y - point4.Y; identity.M21 = point6.X - point4.X; identity.M22 = point6.Y - point4.Y; identity.OffsetX -= point4.X; identity.OffsetY -= point4.Y; MatrixTransform transform2 = new MatrixTransform(); transform2.Matrix = identity; this.m_canvasPopupOutside.RenderTransform = transform2; this.m_popupRoot.MinWidth = num8; this.m_popupRoot.MaxWidth = actualWidth; this.m_popupRoot.MinHeight = num7; this.m_popupRoot.MaxHeight = actualHeight; this.m_popupRoot.HorizontalAlignment = HorizontalAlignment.Left; this.m_popupRoot.VerticalAlignment = VerticalAlignment.Top; try { transform = this.TransformToVisual(null); } catch { //Don't need to do nothing. } point4 = transform.Transform(point); if ((this.m_popupRoot.ActualWidth - base.ActualWidth) <= point4.X) { Canvas.SetLeft(this.m_popupRoot, -(this.m_popupRoot.ActualWidth - this.ActualWidth)); } else { Canvas.SetLeft(this.m_popupRoot, 0); } if (this.m_popupRoot.ActualHeight <= (actualHeight - point4.Y - base.ActualHeight)) { Canvas.SetTop(this.m_popupRoot, base.ActualHeight); } else { Canvas.SetTop(this.m_popupRoot, -this.m_popupRoot.ActualHeight); } bool isTop = false; bool isLeft = false; double popY = Canvas.GetTop(this.m_popupRoot); double popX = Canvas.GetLeft(this.m_popupRoot); if (popY < 0) { isTop = true; } if (popX < 0) { isLeft = true; } if (isTop && isLeft) { this.m_popupContent.Margin = new Thickness(0, 1, 0, 0); VisualStateManager.GoToState(this, "PopTopLeftState", false); } else if (!isTop && isLeft) { this.m_popupContent.Margin = new Thickness(0, -1, 0, 0); VisualStateManager.GoToState(this, "PopBottomLeftState", false); } else if (!isTop && !isLeft) { this.m_popupContent.Margin = new Thickness(0, -1, 0, 0); VisualStateManager.GoToState(this, "PopBottomRightState", false); } else if (isTop && !isLeft) { this.m_popupContent.Margin = new Thickness(0, 1, 0, 0); VisualStateManager.GoToState(this, "PopTopRightState", false); } } } } }