public VirtualSearchResultsView(IMediaIndex index) { this.index = index ?? throw new ArgumentNullException(nameof(index)); this.AllowColumnReorder = true; this.FullRowSelect = true; this.View = View.Details; this.columnDefinitions = new ColumnDefinitionList { { Column.Path, GetBestPath, value => value == null ? string.Empty : Path.GetDirectoryName(value), (a, b) => PathComparer.Instance.Compare(GetBestPath(a), GetBestPath(b)) }, { Column.Name, r => { var path = GetBestPath(r); return(path == null ? string.Empty : Path.GetFileNameWithoutExtension(path)); }, value => value, (a, b) => { var aPath = GetBestPath(a); var bPath = GetBestPath(b); return(StringComparer.CurrentCultureIgnoreCase.Compare( aPath == null ? null : Path.GetFileNameWithoutExtension(aPath), bPath == null ? null : Path.GetFileNameWithoutExtension(bPath))); }, r => GetImageKey(r.FileType) }, { Column.People, r => r.People, value => string.Join("; ", value.Select(p => p.Name)), (a, b) => a.People.Count.CompareTo(b.People.Count) }, { Column.Tags, r => r.Tags, value => string.Join("; ", value), (a, b) => this.TagComparer.Compare(a.Tags, b.Tags), (g, bounds, r) => { var tagComparer = this.TagComparer; var baseSize = g.MeasureString("#", this.Font); var padding = (int)Math.Floor((bounds.Height - baseSize.Height) / 2); var xOffset = 0f; if (r.Tags.Contains("favorite")) { var size = bounds.Height - padding * 2; g.DrawImage(Resources.love_it_filled, new RectangleF(bounds.Left + xOffset, bounds.Top + padding, size, size)); xOffset += size + padding; } foreach (var tag in r.Tags.Where(t => t != "favorite").OrderBy(t => t, tagComparer)) { var backgroundColor = tagComparer.GetTagColor(tag) ?? SystemColors.Info; var textColor = ColorService.ContrastColor(backgroundColor); var size = g.MeasureString(tag, this.Font); using (var backgroundBrush = new SolidBrush(backgroundColor)) using (var textBrush = new SolidBrush(textColor)) { var topLeft = new PointF(bounds.Left + xOffset, bounds.Top + padding); g.FillRectangle(backgroundBrush, new RectangleF(topLeft, size)); g.DrawString(tag, this.Font, textBrush, topLeft); } // TODO: Break on out-of-bounds. xOffset += size.Width + padding; } } }, { Column.FileSize, HorizontalAlignment.Right, r => r.FileSize, value => ByteSize.FromBytes(value).ToString(), (a, b) => a.FileSize.CompareTo(b.FileSize) }, { Column.Rating, HorizontalAlignment.Right, r => r.Rating, value => value != null ? $"{Math.Round(value.Value)}{(value.Count < 15 ? "?" : string.Empty)}" : string.Empty, (a, b) => Rating.Compare(a.Rating, b.Rating) }, }.ToImmutableDictionary(c => c.Column); this.VirtualListDataSource = new DataSource(this, this.columnDefinitions); this.index.HashTagAdded += this.Index_HashTagAdded; this.index.HashTagRemoved += this.Index_HashTagRemoved; this.index.HashPersonAdded += this.Index_HashPersonAdded; this.index.HashPersonRemoved += this.Index_HashPersonRemoved; this.index.RatingUpdated += this.Index_RatingUpdated; this.index.TagRulesUpdated += this.Index_TagRulesUpdated; foreach (var column in this.columnDefinitions.Values.OrderBy(c => c.Index)) { var columnHeader = this.columns[column.Column] = new OLVColumn(); columnHeader.Name = column.Column.ToString(); columnHeader.Text = column.Name; columnHeader.TextAlign = column.HorizontalAlignment; columnHeader.AspectGetter = row => row == null ? null : column.GetValue((SearchResult)row); columnHeader.AspectToStringConverter = value => value == null ? null : column.FormatValue(value); if (column.DrawSubItem != null) { columnHeader.Renderer = new ColumnRenderer(column.DrawSubItem) { ListView = this, }; } if (column.GetImage != null) { columnHeader.ImageGetter = row => row == null ? null : column.GetImage((SearchResult)row); } this.Columns.Add(columnHeader); } this.ColumnWidthChanged += this.Internal_ColumnWidthChanged; this.BeforeSorting += this.Internal_BeforeSorting; }
public static Color?GetTagColor(this TagRuleEngine tagEngine, string tag) => ColorService.ParseColor(tagEngine.GetPropertyValue(tag, "color"));