diff --git a/ProjectTank/FormTankCollection.Designer.cs b/ProjectTank/FormTankCollection.Designer.cs index 00062aa..e880da6 100644 --- a/ProjectTank/FormTankCollection.Designer.cs +++ b/ProjectTank/FormTankCollection.Designer.cs @@ -39,6 +39,8 @@ listBoxStorages = new ListBox(); deleteObjectButton = new Button(); groupBox1 = new GroupBox(); + sortByColorButton = new Button(); + sortByTypeButton = new Button(); menuStrip = new MenuStrip(); fileToolStripMenuItem = new ToolStripMenuItem(); loadToolStripMenuItem = new ToolStripMenuItem(); @@ -60,7 +62,7 @@ // // refreshObjectsButton // - refreshObjectsButton.Location = new Point(6, 410); + refreshObjectsButton.Location = new Point(6, 440); refreshObjectsButton.Name = "refreshObjectsButton"; refreshObjectsButton.Size = new Size(139, 29); refreshObjectsButton.TabIndex = 4; @@ -70,7 +72,7 @@ // // deleteTankButton // - deleteTankButton.Location = new Point(6, 377); + deleteTankButton.Location = new Point(6, 404); deleteTankButton.Name = "deleteTankButton"; deleteTankButton.Size = new Size(139, 29); deleteTankButton.TabIndex = 5; @@ -80,7 +82,7 @@ // // addTankButton // - addTankButton.Location = new Point(6, 307); + addTankButton.Location = new Point(6, 338); addTankButton.Name = "addTankButton"; addTankButton.Size = new Size(139, 29); addTankButton.TabIndex = 6; @@ -90,7 +92,7 @@ // // maskedTextBoxNumber // - maskedTextBoxNumber.Location = new Point(6, 344); + maskedTextBoxNumber.Location = new Point(6, 373); maskedTextBoxNumber.Name = "maskedTextBoxNumber"; maskedTextBoxNumber.Size = new Size(139, 27); maskedTextBoxNumber.TabIndex = 7; @@ -106,14 +108,14 @@ // // textBoxStorageName // - textBoxStorageName.Location = new Point(6, 67); + textBoxStorageName.Location = new Point(6, 59); textBoxStorageName.Name = "textBoxStorageName"; textBoxStorageName.Size = new Size(139, 27); textBoxStorageName.TabIndex = 9; // // addObjectButton // - addObjectButton.Location = new Point(6, 100); + addObjectButton.Location = new Point(6, 92); addObjectButton.Name = "addObjectButton"; addObjectButton.Size = new Size(139, 29); addObjectButton.TabIndex = 10; @@ -125,7 +127,7 @@ // listBoxStorages.FormattingEnabled = true; listBoxStorages.ItemHeight = 20; - listBoxStorages.Location = new Point(6, 135); + listBoxStorages.Location = new Point(6, 131); listBoxStorages.Name = "listBoxStorages"; listBoxStorages.Size = new Size(139, 84); listBoxStorages.TabIndex = 11; @@ -133,7 +135,7 @@ // // deleteObjectButton // - deleteObjectButton.Location = new Point(6, 234); + deleteObjectButton.Location = new Point(6, 222); deleteObjectButton.Name = "deleteObjectButton"; deleteObjectButton.Size = new Size(139, 29); deleteObjectButton.TabIndex = 12; @@ -143,6 +145,8 @@ // // groupBox1 // + groupBox1.Controls.Add(sortByColorButton); + groupBox1.Controls.Add(sortByTypeButton); groupBox1.Controls.Add(label2); groupBox1.Controls.Add(refreshObjectsButton); groupBox1.Controls.Add(deleteTankButton); @@ -159,6 +163,26 @@ groupBox1.TabStop = false; groupBox1.Text = "Инструменты"; // + // sortByColorButton + // + sortByColorButton.Location = new Point(6, 297); + sortByColorButton.Name = "sortByColorButton"; + sortByColorButton.Size = new Size(139, 29); + sortByColorButton.TabIndex = 14; + sortByColorButton.Text = "Сорт. по цвету"; + sortByColorButton.UseVisualStyleBackColor = true; + sortByColorButton.Click += ButtonSortByColor_Click; + // + // sortByTypeButton + // + sortByTypeButton.Location = new Point(6, 262); + sortByTypeButton.Name = "sortByTypeButton"; + sortByTypeButton.Size = new Size(139, 29); + sortByTypeButton.TabIndex = 13; + sortByTypeButton.Text = "Сорт. по типу"; + sortByTypeButton.UseVisualStyleBackColor = true; + sortByTypeButton.Click += ButtonSortByType_Click; + // // menuStrip // menuStrip.ImageScalingSize = new Size(20, 20); @@ -238,5 +262,7 @@ private ToolStripMenuItem saveToolStripMenuItem; private OpenFileDialog openFileDialog; private SaveFileDialog saveFileDialog; + private Button sortByColorButton; + private Button sortByTypeButton; } } \ No newline at end of file diff --git a/ProjectTank/FormTankCollection.cs b/ProjectTank/FormTankCollection.cs index da3860b..7c1507f 100644 --- a/ProjectTank/FormTankCollection.cs +++ b/ProjectTank/FormTankCollection.cs @@ -29,7 +29,7 @@ namespace ProjectTank for (int i = 0; i < _storage.Keys.Count; i++) { - listBoxStorages.Items.Add(_storage.Keys[i]); + listBoxStorages.Items.Add(_storage.Keys[i].Name); } if (listBoxStorages.Items.Count > 0 && (index == -1 || index >= listBoxStorages.Items.Count)) @@ -56,6 +56,35 @@ namespace ProjectTank Log.Information($"Добавлен набор: {textBoxStorageName.Text}"); } + /// + /// Сортировка по типу + /// + /// + /// + private void ButtonSortByType_Click(object sender, EventArgs e) => CompareTanks(new TankCompareByType()); + /// + /// Сортировка по цвету + /// + /// + /// + private void ButtonSortByColor_Click(object sender, EventArgs e) => CompareTanks(new TankCompareByColor()); + /// + /// Сортировка по сравнителю + /// + /// + private void CompareTanks(IComparer comparer) + { + if (listBoxStorages.SelectedIndex == -1) return; + + var obj = _storage[listBoxStorages.SelectedItem.ToString() ?? string.Empty]; + + if (obj == null) return; + + obj.Sort(comparer); + pictureBoxCollection.Image = obj.ShowTanks(); + } + + private void ListBoxObjects_SelectedIndexChanged(object sender, EventArgs e) { pictureBoxCollection.Image = _storage[listBoxStorages.SelectedItem?.ToString() ?? string.Empty]?.ShowTanks(); @@ -107,6 +136,11 @@ namespace ProjectTank Log.Warning($"Коллекция {listBoxStorages.SelectedItem.ToString() ?? string.Empty} переполнена"); MessageBox.Show(ex.Message); } + catch (ArgumentException ex) + { + Log.Warning($"Добавляемый объект уже существует в коллекции {listBoxStorages.SelectedItem.ToString() ?? string.Empty}"); + MessageBox.Show("Добавляемый объект уже существует в коллекции"); + } }); form.AddEvent(tankDelegate); diff --git a/ProjectTank/Generics/DrawningTankBaseEqutables.cs b/ProjectTank/Generics/DrawningTankBaseEqutables.cs new file mode 100644 index 0000000..0c2db63 --- /dev/null +++ b/ProjectTank/Generics/DrawningTankBaseEqutables.cs @@ -0,0 +1,53 @@ +using ProjectTank.DrawningObjects; +using ProjectTank.Entities; +using System.Diagnostics.CodeAnalysis; + +namespace ProjectTank.Generics +{ + internal class DrawningTankBaseEqutables : IEqualityComparer + { + public bool Equals(DrawningTankBase? x, DrawningTankBase? y) + { + if (x == null || x.EntityTankBase == null) + { + throw new ArgumentNullException(nameof(x)); + } + if (y == null || y.EntityTankBase == null) + { + throw new ArgumentNullException(nameof(y)); + } + if (x.GetType().Name != y.GetType().Name) + { + return false; + } + if (x.EntityTankBase.Speed != y.EntityTankBase.Speed) + { + return false; + } + if (x.EntityTankBase.Weight != y.EntityTankBase.Weight) + { + return false; + } + if (x.EntityTankBase.BodyColor != y.EntityTankBase.BodyColor) + { + return false; + } + if (x is DrawningTank && y is DrawningTank) + { + EntityTank EntityX = (EntityTank)x.EntityTankBase; + EntityTank EntityY = (EntityTank)y.EntityTankBase; + if (EntityX.AntiAirforceGun != EntityY.AntiAirforceGun) + return false; + if (EntityX.TankTower != EntityY.TankTower) + return false; + if (EntityX.AdditionalColor != EntityY.AdditionalColor) + return false; + } + return true; + } + public int GetHashCode([DisallowNull] DrawningTankBase obj) + { + return obj.GetHashCode(); + } + } +} \ No newline at end of file diff --git a/ProjectTank/Generics/SetGeneric.cs b/ProjectTank/Generics/SetGeneric.cs index f402168..d4230b6 100644 --- a/ProjectTank/Generics/SetGeneric.cs +++ b/ProjectTank/Generics/SetGeneric.cs @@ -27,17 +27,18 @@ namespace ProjectTank.Generics _maxCount = count; _places = new List(count); } + public void SortSet(IComparer comparer) => _places.Sort(comparer); /// /// Добавление объекта в набор /// /// Добавляемый танк /// - public bool Insert(T tank) + public bool Insert(T tank, IEqualityComparer? equal = null) { if (_places.Count == _maxCount) throw new StorageOverflowException(_maxCount); - Insert(tank, 0); + Insert(tank, 0, equal); return true; } /// @@ -46,12 +47,17 @@ namespace ProjectTank.Generics /// Добавляемый танк /// Позиция /// - public bool Insert(T tank, int position) + public bool Insert(T tank, int position, IEqualityComparer? equal = null) { if (_places.Count == _maxCount) throw new StorageOverflowException(_maxCount); if (!(position >= 0 && position <= Count)) return false; + if (equal != null) + { + if (_places.Contains(tank, equal)) + throw new ArgumentException(nameof(tank)); + } _places.Insert(position, tank); return true; } diff --git a/ProjectTank/Generics/TankCompareByColor.cs b/ProjectTank/Generics/TankCompareByColor.cs new file mode 100644 index 0000000..46ed861 --- /dev/null +++ b/ProjectTank/Generics/TankCompareByColor.cs @@ -0,0 +1,42 @@ +using ProjectTank.DrawningObjects; +using ProjectTank.Entities; + +namespace ProjectTank.Generics +{ + internal class TankCompareByColor : IComparer + { + public int Compare(DrawningTankBase? x, DrawningTankBase? y) + { + if (x == null || x.EntityTankBase == null) + throw new ArgumentNullException(nameof(x)); + + if (y == null || y.EntityTankBase == null) + throw new ArgumentNullException(nameof(y)); + + if (x.EntityTankBase.BodyColor.Name != y.EntityTankBase.BodyColor.Name) + { + return x.EntityTankBase.BodyColor.Name.CompareTo(y.EntityTankBase.BodyColor.Name); + } + if (x.GetType().Name != y.GetType().Name) + { + if (x is DrawningTankBase) return -1; + else return 1; + } + if (x.GetType().Name == y.GetType().Name && x is DrawningTank) + { + EntityTank EntityX = (EntityTank)x.EntityTankBase; + EntityTank EntityY = (EntityTank)y.EntityTankBase; + if (EntityX.AdditionalColor.Name != EntityY.AdditionalColor.Name) + { + return EntityX.AdditionalColor.Name.CompareTo(EntityY.AdditionalColor.Name); + } + } + var speedCompare = x.EntityTankBase.Speed.CompareTo(y.EntityTankBase.Speed); + + if (speedCompare != 0) + return speedCompare; + + return x.EntityTankBase.Weight.CompareTo(y.EntityTankBase.Weight); + } + } +} \ No newline at end of file diff --git a/ProjectTank/Generics/TankCompareByType.cs b/ProjectTank/Generics/TankCompareByType.cs new file mode 100644 index 0000000..6bd6a26 --- /dev/null +++ b/ProjectTank/Generics/TankCompareByType.cs @@ -0,0 +1,29 @@ +using ProjectTank.DrawningObjects; + +namespace ProjectTank.Generics +{ + internal class TankCompareByType : IComparer + { + public int Compare(DrawningTankBase? x, DrawningTankBase? y) + { + if (x == null || x.EntityTankBase == null) + { + throw new ArgumentNullException(nameof(x)); + } + if (y == null || y.EntityTankBase == null) + { + throw new ArgumentNullException(nameof(y)); + } + if (x.GetType().Name != y.GetType().Name) + { + return x.GetType().Name.CompareTo(y.GetType().Name); + } + var speedCompare = x.EntityTankBase.Speed.CompareTo(y.EntityTankBase.Speed); + if (speedCompare != 0) + { + return speedCompare; + } + return x.EntityTankBase.Weight.CompareTo(y.EntityTankBase.Weight); + } + } +} diff --git a/ProjectTank/Generics/TanksCollectionInfo.cs b/ProjectTank/Generics/TanksCollectionInfo.cs new file mode 100644 index 0000000..53797e5 --- /dev/null +++ b/ProjectTank/Generics/TanksCollectionInfo.cs @@ -0,0 +1,22 @@ +namespace ProjectTank.Generics +{ + internal class TanksCollectionInfo : IEquatable + { + public string Name { get; private set; } + public string Description { get; private set; } + public TanksCollectionInfo(string name, string description) + { + Name = name; + Description = description; + } + public bool Equals(TanksCollectionInfo? other) + { + if (other == null) return false; + return Name == other.Name; + } + public override int GetHashCode() + { + return this.Name.GetHashCode(); + } + } +} diff --git a/ProjectTank/Generics/TanksGenericCollection.cs b/ProjectTank/Generics/TanksGenericCollection.cs index 7ea59ca..fc34372 100644 --- a/ProjectTank/Generics/TanksGenericCollection.cs +++ b/ProjectTank/Generics/TanksGenericCollection.cs @@ -48,6 +48,11 @@ namespace ProjectTank.Generics _collection = new SetGeneric(width * height); } /// + /// Сортировка + /// + /// + public void Sort(IComparer comparer) => _collection.SortSet(comparer); + /// /// Перегрузка оператора сложения /// /// @@ -58,7 +63,7 @@ namespace ProjectTank.Generics if (obj == null) return false; - return collect?._collection.Insert(obj) ?? false; + return collect?._collection.Insert(obj, new DrawningTankBaseEqutables()) ?? false; } /// /// Перегрузка оператора вычитания diff --git a/ProjectTank/Generics/TanksGenericStorage.cs b/ProjectTank/Generics/TanksGenericStorage.cs index d14bb07..068b97e 100644 --- a/ProjectTank/Generics/TanksGenericStorage.cs +++ b/ProjectTank/Generics/TanksGenericStorage.cs @@ -13,12 +13,12 @@ namespace ProjectTank.Generics /// /// Словарь (хранилище) /// - readonly Dictionary> _tankStorages; + readonly Dictionary> _tankStorages; /// /// Возвращение списка названий наборов /// - public List Keys => _tankStorages.Keys.ToList(); + public List Keys => _tankStorages.Keys.ToList(); /// /// Ширина окна отрисовки /// @@ -46,7 +46,7 @@ namespace ProjectTank.Generics /// public TanksGenericStorage(int pictureWidth, int pictureHeight) { - _tankStorages = new Dictionary>(); _pictureWidth = pictureWidth; _pictureHeight = pictureHeight; @@ -55,10 +55,10 @@ namespace ProjectTank.Generics /// Добавление набора /// /// Название набора - public void AddSet(string name) { - _tankStorages.Add(name, new TanksGenericCollection (_pictureWidth, _pictureHeight)); + _tankStorages.Add(new TanksCollectionInfo(name, string.Empty), + new TanksGenericCollection(_pictureWidth, _pictureHeight)); } /// /// Удаление набора @@ -66,11 +66,10 @@ namespace ProjectTank.Generics /// Название набора public void DelSet(string name) { - if (!_tankStorages.ContainsKey(name)) + if (!_tankStorages.ContainsKey(new TanksCollectionInfo(name, string.Empty))) return; - _tankStorages.Remove(name); + _tankStorages.Remove(new TanksCollectionInfo(name, string.Empty)); } - /// /// Доступ к набору /// @@ -80,8 +79,9 @@ namespace ProjectTank.Generics { get { - if (_tankStorages.ContainsKey(ind)) - return _tankStorages[ind]; + TanksCollectionInfo indObj = new TanksCollectionInfo(ind, string.Empty); + if (_tankStorages.ContainsKey(indObj)) + return _tankStorages[indObj]; return null; } } @@ -98,19 +98,19 @@ namespace ProjectTank.Generics File.Delete(filename); } StringBuilder data = new(); - foreach (KeyValuePair> record in _tankStorages) + foreach (KeyValuePair> record in _tankStorages) { StringBuilder records = new(); foreach (DrawningTankBase? elem in record.Value.GetTanks) { records.Append($"{elem?.GetDataForSave(_separatorForObject)}{_separatorRecords}"); } - data.AppendLine($"{record.Key}{_separatorForKeyValue}{records}"); + data.AppendLine($"{record.Key.Name}{_separatorForKeyValue}{records}"); } if (data.Length == 0) { - throw new Exception("Невалиданя операция, нет данных для сохранения"); + throw new Exception("Невалидная операция, нет данных для сохранения"); } string toWrite = $"TanksStorage{Environment.NewLine}{data}"; @@ -178,7 +178,7 @@ namespace ProjectTank.Generics } } } - _tankStorages.Add(record[0], collection); + _tankStorages.Add(new TanksCollectionInfo(record[0], string.Empty), collection); str = sr.ReadLine(); } while (str != null);