コード例 #1
0
ファイル: ImageFrameRenderer.cs プロジェクト: prepare/HexKit
        /// <summary>
        /// Renders the visual content of the <see cref="ImageFrameRenderer"/>.</summary>
        /// <param name="context">
        /// The <see cref="DrawingContext"/> for the rendering.</param>
        /// <remarks><para>
        /// <b>OnRender</b> attempts to draw the shown <see cref="Frame"/> within the <see
        /// cref="RegularPolygon.Bounds"/> of the current <see cref="Polygon"/>. The drawing is
        /// centered within the <see cref="ImageFrameRenderer"/>.
        /// </para><para>
        /// If drawing fails for any reason, <b>OnRender</b> shows an "invalid" icon instead.
        /// </para></remarks>

        protected override void OnRender(DrawingContext context)
        {
            base.OnRender(context);

            // target rectangle centered on viewport
            Rect target = new Rect(
                (ActualWidth - Polygon.Bounds.Width) / 2.0,
                (ActualHeight - Polygon.Bounds.Height) / 2.0,
                Polygon.Bounds.Width, Polygon.Bounds.Height);

            // attempt to draw image frame
            bool success = false;

            if (Frame != null)
            {
                success = ImageUtility.DrawOutlineFrame(context, Brushes.Black,
                                                        target, Bitmap, Frame.Bounds, Polygon, ScalingX, ScalingY,
                                                        ColorVector.Empty, PointI.Empty, PointI.Empty);
            }

            // draw "invalid" icon on failure
            if (!success)
            {
                ImageUtility.DrawInvalidIcon(context, Brushes.Black, target, Polygon);
            }
        }
