/// <summary> /// Overridden. Set the bounds of this path. /// </summary> /// <param name="x">The new x-coordinate of the bounds/</param> /// <param name="y">The new y-coordinate of the bounds.</param> /// <param name="width">The new width of the bounds.</param> /// <param name="height">The new height of the bounds.</param> /// <returns>True if the bounds have changed; otherwise, false.</returns> /// <remarks> /// This works by scaling the path to fit into the specified bounds. This normally /// works well, but if the specified base bounds get too small then it is impossible /// to expand the path shape again since all its numbers have tended to zero, so /// application code may need to take this into consideration. /// </remarks> protected override void InternalUpdateBounds(float x, float y, float width, float height) { if (updatingBoundsFromPath || path == null) { return; } if (resizePath != null) { path.Reset(); path.AddPath(resizePath, false); } RectangleF pathBounds = path.GetBounds(); if (pen != null && path.PointCount > 0) { try { TEMP_PATH.Reset(); TEMP_PATH.AddPath(path, false); TEMP_PATH.Widen(pen); RectangleF penPathBounds = TEMP_PATH.GetBounds(); float strokeOutset = Math.Max(penPathBounds.Width - pathBounds.Width, penPathBounds.Height - pathBounds.Height); x += strokeOutset / 2; y += strokeOutset / 2; width -= strokeOutset; height -= strokeOutset; } catch (OutOfMemoryException) { // Catch the case where the path is a single point } } float scaleX = (width == 0 || pathBounds.Width == 0) ? 1 : width / pathBounds.Width; float scaleY = (height == 0 || pathBounds.Height == 0) ? 1 : height / pathBounds.Height; TEMP_MATRIX.Reset(); TEMP_MATRIX.TranslateBy(x, y); TEMP_MATRIX.ScaleBy(scaleX, scaleY); TEMP_MATRIX.TranslateBy(-pathBounds.X, -pathBounds.Y); path.Transform(TEMP_MATRIX.MatrixReference); }
//**************************************************************** // Painting - Methods for painting a PText. //**************************************************************** /// <summary> /// Overridden. See <see cref="PNode.Paint">PNode.Paint</see>. /// </summary> protected override void Paint(UMD.HCIL.Piccolo.Util.PPaintContext paintContext) { base.Paint(paintContext); Device device = (paintContext as P3PaintContext).Device; PMatrix currMatrix = (paintContext as P3PaintContext).Transform; // Scale the matrix down to display font units float scale = displayFontSize / font.Size; currMatrix.ScaleBy(scale, X, Y); float[] piccoloMatrixElements = currMatrix.Elements; if (!currMatrix.IsIdentity) { Matrix m = new Matrix(); m.M11 = piccoloMatrixElements[0]; m.M12 = piccoloMatrixElements[1]; m.M21 = piccoloMatrixElements[2]; m.M22 = piccoloMatrixElements[3]; m.M41 = piccoloMatrixElements[4]; m.M42 = piccoloMatrixElements[5]; m.M33 = 1; m.M44 = 1; textSprite.Transform = m; } textSprite.Begin(SpriteFlags.None); DrawTextFormat D3DAlignment = P3Util.GetD3DAlignment(stringFormat.Alignment); // Calculate the rectangle with no padding, in actual font units scale = 1 / scale; int totHzPadding = currLeftPadding + currRightPadding; int totVtPadding = currTopPadding + currBottomPadding; Rectangle dstRect = new Rectangle((int)(Bounds.X + currLeftPadding * scale), (int)(Bounds.Y + currTopPadding * scale), (int)((Bounds.Width - totHzPadding) * scale), (int)((Bounds.Height - totVtPadding) * scale)); // Wrap the string ourselves, instead of letting the draw method do it, since we want to make // sure it's consistent with our own MeasureString method. String str = P3Util.WrapString(textSprite, D3Dfont, Text, dstRect.Width, (TextBrush as SolidBrush).Color); D3Dfont.DrawText(textSprite, str, dstRect, D3DAlignment, (TextBrush as SolidBrush).Color); textSprite.End(); }
//**************************************************************** // Animation - Methods to animate the camera's view. //**************************************************************** /// <summary> /// Animate the camera's view from its current matrix when the activity starts /// to a new matrix that centers the given bounds in the camera layers' coordinate /// system into the camera's view bounds. /// </summary> /// <param name="centerBounds">The bounds to center the view on.</param> /// <param name="shouldScaleToFit"> /// Indicates whether the camera should scale it's view when necessary to fully fit /// the given bounds within the camera's view bounds. /// </param> /// <param name="duration">The amount of time that the animation should take.</param> /// <returns> /// The newly scheduled activity, if the duration is greater than 0; else null. /// </returns> /// <remarks> /// If the duration is 0 then the view will be transformed immediately, and null will /// be returned. Else a new PTransformActivity will get returned that is set to /// animate the camera’s view matrix to the new bounds. If shouldScaleToFit is true, /// then the camera will also scale its view so that the given bounds fit fully within /// the camera's view bounds, else the camera will maintain its original scale. /// </remarks> public virtual PTransformActivity AnimateViewToCenterBounds(RectangleF centerBounds, bool shouldScaleToFit, long duration) { SizeF delta = PUtil.DeltaRequiredToCenter(ViewBounds, centerBounds); PMatrix newMatrix = ViewMatrix; newMatrix.TranslateBy(delta.Width, delta.Height); if (shouldScaleToFit) { float s = Math.Min(ViewBounds.Width / centerBounds.Width, ViewBounds.Height / centerBounds.Height); if (s != float.PositiveInfinity && s != 0) { PointF c = PUtil.CenterOfRectangle(centerBounds); newMatrix.ScaleBy(s, c.X, c.Y); } } return(AnimateViewToMatrix(newMatrix, duration)); }
/// <summary> /// Hilite the specified slide - or unhilite all slides if hiliteIndex is -1. /// </summary> private void HiliteSlide(int newHiliteIndex) { PNode newSlide = null; if (newHiliteIndex >= 0) { newSlide = slides[newHiliteIndex]; } if (newSlide != hiliteSlide) { // First unhilite previously hilited slide if ((hiliteSlide != null) && (hiliteSlide != focusSlide)) { // If this slide is currently animating, then kill that animation int index = (int)hiliteSlide.Tag; if (slideActivities[index] != null) { slideActivities[index].Terminate(); slideActivities[index] = null; } (hiliteSlide as PMultiSizeImage).ShowThumb = true; (hiliteSlide as PMultiSizeImage).Hilite = false; PTransformActivity activity = hiliteSlide.AnimateToMatrix(GetUnfocusedMatrix(hiliteSlide, (int)hiliteSlide.Tag), SLIDEBAR_ANIMATION_TIME_MILLIS); // Put the slide in order when the animation finishes activity.ActivityFinished = new ActivityFinishedDelegate(HiliteActivityFinished); hiliteSlide = null; } // Then hilite new slide (as long is it isn't the currently focused slide) if (newSlide != focusSlide) { hiliteSlide = newSlide; if (hiliteSlide != null) { PMatrix matrix = GetUnfocusedMatrix(hiliteSlide, (int)hiliteSlide.Tag); matrix.ScaleBy(1.3f, (hiliteSlide.Bounds.Width / 2), hiliteSlide.Bounds.Height); (hiliteSlide as PMultiSizeImage).Hilite = true; hiliteSlide.MoveToFront(); currentPosition.MoveToFront(); slideActivities[newHiliteIndex] = hiliteSlide.AnimateToMatrix(matrix, SLIDEBAR_ANIMATION_TIME_MILLIS); } } } }