<commit_before>﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace Manina.Windows.Forms
{
    /// <summary>
    /// Zooms on items on mouse over.
    /// </summary>
    public class ZoomingRenderer : ImageListView.ImageListViewRenderer
    {
        /// <summary>
        /// Initializes the System.Drawing.Graphics used to draw
        /// control elements.
        /// </summary>
        /// <param name="g">The System.Drawing.Graphics to draw on.</param>
        public override void InitializeGraphics(System.Drawing.Graphics g)
        {
            base.InitializeGraphics(g);

            Clip = false;
            g.InterpolationMode = InterpolationMode.NearestNeighbor;
            ItemDrawOrder = ItemDrawOrder.NormalSelectedHovered;
        }
        /// <summary>
        /// Returns item size for the given view mode.
        /// </summary>
        /// <param name="view">The view mode for which the item measurement should be made.</param>
        /// <returns></returns>
        public override Size MeasureItem(View view)
        {
            if (view == View.Thumbnails)
                return mImageListView.ThumbnailSize + new Size(8, 8);
            else
                return base.MeasureItem(view);
        }
        /// <summary>
        /// Draws the specified item on the given graphics.
        /// </summary>
        /// <param name="g">The System.Drawing.Graphics to draw on.</param>
        /// <param name="item">The ImageListViewItem to draw.</param>
        /// <param name="state">The current view state of item.</param>
        /// <param name="bounds">The bounding rectangle of item in client coordinates.</param>
        public override void DrawItem(Graphics g, ImageListViewItem item, ItemState state, Rectangle bounds)
        {
            if (ImageListView.View == View.Thumbnails)
            {
                // Zoom on mouse over
                if ((state & ItemState.Hovered) != ItemState.None)
                {
                    bounds.Inflate((int)(bounds.Width * 0.5f), (int)(bounds.Height * 0.5f));
                    if (bounds.Bottom > ItemAreaBounds.Bottom)
                        bounds.Y = ItemAreaBounds.Bottom - bounds.Height;
                    if (bounds.Top < ItemAreaBounds.Top)
                        bounds.Y = ItemAreaBounds.Top;
                    if (bounds.Right > ItemAreaBounds.Right)
                        bounds.X = ItemAreaBounds.Right - bounds.Width;
                    if (bounds.Left < ItemAreaBounds.Left)
                        bounds.X = ItemAreaBounds.Left;
                }

                // Get item image
                Image img = null;
                if ((state & ItemState.Hovered) == ItemState.None)
                    img = item.ThumbnailImage;
                else
                    img = item.GetImage();

                // Calculate image bounds
                float xscale = ((float)bounds.Width - 8.0f) / (float)img.Width;
                float yscale = ((float)bounds.Height - 8.0f) / (float)img.Height;
                float scale = Math.Min(xscale, yscale);
                if (scale > 1.0f) scale = 1.0f;
                int imageWidth = (int)((float)img.Width * scale);
                int imageHeight = (int)((float)img.Height * scale);
                int imageX = bounds.Left + (bounds.Width - imageWidth) / 2;
                int imageY = bounds.Top + (bounds.Height - imageHeight) / 2;

                // Allocate space for item text
                if ((state & ItemState.Hovered) != ItemState.None &&
                    (bounds.Height - imageHeight) / 2 < mImageListView.Font.Height + 8)
                {
                    int delta = (mImageListView.Font.Height + 8) - (bounds.Height - imageHeight) / 2;
                    bounds.Height += 2 * delta;
                    imageY += delta;
                }

                // Paint background
                using (Brush bBack = new SolidBrush(mImageListView.BackColor))
                {
                    Utility.FillRoundedRectangle(g, bBack, bounds, 4);
                }
                using (Brush bItemBack = new SolidBrush(item.BackColor))
                {
                    Utility.FillRoundedRectangle(g, bItemBack, bounds, 4);
                }
                if (mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    using (Brush bSelected = new LinearGradientBrush(bounds, Color.FromArgb(16, SystemColors.Highlight), Color.FromArgb(64, SystemColors.Highlight), LinearGradientMode.Vertical))
                    {
                        Utility.FillRoundedRectangle(g, bSelected, bounds, 4);
                    }
                }
                else if (!mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    using (Brush bGray64 = new LinearGradientBrush(bounds, Color.FromArgb(16, SystemColors.GrayText), Color.FromArgb(64, SystemColors.GrayText), LinearGradientMode.Vertical))
                    {
                        Utility.FillRoundedRectangle(g, bGray64, bounds, 4);
                    }
                }
                if (((state & ItemState.Hovered) != ItemState.None))
                {
                    using (Brush bHovered = new LinearGradientBrush(bounds, Color.FromArgb(8, SystemColors.Highlight), Color.FromArgb(32, SystemColors.Highlight), LinearGradientMode.Vertical))
                    {
                        Utility.FillRoundedRectangle(g, bHovered, bounds, 4);
                    }
                }

                // Draw the image
                g.DrawImage(img, imageX, imageY, imageWidth, imageHeight);
                // Draw image border
                if (img.Width > 32)
                {
                    using (Pen pGray128 = new Pen(Color.FromArgb(128, Color.Gray)))
                    {
                        g.DrawRectangle(pGray128, imageX, imageY, imageWidth, imageHeight);
                    }
                    if (System.Math.Min(imageWidth, imageHeight) > 32)
                    {
                        using (Pen pWhite128 = new Pen(Color.FromArgb(128, Color.White)))
                        {
                            g.DrawRectangle(pWhite128, imageX + 1, imageY + 1, imageWidth - 2, imageHeight - 2);
                        }
                    }
                }

                // Draw item text
                if ((state & ItemState.Hovered) != ItemState.None)
                {
                    RectangleF rt;
                    StringFormat sf = new StringFormat();
                    rt = new RectangleF(bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, (bounds.Height - imageHeight) / 2 - 8);
                    sf.Alignment = StringAlignment.Center;
                    sf.FormatFlags = StringFormatFlags.NoWrap;
                    sf.LineAlignment = StringAlignment.Center;
                    sf.Trimming = StringTrimming.EllipsisCharacter;
                    using (Brush bItemFore = new SolidBrush(item.ForeColor))
                    {
                        g.DrawString(item.Text, mImageListView.Font, bItemFore, rt, sf);
                    }
                    rt.Y = bounds.Bottom - (bounds.Height - imageHeight) / 2 + 4;
                    using (Brush bGrayText = new SolidBrush(Color.Gray))
                    {
                        g.DrawString(string.Format("{0} pixels, {1}", item.GetSubItemText(ColumnType.Dimension), item.GetSubItemText(ColumnType.FileSize)),
                            mImageListView.Font, bGrayText, rt, sf);
                    }
                }

                // Item border
                using (Pen pWhite128 = new Pen(Color.FromArgb(128, Color.White)))
                {
                    Utility.DrawRoundedRectangle(g, pWhite128, bounds.Left + 1, bounds.Top + 1, bounds.Width - 3, bounds.Height - 3, 4);
                }
                if (mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    using (Pen pHighlight128 = new Pen(Color.FromArgb(128, SystemColors.Highlight)))
                    {
                        Utility.DrawRoundedRectangle(g, pHighlight128, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4);
                    }
                }
                else if (!mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    using (Pen pGray128 = new Pen(Color.FromArgb(128, SystemColors.GrayText)))
                    {
                        Utility.DrawRoundedRectangle(g, pGray128, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4);
                    }
                }
                else if ((state & ItemState.Selected) == ItemState.None)
                {
                    using (Pen pGray64 = new Pen(Color.FromArgb(64, SystemColors.GrayText)))
                    {
                        Utility.DrawRoundedRectangle(g, pGray64, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4);
                    }
                }

                if (mImageListView.Focused && ((state & ItemState.Hovered) != ItemState.None))
                {
                    using (Pen pHighlight64 = new Pen(Color.FromArgb(64, SystemColors.Highlight)))
                    {
                        Utility.DrawRoundedRectangle(g, pHighlight64, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4);
                    }
                }
            }
            else
                base.DrawItem(g, item, state, bounds);
        }
    }

    /// <summary>
    /// Displays items with large tiles.
    /// </summary>
    public class TilesRenderer : ImageListView.ImageListViewRenderer
    {
        private Font font = null;
        private int tileSize;
        private int textHeight;

        public TilesRenderer()
            : this(180)
        {
        }

        public TilesRenderer(int tileWidth)
        {
            tileSize = tileWidth;
        }

        public override void OnDispose()
        {
            font.Dispose();
        }

        /// <summary>
        /// Returns item size for the given view mode.
        /// </summary>
        /// <param name="view">The view mode for which the item measurement should be made.</param>
        public override Size MeasureItem(View view)
        {
            if (view == View.Thumbnails)
            {
                Size itemSize = new Size();
                if (font == null)
                    font = new Font(mImageListView.Font, FontStyle.Bold);
                textHeight = (int)(5.8f * (float)font.Height);

                // Calculate item size
                Size itemPadding = new Size(4, 4);
                itemSize.Width = mImageListView.ThumbnailSize.Width + 4 * itemPadding.Width + tileSize;
                itemSize.Height = Math.Max(textHeight, mImageListView.ThumbnailSize.Height) + itemPadding.Height;
                return itemSize;
            }
            else
                return base.MeasureItem(view);
        }
        /// <summary>
        /// Draws the specified item on the given graphics.
        /// </summary>
        /// <param name="g">The System.Drawing.Graphics to draw on.</param>
        /// <param name="item">The ImageListViewItem to draw.</param>
        /// <param name="state">The current view state of item.</param>
        /// <param name="bounds">The bounding rectangle of item in client coordinates.</param>
        public override void DrawItem(Graphics g, ImageListViewItem item, ItemState state, Rectangle bounds)
        {
            if (ImageListView.View == View.Thumbnails)
            {
                Size itemPadding = new Size(4, 4);

                // Paint background
                using (Brush bItemBack = new SolidBrush(item.BackColor))
                {
                    g.FillRectangle(bItemBack, bounds);
                }
                if (mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    using (Brush bSelected = new LinearGradientBrush(bounds, Color.FromArgb(16, SystemColors.Highlight), Color.FromArgb(64, SystemColors.Highlight), LinearGradientMode.Vertical))
                    {
                        Utility.FillRoundedRectangle(g, bSelected, bounds, 4);
                    }
                }
                else if (!mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    using (Brush bGray64 = new LinearGradientBrush(bounds, Color.FromArgb(16, SystemColors.GrayText), Color.FromArgb(64, SystemColors.GrayText), LinearGradientMode.Vertical))
                    {
                        Utility.FillRoundedRectangle(g, bGray64, bounds, 4);
                    }
                }
                if (((state & ItemState.Hovered) != ItemState.None))
                {
                    using (Brush bHovered = new LinearGradientBrush(bounds, Color.FromArgb(8, SystemColors.Highlight), Color.FromArgb(32, SystemColors.Highlight), LinearGradientMode.Vertical))
                    {
                        Utility.FillRoundedRectangle(g, bHovered, bounds, 4);
                    }
                }

                // Draw the image
                Image img = item.ThumbnailImage;
                if (img != null)
                {
                    int x = bounds.Left + itemPadding.Width + (mImageListView.ThumbnailSize.Width - img.Width) / 2;
                    int y = bounds.Top + itemPadding.Height + (mImageListView.ThumbnailSize.Height - img.Height) / 2;
                    g.DrawImageUnscaled(img, x, y);
                    // Draw image border
                    if (img.Width > 32)
                    {
                        using (Pen pGray128 = new Pen(Color.FromArgb(128, Color.Gray)))
                        {
                            g.DrawRectangle(pGray128, x, y, img.Width, img.Height);
                        }
                        if (System.Math.Min(mImageListView.ThumbnailSize.Width, mImageListView.ThumbnailSize.Height) > 32)
                        {
                            using (Pen pWhite128 = new Pen(Color.FromArgb(128, Color.White)))
                            {
                                g.DrawRectangle(pWhite128, x + 1, y + 1, img.Width - 2, img.Height - 2);
                            }
                        }
                    }

                    // Draw item text
                    int lineHeight = font.Height;
                    RectangleF rt;
                    StringFormat sf = new StringFormat();
                    rt = new RectangleF(bounds.Left + 2 * itemPadding.Width + mImageListView.ThumbnailSize.Width,
                        bounds.Top + itemPadding.Height + (Math.Max(mImageListView.ThumbnailSize.Height, textHeight) - textHeight) / 2,
                        tileSize, lineHeight);
                    sf.Alignment = StringAlignment.Near;
                    sf.FormatFlags = StringFormatFlags.NoWrap;
                    sf.LineAlignment = StringAlignment.Center;
                    sf.Trimming = StringTrimming.EllipsisCharacter;
                    using (Brush bItemFore = new SolidBrush(item.ForeColor))
                    {
                        g.DrawString(item.Text, font, bItemFore, rt, sf);
                    }
                    using (Brush bItemDetails = new SolidBrush(Color.Gray))
                    {
                        rt.Offset(0, 1.5f * lineHeight);
                        g.DrawString(item.GetSubItemText(ColumnType.FileType),
                            mImageListView.Font, bItemDetails, rt, sf);
                        rt.Offset(0, 1.1f * lineHeight);
                        g.DrawString(string.Format("{0} pixels, {1} dpi", item.GetSubItemText(ColumnType.Dimension), item.Resolution.Width),
                            mImageListView.Font, bItemDetails, rt, sf);
                        rt.Offset(0, 1.1f * lineHeight);
                        g.DrawString(item.GetSubItemText(ColumnType.FileSize),
                            mImageListView.Font, bItemDetails, rt, sf);
                        rt.Offset(0, 1.1f * lineHeight);
                        g.DrawString(item.GetSubItemText(ColumnType.DateModified),
                            mImageListView.Font, bItemDetails, rt, sf);
                    }
                }

                // Item border
                using (Pen pWhite128 = new Pen(Color.FromArgb(128, Color.White)))
                {
                    Utility.DrawRoundedRectangle(g, pWhite128, bounds.Left + 1, bounds.Top + 1, bounds.Width - 3, bounds.Height - 3, 4);
                }
                if (mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    using (Pen pHighlight128 = new Pen(Color.FromArgb(128, SystemColors.Highlight)))
                    {
                        Utility.DrawRoundedRectangle(g, pHighlight128, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4);
                    }
                }
                else if (!mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    using (Pen pGray128 = new Pen(Color.FromArgb(128, SystemColors.GrayText)))
                    {
                        Utility.DrawRoundedRectangle(g, pGray128, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4);
                    }
                }
                else if ((state & ItemState.Selected) == ItemState.None)
                {
                    using (Pen pGray64 = new Pen(Color.FromArgb(64, SystemColors.GrayText)))
                    {
                        Utility.DrawRoundedRectangle(g, pGray64, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4);
                    }
                }

                if (mImageListView.Focused && ((state & ItemState.Hovered) != ItemState.None))
                {
                    using (Pen pHighlight64 = new Pen(Color.FromArgb(64, SystemColors.Highlight)))
                    {
                        Utility.DrawRoundedRectangle(g, pHighlight64, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4);
                    }
                }

                // Focus rectangle
                if (mImageListView.Focused && ((state & ItemState.Focused) != ItemState.None))
                {
                    ControlPaint.DrawFocusRectangle(g, bounds);
                }
            }
            else
                base.DrawItem(g, item, state, bounds);
        }
    }

    /// <summary>
    /// Mimics Windows XP appearance.
    /// </summary>
    public class XPRenderer : ImageListView.ImageListViewRenderer
    {
        /// <summary>
        /// Returns item size for the given view mode.
        /// </summary>
        /// <param name="view">The view mode for which the item measurement should be made.</param>
        public override Size MeasureItem(View view)
        {
            Size itemSize = new Size();

            // Reference text height
            int textHeight = mImageListView.Font.Height;

            if (view == View.Thumbnails)
            {
                // Calculate item size
                Size itemPadding = new Size(4, 4);
                itemSize = mImageListView.ThumbnailSize + itemPadding + itemPadding;
                itemSize.Height += textHeight + System.Math.Max(4, textHeight / 3) + itemPadding.Height; // textHeight / 3 = vertical space between thumbnail and text
                return itemSize;
            }
            else
                return base.MeasureItem(view);
        }
        /// <summary>
        /// Draws the specified item on the given graphics.
        /// </summary>
        /// <param name="g">The System.Drawing.Graphics to draw on.</param>
        /// <param name="item">The ImageListViewItem to draw.</param>
        /// <param name="state">The current view state of item.</param>
        /// <param name="bounds">The bounding rectangle of item in client coordinates.</param>
        public override void DrawItem(System.Drawing.Graphics g, ImageListViewItem item, ItemState state, System.Drawing.Rectangle bounds)
        {
            // Paint background
            using (Brush bItemBack = new SolidBrush(item.BackColor))
            {
                g.FillRectangle(bItemBack, bounds);
            }

            if (mImageListView.View == View.Thumbnails)
            {
                Size itemPadding = new Size(4, 4);

                // Draw the image
                Image img = item.ThumbnailImage;
                if (img != null)
                {
                    int x = bounds.Left + itemPadding.Width + (mImageListView.ThumbnailSize.Width - img.Width) / 2;
                    int y = bounds.Top + itemPadding.Height + (mImageListView.ThumbnailSize.Height - img.Height) / 2;
                    Rectangle imageBounds = new Rectangle(bounds.Location + itemPadding, mImageListView.ThumbnailSize);
                    g.DrawImageUnscaled(img, x, y);
                    // Draw image border
                    if (img.Width > 32)
                    {
                        if (mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                        {
                            using (Pen pen = new Pen(SystemColors.Highlight, 3))
                            {
                                g.DrawRectangle(pen, imageBounds);
                            }
                        }
                        else if (!mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                        {
                            using (Pen pen = new Pen(SystemColors.GrayText, 3))
                            {
                                g.DrawRectangle(pen, imageBounds);
                            }
                        }
                        else
                        {
                            using (Pen pGray128 = new Pen(Color.FromArgb(128, SystemColors.GrayText)))
                            {
                                g.DrawRectangle(pGray128, imageBounds);
                            }
                        }
                    }
                }

                // Draw item text
                SizeF szt = TextRenderer.MeasureText(item.Text, mImageListView.Font);
                RectangleF rt;
                StringFormat sf = new StringFormat();
                rt = new RectangleF(bounds.Left + itemPadding.Width, bounds.Top + 3 * itemPadding.Height + mImageListView.ThumbnailSize.Height, mImageListView.ThumbnailSize.Width, szt.Height);
                sf.Alignment = StringAlignment.Center;
                sf.FormatFlags = StringFormatFlags.NoWrap;
                sf.LineAlignment = StringAlignment.Center;
                sf.Trimming = StringTrimming.EllipsisCharacter;
                rt.Inflate(0, 2);
                if (mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    g.FillRectangle(SystemBrushes.Highlight, rt);
                }
                else if (!mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    g.FillRectangle(SystemBrushes.GrayText, rt);
                }
                if (((state & ItemState.Selected) != ItemState.None))
                {
                    g.DrawString(item.Text, mImageListView.Font, SystemBrushes.HighlightText, rt, sf);
                }
                else
                {
                    using (Brush bItemFore = new SolidBrush(item.ForeColor))
                    {
                        g.DrawString(item.Text, mImageListView.Font, bItemFore, rt, sf);
                    }
                }

                if (mImageListView.Focused && ((state & ItemState.Focused) != ItemState.None))
                {
                    Rectangle fRect = Rectangle.Round(rt);
                    fRect.Inflate(1, 1);
                    ControlPaint.DrawFocusRectangle(g, fRect);
                }
            }
            else
            {
                if (mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    g.FillRectangle(SystemBrushes.Highlight, bounds);
                }
                else if (!mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    g.FillRectangle(SystemBrushes.GrayText, bounds);
                }

                Size offset = new Size(2, (bounds.Height - mImageListView.Font.Height) / 2);
                StringFormat sf = new StringFormat();
                sf.FormatFlags = StringFormatFlags.NoWrap;
                sf.Alignment = StringAlignment.Near;
                sf.LineAlignment = StringAlignment.Center;
                sf.Trimming = StringTrimming.EllipsisCharacter;
                // Sub text
                List<Manina.Windows.Forms.ImageListView.ImageListViewColumnHeader> uicolumns = mImageListView.Columns.GetUIColumns();
                RectangleF rt = new RectangleF(bounds.Left + offset.Width, bounds.Top + offset.Height, uicolumns[0].Width - 2 * offset.Width, bounds.Height - 2 * offset.Height);
                foreach (Manina.Windows.Forms.ImageListView.ImageListViewColumnHeader column in uicolumns)
                {
                    rt.Width = column.Width - 2 * offset.Width;
                    using (Brush bItemFore = new SolidBrush(item.ForeColor))
                    {
                        if ((state & ItemState.Selected) == ItemState.None)
                            g.DrawString(item.GetSubItemText(column.Type), mImageListView.Font, bItemFore, rt, sf);
                        else
                            g.DrawString(item.GetSubItemText(column.Type), mImageListView.Font, SystemBrushes.HighlightText, rt, sf);
                    }
                    rt.X += column.Width;
                }

                if (mImageListView.Focused && ((state & ItemState.Focused) != ItemState.None))
                    ControlPaint.DrawFocusRectangle(g, bounds);
            }
        }
    }
}
<commit_msg>Very minor fix in ZoomingRenderer's draw image border code.<commit_after>﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace Manina.Windows.Forms
{
    /// <summary>
    /// Zooms on items on mouse over.
    /// </summary>
    public class ZoomingRenderer : ImageListView.ImageListViewRenderer
    {
        /// <summary>
        /// Initializes the System.Drawing.Graphics used to draw
        /// control elements.
        /// </summary>
        /// <param name="g">The System.Drawing.Graphics to draw on.</param>
        public override void InitializeGraphics(System.Drawing.Graphics g)
        {
            base.InitializeGraphics(g);

            Clip = false;
            g.InterpolationMode = InterpolationMode.NearestNeighbor;
            ItemDrawOrder = ItemDrawOrder.NormalSelectedHovered;
        }
        /// <summary>
        /// Returns item size for the given view mode.
        /// </summary>
        /// <param name="view">The view mode for which the item measurement should be made.</param>
        /// <returns></returns>
        public override Size MeasureItem(View view)
        {
            if (view == View.Thumbnails)
                return mImageListView.ThumbnailSize + new Size(8, 8);
            else
                return base.MeasureItem(view);
        }
        /// <summary>
        /// Draws the specified item on the given graphics.
        /// </summary>
        /// <param name="g">The System.Drawing.Graphics to draw on.</param>
        /// <param name="item">The ImageListViewItem to draw.</param>
        /// <param name="state">The current view state of item.</param>
        /// <param name="bounds">The bounding rectangle of item in client coordinates.</param>
        public override void DrawItem(Graphics g, ImageListViewItem item, ItemState state, Rectangle bounds)
        {
            if (ImageListView.View == View.Thumbnails)
            {
                // Zoom on mouse over
                if ((state & ItemState.Hovered) != ItemState.None)
                {
                    bounds.Inflate((int)(bounds.Width * 0.5f), (int)(bounds.Height * 0.5f));
                    if (bounds.Bottom > ItemAreaBounds.Bottom)
                        bounds.Y = ItemAreaBounds.Bottom - bounds.Height;
                    if (bounds.Top < ItemAreaBounds.Top)
                        bounds.Y = ItemAreaBounds.Top;
                    if (bounds.Right > ItemAreaBounds.Right)
                        bounds.X = ItemAreaBounds.Right - bounds.Width;
                    if (bounds.Left < ItemAreaBounds.Left)
                        bounds.X = ItemAreaBounds.Left;
                }

                // Get item image
                Image img = null;
                if ((state & ItemState.Hovered) == ItemState.None)
                    img = item.ThumbnailImage;
                else
                    img = item.GetImage();

                // Calculate image bounds
                float xscale = ((float)bounds.Width - 8.0f) / (float)img.Width;
                float yscale = ((float)bounds.Height - 8.0f) / (float)img.Height;
                float scale = Math.Min(xscale, yscale);
                if (scale > 1.0f) scale = 1.0f;
                int imageWidth = (int)((float)img.Width * scale);
                int imageHeight = (int)((float)img.Height * scale);
                int imageX = bounds.Left + (bounds.Width - imageWidth) / 2;
                int imageY = bounds.Top + (bounds.Height - imageHeight) / 2;

                // Allocate space for item text
                if ((state & ItemState.Hovered) != ItemState.None &&
                    (bounds.Height - imageHeight) / 2 < mImageListView.Font.Height + 8)
                {
                    int delta = (mImageListView.Font.Height + 8) - (bounds.Height - imageHeight) / 2;
                    bounds.Height += 2 * delta;
                    imageY += delta;
                }

                // Paint background
                using (Brush bBack = new SolidBrush(mImageListView.BackColor))
                {
                    Utility.FillRoundedRectangle(g, bBack, bounds, 5);
                }
                using (Brush bItemBack = new SolidBrush(item.BackColor))
                {
                    Utility.FillRoundedRectangle(g, bItemBack, bounds, 5);
                }
                if (mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    using (Brush bSelected = new LinearGradientBrush(bounds, Color.FromArgb(16, SystemColors.Highlight), Color.FromArgb(64, SystemColors.Highlight), LinearGradientMode.Vertical))
                    {
                        Utility.FillRoundedRectangle(g, bSelected, bounds, 5);
                    }
                }
                else if (!mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    using (Brush bGray64 = new LinearGradientBrush(bounds, Color.FromArgb(16, SystemColors.GrayText), Color.FromArgb(64, SystemColors.GrayText), LinearGradientMode.Vertical))
                    {
                        Utility.FillRoundedRectangle(g, bGray64, bounds, 5);
                    }
                }
                if (((state & ItemState.Hovered) != ItemState.None))
                {
                    using (Brush bHovered = new LinearGradientBrush(bounds, Color.FromArgb(8, SystemColors.Highlight), Color.FromArgb(32, SystemColors.Highlight), LinearGradientMode.Vertical))
                    {
                        Utility.FillRoundedRectangle(g, bHovered, bounds, 5);
                    }
                }

                // Draw the image
                g.DrawImage(img, imageX, imageY, imageWidth, imageHeight);
                // Draw image border
                if (imageWidth > 32)
                {
                    using (Pen pGray128 = new Pen(Color.FromArgb(128, Color.Gray)))
                    {
                        g.DrawRectangle(pGray128, imageX, imageY, imageWidth, imageHeight);
                    }
                    if (System.Math.Min(imageWidth, imageHeight) > 32)
                    {
                        using (Pen pWhite128 = new Pen(Color.FromArgb(128, Color.White)))
                        {
                            g.DrawRectangle(pWhite128, imageX + 1, imageY + 1, imageWidth - 2, imageHeight - 2);
                        }
                    }
                }

                // Draw item text
                if ((state & ItemState.Hovered) != ItemState.None)
                {
                    RectangleF rt;
                    StringFormat sf = new StringFormat();
                    rt = new RectangleF(bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, (bounds.Height - imageHeight) / 2 - 8);
                    sf.Alignment = StringAlignment.Center;
                    sf.FormatFlags = StringFormatFlags.NoWrap;
                    sf.LineAlignment = StringAlignment.Center;
                    sf.Trimming = StringTrimming.EllipsisCharacter;
                    using (Brush bItemFore = new SolidBrush(item.ForeColor))
                    {
                        g.DrawString(item.Text, mImageListView.Font, bItemFore, rt, sf);
                    }
                    rt.Y = bounds.Bottom - (bounds.Height - imageHeight) / 2 + 4;
                    using (Brush bGrayText = new SolidBrush(Color.Gray))
                    {
                        g.DrawString(string.Format("{0} pixels, {1}", item.GetSubItemText(ColumnType.Dimension), item.GetSubItemText(ColumnType.FileSize)),
                            mImageListView.Font, bGrayText, rt, sf);
                    }
                }

                // Item border
                using (Pen pWhite128 = new Pen(Color.FromArgb(128, Color.White)))
                {
                    Utility.DrawRoundedRectangle(g, pWhite128, bounds.Left + 1, bounds.Top + 1, bounds.Width - 3, bounds.Height - 3, 4);
                }
                if (mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    using (Pen pHighlight128 = new Pen(Color.FromArgb(128, SystemColors.Highlight)))
                    {
                        Utility.DrawRoundedRectangle(g, pHighlight128, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4);
                    }
                }
                else if (!mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    using (Pen pGray128 = new Pen(Color.FromArgb(128, SystemColors.GrayText)))
                    {
                        Utility.DrawRoundedRectangle(g, pGray128, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4);
                    }
                }
                else if ((state & ItemState.Selected) == ItemState.None)
                {
                    using (Pen pGray64 = new Pen(Color.FromArgb(64, SystemColors.GrayText)))
                    {
                        Utility.DrawRoundedRectangle(g, pGray64, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4);
                    }
                }

                if (mImageListView.Focused && ((state & ItemState.Hovered) != ItemState.None))
                {
                    using (Pen pHighlight64 = new Pen(Color.FromArgb(64, SystemColors.Highlight)))
                    {
                        Utility.DrawRoundedRectangle(g, pHighlight64, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4);
                    }
                }
            }
            else
                base.DrawItem(g, item, state, bounds);
        }
    }

    /// <summary>
    /// Displays items with large tiles.
    /// </summary>
    public class TilesRenderer : ImageListView.ImageListViewRenderer
    {
        private Font font = null;
        private int tileSize;
        private int textHeight;

        public TilesRenderer()
            : this(180)
        {
        }

        public TilesRenderer(int tileWidth)
        {
            tileSize = tileWidth;
        }

        public override void OnDispose()
        {
            font.Dispose();
        }

        /// <summary>
        /// Returns item size for the given view mode.
        /// </summary>
        /// <param name="view">The view mode for which the item measurement should be made.</param>
        public override Size MeasureItem(View view)
        {
            if (view == View.Thumbnails)
            {
                Size itemSize = new Size();
                if (font == null)
                    font = new Font(mImageListView.Font, FontStyle.Bold);
                textHeight = (int)(5.8f * (float)font.Height);

                // Calculate item size
                Size itemPadding = new Size(4, 4);
                itemSize.Width = mImageListView.ThumbnailSize.Width + 4 * itemPadding.Width + tileSize;
                itemSize.Height = Math.Max(textHeight, mImageListView.ThumbnailSize.Height) + itemPadding.Height;
                return itemSize;
            }
            else
                return base.MeasureItem(view);
        }
        /// <summary>
        /// Draws the specified item on the given graphics.
        /// </summary>
        /// <param name="g">The System.Drawing.Graphics to draw on.</param>
        /// <param name="item">The ImageListViewItem to draw.</param>
        /// <param name="state">The current view state of item.</param>
        /// <param name="bounds">The bounding rectangle of item in client coordinates.</param>
        public override void DrawItem(Graphics g, ImageListViewItem item, ItemState state, Rectangle bounds)
        {
            if (ImageListView.View == View.Thumbnails)
            {
                Size itemPadding = new Size(4, 4);

                // Paint background
                using (Brush bItemBack = new SolidBrush(item.BackColor))
                {
                    g.FillRectangle(bItemBack, bounds);
                }
                if (mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    using (Brush bSelected = new LinearGradientBrush(bounds, Color.FromArgb(16, SystemColors.Highlight), Color.FromArgb(64, SystemColors.Highlight), LinearGradientMode.Vertical))
                    {
                        Utility.FillRoundedRectangle(g, bSelected, bounds, 4);
                    }
                }
                else if (!mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    using (Brush bGray64 = new LinearGradientBrush(bounds, Color.FromArgb(16, SystemColors.GrayText), Color.FromArgb(64, SystemColors.GrayText), LinearGradientMode.Vertical))
                    {
                        Utility.FillRoundedRectangle(g, bGray64, bounds, 4);
                    }
                }
                if (((state & ItemState.Hovered) != ItemState.None))
                {
                    using (Brush bHovered = new LinearGradientBrush(bounds, Color.FromArgb(8, SystemColors.Highlight), Color.FromArgb(32, SystemColors.Highlight), LinearGradientMode.Vertical))
                    {
                        Utility.FillRoundedRectangle(g, bHovered, bounds, 4);
                    }
                }

                // Draw the image
                Image img = item.ThumbnailImage;
                if (img != null)
                {
                    int x = bounds.Left + itemPadding.Width + (mImageListView.ThumbnailSize.Width - img.Width) / 2;
                    int y = bounds.Top + itemPadding.Height + (mImageListView.ThumbnailSize.Height - img.Height) / 2;
                    g.DrawImageUnscaled(img, x, y);
                    // Draw image border
                    if (img.Width > 32)
                    {
                        using (Pen pGray128 = new Pen(Color.FromArgb(128, Color.Gray)))
                        {
                            g.DrawRectangle(pGray128, x, y, img.Width, img.Height);
                        }
                        if (System.Math.Min(mImageListView.ThumbnailSize.Width, mImageListView.ThumbnailSize.Height) > 32)
                        {
                            using (Pen pWhite128 = new Pen(Color.FromArgb(128, Color.White)))
                            {
                                g.DrawRectangle(pWhite128, x + 1, y + 1, img.Width - 2, img.Height - 2);
                            }
                        }
                    }

                    // Draw item text
                    int lineHeight = font.Height;
                    RectangleF rt;
                    StringFormat sf = new StringFormat();
                    rt = new RectangleF(bounds.Left + 2 * itemPadding.Width + mImageListView.ThumbnailSize.Width,
                        bounds.Top + itemPadding.Height + (Math.Max(mImageListView.ThumbnailSize.Height, textHeight) - textHeight) / 2,
                        tileSize, lineHeight);
                    sf.Alignment = StringAlignment.Near;
                    sf.FormatFlags = StringFormatFlags.NoWrap;
                    sf.LineAlignment = StringAlignment.Center;
                    sf.Trimming = StringTrimming.EllipsisCharacter;
                    using (Brush bItemFore = new SolidBrush(item.ForeColor))
                    {
                        g.DrawString(item.Text, font, bItemFore, rt, sf);
                    }
                    using (Brush bItemDetails = new SolidBrush(Color.Gray))
                    {
                        rt.Offset(0, 1.5f * lineHeight);
                        g.DrawString(item.GetSubItemText(ColumnType.FileType),
                            mImageListView.Font, bItemDetails, rt, sf);
                        rt.Offset(0, 1.1f * lineHeight);
                        g.DrawString(string.Format("{0} pixels, {1} dpi", item.GetSubItemText(ColumnType.Dimension), item.Resolution.Width),
                            mImageListView.Font, bItemDetails, rt, sf);
                        rt.Offset(0, 1.1f * lineHeight);
                        g.DrawString(item.GetSubItemText(ColumnType.FileSize),
                            mImageListView.Font, bItemDetails, rt, sf);
                        rt.Offset(0, 1.1f * lineHeight);
                        g.DrawString(item.GetSubItemText(ColumnType.DateModified),
                            mImageListView.Font, bItemDetails, rt, sf);
                    }
                }

                // Item border
                using (Pen pWhite128 = new Pen(Color.FromArgb(128, Color.White)))
                {
                    Utility.DrawRoundedRectangle(g, pWhite128, bounds.Left + 1, bounds.Top + 1, bounds.Width - 3, bounds.Height - 3, 4);
                }
                if (mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    using (Pen pHighlight128 = new Pen(Color.FromArgb(128, SystemColors.Highlight)))
                    {
                        Utility.DrawRoundedRectangle(g, pHighlight128, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4);
                    }
                }
                else if (!mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    using (Pen pGray128 = new Pen(Color.FromArgb(128, SystemColors.GrayText)))
                    {
                        Utility.DrawRoundedRectangle(g, pGray128, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4);
                    }
                }
                else if ((state & ItemState.Selected) == ItemState.None)
                {
                    using (Pen pGray64 = new Pen(Color.FromArgb(64, SystemColors.GrayText)))
                    {
                        Utility.DrawRoundedRectangle(g, pGray64, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4);
                    }
                }

                if (mImageListView.Focused && ((state & ItemState.Hovered) != ItemState.None))
                {
                    using (Pen pHighlight64 = new Pen(Color.FromArgb(64, SystemColors.Highlight)))
                    {
                        Utility.DrawRoundedRectangle(g, pHighlight64, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4);
                    }
                }

                // Focus rectangle
                if (mImageListView.Focused && ((state & ItemState.Focused) != ItemState.None))
                {
                    ControlPaint.DrawFocusRectangle(g, bounds);
                }
            }
            else
                base.DrawItem(g, item, state, bounds);
        }
    }

    /// <summary>
    /// Mimics Windows XP appearance.
    /// </summary>
    public class XPRenderer : ImageListView.ImageListViewRenderer
    {
        /// <summary>
        /// Returns item size for the given view mode.
        /// </summary>
        /// <param name="view">The view mode for which the item measurement should be made.</param>
        public override Size MeasureItem(View view)
        {
            Size itemSize = new Size();

            // Reference text height
            int textHeight = mImageListView.Font.Height;

            if (view == View.Thumbnails)
            {
                // Calculate item size
                Size itemPadding = new Size(4, 4);
                itemSize = mImageListView.ThumbnailSize + itemPadding + itemPadding;
                itemSize.Height += textHeight + System.Math.Max(4, textHeight / 3) + itemPadding.Height; // textHeight / 3 = vertical space between thumbnail and text
                return itemSize;
            }
            else
                return base.MeasureItem(view);
        }
        /// <summary>
        /// Draws the specified item on the given graphics.
        /// </summary>
        /// <param name="g">The System.Drawing.Graphics to draw on.</param>
        /// <param name="item">The ImageListViewItem to draw.</param>
        /// <param name="state">The current view state of item.</param>
        /// <param name="bounds">The bounding rectangle of item in client coordinates.</param>
        public override void DrawItem(System.Drawing.Graphics g, ImageListViewItem item, ItemState state, System.Drawing.Rectangle bounds)
        {
            // Paint background
            using (Brush bItemBack = new SolidBrush(item.BackColor))
            {
                g.FillRectangle(bItemBack, bounds);
            }

            if (mImageListView.View == View.Thumbnails)
            {
                Size itemPadding = new Size(4, 4);

                // Draw the image
                Image img = item.ThumbnailImage;
                if (img != null)
                {
                    int x = bounds.Left + itemPadding.Width + (mImageListView.ThumbnailSize.Width - img.Width) / 2;
                    int y = bounds.Top + itemPadding.Height + (mImageListView.ThumbnailSize.Height - img.Height) / 2;
                    Rectangle imageBounds = new Rectangle(bounds.Location + itemPadding, mImageListView.ThumbnailSize);
                    g.DrawImageUnscaled(img, x, y);
                    // Draw image border
                    if (img.Width > 32)
                    {
                        if (mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                        {
                            using (Pen pen = new Pen(SystemColors.Highlight, 3))
                            {
                                g.DrawRectangle(pen, imageBounds);
                            }
                        }
                        else if (!mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                        {
                            using (Pen pen = new Pen(SystemColors.GrayText, 3))
                            {
                                g.DrawRectangle(pen, imageBounds);
                            }
                        }
                        else
                        {
                            using (Pen pGray128 = new Pen(Color.FromArgb(128, SystemColors.GrayText)))
                            {
                                g.DrawRectangle(pGray128, imageBounds);
                            }
                        }
                    }
                }

                // Draw item text
                SizeF szt = TextRenderer.MeasureText(item.Text, mImageListView.Font);
                RectangleF rt;
                StringFormat sf = new StringFormat();
                rt = new RectangleF(bounds.Left + itemPadding.Width, bounds.Top + 3 * itemPadding.Height + mImageListView.ThumbnailSize.Height, mImageListView.ThumbnailSize.Width, szt.Height);
                sf.Alignment = StringAlignment.Center;
                sf.FormatFlags = StringFormatFlags.NoWrap;
                sf.LineAlignment = StringAlignment.Center;
                sf.Trimming = StringTrimming.EllipsisCharacter;
                rt.Inflate(0, 2);
                if (mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    g.FillRectangle(SystemBrushes.Highlight, rt);
                }
                else if (!mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    g.FillRectangle(SystemBrushes.GrayText, rt);
                }
                if (((state & ItemState.Selected) != ItemState.None))
                {
                    g.DrawString(item.Text, mImageListView.Font, SystemBrushes.HighlightText, rt, sf);
                }
                else
                {
                    using (Brush bItemFore = new SolidBrush(item.ForeColor))
                    {
                        g.DrawString(item.Text, mImageListView.Font, bItemFore, rt, sf);
                    }
                }

                if (mImageListView.Focused && ((state & ItemState.Focused) != ItemState.None))
                {
                    Rectangle fRect = Rectangle.Round(rt);
                    fRect.Inflate(1, 1);
                    ControlPaint.DrawFocusRectangle(g, fRect);
                }
            }
            else
            {
                if (mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    g.FillRectangle(SystemBrushes.Highlight, bounds);
                }
                else if (!mImageListView.Focused && ((state & ItemState.Selected) != ItemState.None))
                {
                    g.FillRectangle(SystemBrushes.GrayText, bounds);
                }

                Size offset = new Size(2, (bounds.Height - mImageListView.Font.Height) / 2);
                StringFormat sf = new StringFormat();
                sf.FormatFlags = StringFormatFlags.NoWrap;
                sf.Alignment = StringAlignment.Near;
                sf.LineAlignment = StringAlignment.Center;
                sf.Trimming = StringTrimming.EllipsisCharacter;
                // Sub text
                List<Manina.Windows.Forms.ImageListView.ImageListViewColumnHeader> uicolumns = mImageListView.Columns.GetUIColumns();
                RectangleF rt = new RectangleF(bounds.Left + offset.Width, bounds.Top + offset.Height, uicolumns[0].Width - 2 * offset.Width, bounds.Height - 2 * offset.Height);
                foreach (Manina.Windows.Forms.ImageListView.ImageListViewColumnHeader column in uicolumns)
                {
                    rt.Width = column.Width - 2 * offset.Width;
                    using (Brush bItemFore = new SolidBrush(item.ForeColor))
                    {
                        if ((state & ItemState.Selected) == ItemState.None)
                            g.DrawString(item.GetSubItemText(column.Type), mImageListView.Font, bItemFore, rt, sf);
                        else
                            g.DrawString(item.GetSubItemText(column.Type), mImageListView.Font, SystemBrushes.HighlightText, rt, sf);
                    }
                    rt.X += column.Width;
                }

                if (mImageListView.Focused && ((state & ItemState.Focused) != ItemState.None))
                    ControlPaint.DrawFocusRectangle(g, bounds);
            }
        }
    }
}

{'fraction_non_alphanumeric': 0.09708035962554454, 'fraction_numerical': 0.010899990731300399, 'mean_word_length': 1.2842020578396918, 'pattern_counts': {'":': 0, '<': 119, '<?xml version=': 0, '>': 129, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '65511', 'n_tokens_mistral': 14581, 'n_tokens_neox': 12826, 'n_words': 2858}