コード例 #2
0
        /// <summary>
        /// Draws the <see cref="ImageStack"/> to the specified rectangle.</summary>
        /// <param name="context">
        /// The <see cref="DrawingContext"/> for the drawing.</param>
        /// <param name="target">
        /// The drawing region within <paramref name="context"/>, in device-independent pixels.
        /// </param>
        /// <returns>
        /// <c>true</c> if all <see cref="ImageStack"/> elements were drawn without errors;
        /// otherwise, <c>false</c>.</returns>
        /// <remarks>
        /// <b>DrawImageStack</b> draws the selected <see cref="Frames"/> of all <see
        /// cref="ImageStack"/> elements to the specified <paramref name="target"/> rectangle within
        /// the specified <paramref name="context"/>.</remarks>

        private bool DrawImageStack(DrawingContext context, Rect target)
        {
            Debug.Assert(ImageStack.Count == Frames.Count);

            // fail if no images are available
            if (ImageStack.Count == 0)
            {
                return(false);
            }

            // draw selected frames of all images
            for (int i = 0; i < ImageStack.Count; i++)
            {
                ImageStackEntry entry = ImageStack[i];

                // quit on first unavailable image
                EntityImage image = entry.Image.Value;
                if (image == null)
                {
                    return(false);
                }

                // determine selected frame
                int        frameIndex = Frames[i] % image.Frames.Count;
                ImageFrame frame      = image.Frames[frameIndex];

                // quit on first unavailable bitmap
                if (frame.Source.Value == null)
                {
                    return(false);
                }

                // get desired image scaling, unless disabled
                ImageScaling scalingX = ImageScaling.None, scalingY = ImageScaling.None;
                if (!entry.UseUnscaled)
                {
                    scalingX = image.ScalingX;
                    scalingY = image.ScalingY;
                }

                // draw frame with specified display parameters
                if (!ImageUtility.DrawOutlineFrame(context, Brushes.Black, target,
                                                   frame.Source.Value.Bitmap, frame.Bounds, Polygon, scalingX, scalingY,
                                                   entry.ColorShift, entry.Offset, entry.ScalingVector))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #3
0
ファイル: ImageListBoxItem.cs プロジェクト: prepare/HexKit
        /// <summary>
        /// Renders the visual content of the <see cref="ImageListBoxItem"/>.</summary>
        /// <param name="context">
        /// The <see cref="DrawingContext"/> for the rendering.</param>
        /// <remarks><para>
        /// <b>OnRender</b> calls the base class implementation of <see cref="UIElement.OnRender"/>,
        /// and then attempts to display the current <see cref="ContentControl.Content"/> of the
        /// <see cref="ImageListBoxItem"/>, depending on its type:
        /// </para><list type="bullet"><item>
        /// If the element is an <see cref="EntityImage"/>, its first image frame is drawn above a
        /// text label showing its identifier.
        /// </item><item>
        /// If the element is an <see cref="ImageFrame"/>, the frame is drawn without a label.
        /// </item><item>
        /// If the element is a <see cref="RectI"/>, the corresponding region of the <see
        /// cref="ImageListBox.FrameBitmap"/> is drawn without a label.
        /// </item></list><para>
        /// If the element is of any other type, or if an error occurs, the "invalid" icon returned
        /// by <see cref="Images.Invalid"/> is drawn instead.</para></remarks>

        protected override void OnRender(DrawingContext context)
        {
            base.OnRender(context);

            // default to base class if not in an ImageListBox
            ImageListBox listBox = Parent as ImageListBox;

            if (listBox == null)
            {
                return;
            }

            // get drawing parameters of containing ImageListBox
            WriteableBitmap bitmap = listBox.FrameBitmap;
            ImageScaling    scalingX = listBox.ScalingX, scalingY = listBox.ScalingY;

            // source within bitmap and target within context
            RectI source = RectI.Empty;
            Rect  target = new Rect(0, 0, ActualWidth, ActualHeight);

            /*
             * The default Background brush of a ListBoxItem is transparent, meaning that an item
             * will not register clicks on anything but the non-transparent image and text label.
             *
             * This is very inconvenient, so we always draw a fully opaque background. We use the
             * ListBox.Background brush for regular items, and the system-defined HighlightBrush
             * for selected items. The Foreground brush changes automatically as appropriate.
             *
             * NOTE: The HighlightBrush must be drawn explicitly anyway, or else the Foreground
             * of a selected item would be invisible against the Background of the ListBox!
             */

            Brush background = (listBox.SelectedItem == this ?
                                SystemColors.HighlightBrush : listBox.Background);

            context.DrawRectangle(background, null, target);

            // check which content we're drawing
            if (Content is RectI)
            {
                source = (RectI)Content;
            }
            else
            {
                ImageFrame frame = Content as ImageFrame;
                if (frame == null)
                {
                    EntityImage image = Content as EntityImage;
                    if (image == null)
                    {
                        goto failure;
                    }

                    // get first image frame and scaling
                    frame    = image.Frames[0];
                    scalingX = image.ScalingX;
                    scalingY = image.ScalingY;

                    // compute bounds of image label
                    Point textLocation = new Point(0, ActualHeight - this._labelHeight);
                    Size  textSize     = new Size(ActualWidth, this._labelHeight);

                    // reduce image bounds accordingly
                    target.Height -= textSize.Height;

                    // draw text for image label
                    FormattedText text = FormatLabel(image.Id, textSize);
                    context.DrawText(text, textLocation);
                }

                // final sanity check for valid image frame
                if (frame == null || frame.Source.Value == null)
                {
                    goto failure;
                }

                // draw image frame with associated bitmap
                bitmap = frame.Source.Value.Bitmap;
                source = frame.Bounds;
            }

            // draw specified rectangle with desired bitmap & scaling
            if (ImageUtility.DrawOutlineFrame(context, Foreground, target, bitmap, source,
                                              listBox.Polygon, scalingX, scalingY, ColorVector.Empty, PointI.Empty, PointI.Empty))
            {
                return;
            }

failure:
            // draw "invalid" icon on failure
            ImageUtility.DrawInvalidIcon(context, Foreground, target, listBox.Polygon);
        }