178 lines
7.2 KiB
C#
178 lines
7.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Windows.Forms;
|
|
using static System.Windows.Forms.ListViewItem;
|
|
using System.ComponentModel;
|
|
|
|
namespace NethackHelper {
|
|
public partial class ItemDisplay : UserControl {
|
|
public const string UNIDENTIFIED = "[randomized]";
|
|
public static readonly Color SELECTED_COLOR = Color.Black;
|
|
public static readonly Color UNSELECTED_COLOR = Color.Gray;
|
|
|
|
private static readonly Dictionary<ItemAttribute, Func<Item, string>> COLUMN_MAP = new() {
|
|
[ItemAttribute.Name] = item => item.Name,
|
|
[ItemAttribute.Cost] = item => item.Cost.ToString(),
|
|
[ItemAttribute.Ink] = item => item.Ink.ToString(),
|
|
[ItemAttribute.Appearance] = item => item.Appearance ?? UNIDENTIFIED,
|
|
};
|
|
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public Func<int, string> CostFormatter { get; set; } = cost => cost.ToString();
|
|
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
|
|
public List<ItemDisplayColumn> Columns { get; set; } = new();
|
|
|
|
private int[] GroupCosts { get; set; } = [];
|
|
|
|
private Dictionary<string, string?> AppearanceMap { get; set; } = new();
|
|
|
|
public ItemDisplay() {
|
|
InitializeComponent();
|
|
this.itemListView.ListViewItemSorter = Comparer<ListViewItem>.Create(CompareItems);
|
|
}
|
|
|
|
protected override void OnLoad(EventArgs e) {
|
|
base.OnLoad(e);
|
|
if (this.Columns != null) {
|
|
this.itemListView.Columns.Clear();
|
|
foreach (var column in this.Columns) {
|
|
this.itemListView.Columns.Add(column.Attribute.ToString(), column.Width);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void DisplayItemList(ItemList itemList, IdentificationRecord? idRecord) {
|
|
this.itemListView.Groups.Clear();
|
|
this.itemListView.Items.Clear();
|
|
this.AppearanceMap.Clear();
|
|
|
|
this.GroupCosts = itemList.Items.Select(item => item.Cost).Distinct().Order().ToArray();
|
|
var costDictionary = new Dictionary<int, ListViewGroup>();
|
|
|
|
foreach (var cost in this.GroupCosts) {
|
|
var group = new ListViewGroup(this.CostFormatter.Invoke(cost), HorizontalAlignment.Center);
|
|
this.itemListView.Groups.Add(group);
|
|
costDictionary.Add(cost, group);
|
|
}
|
|
|
|
foreach (var item in itemList.Items) {
|
|
bool identified = false;
|
|
ItemRecord record = default;
|
|
if (idRecord != null) {
|
|
if (idRecord.TryGetValue(item.Name, out var identity)) {
|
|
record = identity;
|
|
identified = true;
|
|
}
|
|
} else if (item.Appearance != null) {
|
|
record = new ItemRecord() {
|
|
Name = item.Name,
|
|
Appearance = item.Appearance,
|
|
};
|
|
identified = true;
|
|
}
|
|
|
|
AppearanceMap[item.Name] = record.Appearance;
|
|
|
|
var columns = this.Columns.Select(col => COLUMN_MAP[col.Attribute].Invoke(item)).ToArray();
|
|
|
|
var listViewItem = new ListViewItem(columns, costDictionary[item.Cost]);
|
|
listViewItem.UseItemStyleForSubItems = false;
|
|
var baseFont = new Font(this.itemListView.Font, FontStyle.Regular);
|
|
var baseColor = UNSELECTED_COLOR;
|
|
if (!identified) {
|
|
baseFont = new Font(baseFont, FontStyle.Bold);
|
|
baseColor = SELECTED_COLOR;
|
|
}
|
|
listViewItem.Checked = identified;
|
|
listViewItem.Font = baseFont;
|
|
listViewItem.ForeColor = baseColor;
|
|
foreach (ListViewSubItem subItem in listViewItem.SubItems) {
|
|
subItem.Font = baseFont;
|
|
subItem.ForeColor = baseColor;
|
|
}
|
|
if (record.Appearance == null) {
|
|
var fontStyle = FontStyle.Italic;
|
|
if (!identified) {
|
|
fontStyle |= FontStyle.Bold;
|
|
}
|
|
|
|
for (var i = 0; i < this.Columns.Count; i++) {
|
|
if (this.Columns[i].Attribute == ItemAttribute.Appearance) {
|
|
listViewItem.SubItems[i].Font = new Font(baseFont, fontStyle);
|
|
}
|
|
}
|
|
}
|
|
this.itemListView.Items.Add(listViewItem);
|
|
}
|
|
}
|
|
|
|
public IdentificationRecord Export() {
|
|
List<ItemRecord> records = [];
|
|
foreach (ListViewItem item in this.itemListView.Items) {
|
|
if (item.Checked) {
|
|
string? appearance = this.AppearanceMap[item.Text];
|
|
records.Add(new() {
|
|
Name = item.Text,
|
|
Appearance = appearance,
|
|
});
|
|
}
|
|
}
|
|
return new(records);
|
|
}
|
|
|
|
public void UpdateCostHeaders() {
|
|
for (int i = 0; i < this.GroupCosts.Length; i++) {
|
|
this.itemListView.Groups[i].Header = this.CostFormatter.Invoke(this.GroupCosts[i]);
|
|
}
|
|
}
|
|
|
|
private void itemListView_MouseDoubleClick(object sender, MouseEventArgs e) {
|
|
if (this.itemListView.SelectedItems.Count == 1) {
|
|
var item = this.itemListView.SelectedItems[0];
|
|
item.Checked = !item.Checked;
|
|
var baseFont = item.Font;
|
|
foreach (ListViewSubItem subItem in item.SubItems) {
|
|
if (item.Checked) {
|
|
if (subItem.Font.Italic) {
|
|
subItem.Font = new Font(baseFont, FontStyle.Italic);
|
|
} else {
|
|
subItem.Font = new Font(baseFont, FontStyle.Regular);
|
|
}
|
|
subItem.ForeColor = UNSELECTED_COLOR;
|
|
} else {
|
|
if (subItem.Font.Italic) {
|
|
subItem.Font = new Font(baseFont, FontStyle.Bold | FontStyle.Italic);
|
|
} else {
|
|
subItem.Font = new Font(baseFont, FontStyle.Bold | FontStyle.Regular);
|
|
}
|
|
subItem.ForeColor = SELECTED_COLOR;
|
|
}
|
|
}
|
|
this.itemListView.Sort();
|
|
}
|
|
}
|
|
|
|
private static int CompareItems(ListViewItem a, ListViewItem b) {
|
|
if (a.Checked != b.Checked) {
|
|
return a.Checked.CompareTo(b.Checked);
|
|
} else {
|
|
return a.Text.CompareTo(b.Text);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Serializable]
|
|
public class ItemDisplayColumn {
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
|
public ItemAttribute Attribute { get; set; }
|
|
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
|
public int Width { get; set; }
|
|
}
|
|
}
|