diff --git a/Trolleybus/Trolleybus/BusCompareByColor.cs b/Trolleybus/Trolleybus/BusCompareByColor.cs new file mode 100644 index 0000000..e62add9 --- /dev/null +++ b/Trolleybus/Trolleybus/BusCompareByColor.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Drawing.Drawing2D; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Trolleybus.DrawingObjects; +using Trolleybus.Entities; + +namespace Trolleybus.Generics +{ + internal class BusCompareByColor : IComparer + { + public int Compare(DrawingBus? x, DrawingBus? y) + { + if (x == null || x.EntityBus == null) + { + throw new ArgumentNullException(nameof(x)); + } + + if (y == null || y.EntityBus == null) + { + throw new ArgumentNullException(nameof(y)); + } + + var bodyColorCompare = x.EntityBus.BodyColor.Name.CompareTo(y.EntityBus.BodyColor.Name); + + // Если оба объекта простые или разных типов (т.е. хотя бы 1 непродвинутый), то сравнение по основному цвету + if (!(x.GetType().Name == "DrawingTrolleybus" && y.GetType().Name == "DrawingTrolleybus")) + { + return bodyColorCompare; + } + + // Если оба объекта продвинутые + else + { + EntityTrolleybus entityX = (EntityTrolleybus)x.EntityBus; + EntityTrolleybus entityY = (EntityTrolleybus)y.EntityBus; + + // Если основные цвета одинаковые, сравнение по доп. цвету + if (bodyColorCompare == 0) + { + return entityX.AdditionalColor.Name.CompareTo(entityY.AdditionalColor.Name); + } + // иначе сравнение по основному цвету + return bodyColorCompare; + } + } + } +} diff --git a/Trolleybus/Trolleybus/BusCompareByType.cs b/Trolleybus/Trolleybus/BusCompareByType.cs new file mode 100644 index 0000000..4549ef6 --- /dev/null +++ b/Trolleybus/Trolleybus/BusCompareByType.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Trolleybus.DrawingObjects; + +namespace Trolleybus.Generics +{ + internal class BusCompareByType : IComparer + { + public int Compare(DrawingBus? x, DrawingBus? y) + { + if (x == null || x.EntityBus == null) + { + throw new ArgumentNullException(nameof(x)); + } + if (y == null || y.EntityBus == null) + { + throw new ArgumentNullException(nameof(y)); + } + // Сравнение по типу (простой / продвинутый) + if (x.GetType().Name != y.GetType().Name) + { + return x.GetType().Name.CompareTo(y.GetType().Name); + } + // Сравнение по скорости + var speedCompare = x.EntityBus.Speed.CompareTo(y.EntityBus.Speed); + if (speedCompare != 0) + { + return speedCompare; + } + // Сравнение по весу + return x.EntityBus.Weight.CompareTo(y.EntityBus.Weight); + } + + } +} diff --git a/Trolleybus/Trolleybus/BusesCollectionInfo.cs b/Trolleybus/Trolleybus/BusesCollectionInfo.cs new file mode 100644 index 0000000..297002e --- /dev/null +++ b/Trolleybus/Trolleybus/BusesCollectionInfo.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Trolleybus.Generics +{ + internal class BusesCollectionInfo : IEquatable + { + public string Name { get; private set; } + public string Description { get; private set; } + public BusesCollectionInfo(string name, string description) + { + Name = name; + Description = description; + } + public bool Equals(BusesCollectionInfo? other) + { + return Name == other.Name; + } + public override int GetHashCode() + { + return this.Name.GetHashCode(); + } + } +} diff --git a/Trolleybus/Trolleybus/BusesGenericCollection.cs b/Trolleybus/Trolleybus/BusesGenericCollection.cs index 2df2f1b..e9cb553 100644 --- a/Trolleybus/Trolleybus/BusesGenericCollection.cs +++ b/Trolleybus/Trolleybus/BusesGenericCollection.cs @@ -50,6 +50,13 @@ namespace Trolleybus.Generics _pictureHeight = picHeight; _collection = new SetGeneric(width * height); //width*height - кол-во мест на PictureBox для автобусов; размер массива } + + /// + /// Сортировка + /// + /// + public void Sort(IComparer comparer) => _collection.SortSet(comparer); + /// /// Перегрузка оператора сложения /// @@ -63,7 +70,7 @@ namespace Trolleybus.Generics { return -1; } - return collect._collection.Insert(obj); + return collect._collection.Insert(obj, new DrawingBusEquality()); } /// /// Перегрузка оператора вычитания diff --git a/Trolleybus/Trolleybus/BusesGenericStorage.cs b/Trolleybus/Trolleybus/BusesGenericStorage.cs index f1c9649..502cd0e 100644 --- a/Trolleybus/Trolleybus/BusesGenericStorage.cs +++ b/Trolleybus/Trolleybus/BusesGenericStorage.cs @@ -15,12 +15,12 @@ namespace Trolleybus.Generics /// /// Словарь (хранилище) /// - readonly Dictionary> _busStorages; + readonly Dictionary> _busStorages; /// /// Возвращение списка названий наборов /// - public List Keys => _busStorages.Keys.ToList(); + public List Keys => _busStorages.Keys.ToList(); /// /// Ширина окна отрисовки @@ -52,7 +52,7 @@ namespace Trolleybus.Generics /// public BusesGenericStorage(int pictureWidth, int pictureHeight) { - _busStorages = new Dictionary>(); + _busStorages = new Dictionary>(); _pictureWidth = pictureWidth; _pictureHeight = pictureHeight; } @@ -63,13 +63,14 @@ namespace Trolleybus.Generics /// Название набора public void AddSet(string name) { + BusesCollectionInfo currentCollectionInfo = new BusesCollectionInfo(name, string.Empty); // проверка, существует ли набор с таким ключём - if (_busStorages.ContainsKey(name)) + if (_busStorages.ContainsKey(currentCollectionInfo)) { return; } var busCollection = new BusesGenericCollection(_pictureWidth, _pictureHeight); - _busStorages.Add(name, busCollection); + _busStorages.Add(currentCollectionInfo, busCollection); } /// @@ -78,9 +79,10 @@ namespace Trolleybus.Generics /// Название набора public void DelSet(string name) { - if (_busStorages.ContainsKey(name)) + BusesCollectionInfo currentCollectionInfo = new BusesCollectionInfo(name, string.Empty); + if (_busStorages.ContainsKey(currentCollectionInfo)) { - _busStorages.Remove(name); + _busStorages.Remove(currentCollectionInfo); } } /// @@ -92,11 +94,12 @@ namespace Trolleybus.Generics { get { - if (!_busStorages.ContainsKey(ind)) + BusesCollectionInfo currentCollectionInfo = new BusesCollectionInfo(ind, string.Empty); + if (!_busStorages.ContainsKey(currentCollectionInfo)) { return null; } - return _busStorages[ind]; + return _busStorages[currentCollectionInfo]; } } /// @@ -112,14 +115,14 @@ namespace Trolleybus.Generics } StringBuilder data = new(); - foreach (KeyValuePair> record in _busStorages) + foreach (KeyValuePair> record in _busStorages) { StringBuilder records = new(); foreach (DrawingBus? elem in record.Value.GetBuses) { records.Append($"{elem?.GetDataForSave(_separatorForObject)}{_separatorRecords}"); } - data.AppendLine($"{record.Key}{_separatorForKeyValue}{records}"); + data.AppendLine($"{record.Key.Name}{_separatorForKeyValue}{records}"); } if (data.Length == 0) { @@ -172,7 +175,7 @@ namespace Trolleybus.Generics } } } - _busStorages.Add(record[0], collection); + _busStorages.Add(new BusesCollectionInfo(record[0], string.Empty), collection); currentLine = sr.ReadLine(); } } diff --git a/Trolleybus/Trolleybus/DrawingBusEquality.cs b/Trolleybus/Trolleybus/DrawingBusEquality.cs new file mode 100644 index 0000000..2135971 --- /dev/null +++ b/Trolleybus/Trolleybus/DrawingBusEquality.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Trolleybus.DrawingObjects; +using Trolleybus.Entities; +using System.Diagnostics.CodeAnalysis; + +namespace Trolleybus.Generics +{ + internal class DrawingBusEquality : IEqualityComparer + { + public bool Equals(DrawingBus? x, DrawingBus? y) + { + if (x == null || x.EntityBus == null) + { + throw new ArgumentNullException(nameof(x)); + } + if (y == null || y.EntityBus == null) + { + throw new ArgumentNullException(nameof(y)); + } + if (x.GetType().Name != y.GetType().Name) + { + return false; + } + if (x.EntityBus.Speed != y.EntityBus.Speed) + { + return false; + } + if (x.EntityBus.Weight != y.EntityBus.Weight) + { + return false; + } + if (x.EntityBus.BodyColor != y.EntityBus.BodyColor) + { + return false; + } + + // Если оба сравниваемых объекта продвинутые + if (x is DrawingTrolleybus && y is DrawingTrolleybus) + { + // Cравнение дополнительных параметров + EntityTrolleybus entityX = (EntityTrolleybus)x.EntityBus; + EntityTrolleybus entityY = (EntityTrolleybus)y.EntityBus; + + // сравнение доп. цвета + if (entityX.AdditionalColor != entityY.AdditionalColor) + { + return false; + } + + // сравнение наличия "рогов" + if (entityX.Horns != entityY.Horns) + { + return false; + } + + // сравнение наличия отсека для батарей + if (entityX.Batteries != entityY.Batteries) + { + return false; + } + + } + return true; + } + public int GetHashCode([DisallowNull] DrawingBus obj) + { + return obj.GetHashCode(); + } + } +} diff --git a/Trolleybus/Trolleybus/FormBusesCollection.cs b/Trolleybus/Trolleybus/FormBusesCollection.cs index f3df2c3..3f1f2de 100644 --- a/Trolleybus/Trolleybus/FormBusesCollection.cs +++ b/Trolleybus/Trolleybus/FormBusesCollection.cs @@ -46,7 +46,7 @@ namespace Trolleybus listBoxSets.Items.Clear(); for (int i = 0; i < _storage.Keys.Count; i++) { - listBoxSets.Items.Add(_storage.Keys[i]); + listBoxSets.Items.Add(_storage.Keys[i].Name); } if (listBoxSets.Items.Count > 0 && (index == -1 || index >= listBoxSets.Items.Count)) { @@ -135,7 +135,7 @@ namespace Trolleybus String nameOfSet = listBoxSets.SelectedItem.ToString() ?? string.Empty; try { - if(obj + selectedBus != -1) + if (obj + selectedBus != -1) { MessageBox.Show("Объект добавлен"); _logger.LogInformation($"Объект добавлен в набор {nameOfSet}"); @@ -154,6 +154,12 @@ namespace Trolleybus MessageBox.Show("Не удалось добавить объект"); _logger.LogWarning($"Не удалось добавить объект в набор {nameOfSet} : {ex.Message}"); } + + catch (ArgumentException ex) + { + MessageBox.Show("Добавляемый объект уже есть в наборе"); + _logger.LogWarning($"Ошибка добавления в набор {listBoxSets.SelectedItem.ToString() ?? string.Empty} : {ex.Message}"); + } } /// /// Удаление объекта из набора @@ -267,10 +273,45 @@ namespace Trolleybus } } + /// + /// Сортировка по типу + /// + /// + /// + private void ButtonSortByType_Click(object sender, EventArgs e) => CompareBuses(new BusCompareByType()); + + /// + /// Сортировка по цвету + /// + /// + /// + private void ButtonSortByColor_Click(object sender, EventArgs e) => CompareBuses(new BusCompareByColor()); + + /// + /// Сортировка по сравнителю + /// + /// + private void CompareBuses(IComparer comparer) + { + if (listBoxSets.SelectedIndex == -1) + { + return; + } + var obj = _storage[listBoxSets.SelectedItem.ToString() ?? string.Empty]; + if (obj == null) + { + return; + } + obj.Sort(comparer); + pictureBoxCollection.Image = obj.ShowBuses(); + } + private void InitializeComponent() { pictureBoxCollection = new PictureBox(); panelTools = new Panel(); + buttonSortByColor = new Button(); + buttonSortByType = new Button(); panelSets = new Panel(); buttonDeleteSetOfObjects = new Button(); textBoxNameOfSet = new TextBox(); @@ -297,7 +338,7 @@ namespace Trolleybus pictureBoxCollection.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; pictureBoxCollection.Location = new Point(0, 36); pictureBoxCollection.Name = "pictureBoxCollection"; - pictureBoxCollection.Size = new Size(270, 517); + pictureBoxCollection.Size = new Size(670, 617); pictureBoxCollection.TabIndex = 0; pictureBoxCollection.TabStop = false; // @@ -305,16 +346,38 @@ namespace Trolleybus // panelTools.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right; panelTools.BorderStyle = BorderStyle.FixedSingle; + panelTools.Controls.Add(buttonSortByColor); + panelTools.Controls.Add(buttonSortByType); panelTools.Controls.Add(panelSets); panelTools.Controls.Add(buttonRefreshCollection); panelTools.Controls.Add(maskedTextBoxNumber); panelTools.Controls.Add(buttonRemoveBus); panelTools.Controls.Add(buttonAddBus); - panelTools.Location = new Point(276, 36); + panelTools.Location = new Point(676, 36); panelTools.Name = "panelTools"; - panelTools.Size = new Size(200, 517); + panelTools.Size = new Size(200, 617); panelTools.TabIndex = 1; // + // buttonSortByColor + // + buttonSortByColor.Location = new Point(13, 345); + buttonSortByColor.Name = "buttonSortByColor"; + buttonSortByColor.Size = new Size(180, 30); + buttonSortByColor.TabIndex = 6; + buttonSortByColor.Text = "Сортировать по цвету"; + buttonSortByColor.UseVisualStyleBackColor = true; + buttonSortByColor.Click += ButtonSortByColor_Click; + // + // buttonSortByType + // + buttonSortByType.Location = new Point(13, 309); + buttonSortByType.Name = "buttonSortByType"; + buttonSortByType.Size = new Size(180, 30); + buttonSortByType.TabIndex = 5; + buttonSortByType.Text = "Сортировать по типу"; + buttonSortByType.UseVisualStyleBackColor = true; + buttonSortByType.Click += ButtonSortByType_Click; + // // panelSets // panelSets.Anchor = AnchorStyles.Top | AnchorStyles.Right; @@ -367,7 +430,7 @@ namespace Trolleybus // // buttonRefreshCollection // - buttonRefreshCollection.Location = new Point(17, 465); + buttonRefreshCollection.Location = new Point(17, 549); buttonRefreshCollection.Name = "buttonRefreshCollection"; buttonRefreshCollection.Size = new Size(170, 40); buttonRefreshCollection.TabIndex = 3; @@ -377,7 +440,7 @@ namespace Trolleybus // // maskedTextBoxNumber // - maskedTextBoxNumber.Location = new Point(39, 366); + maskedTextBoxNumber.Location = new Point(39, 450); maskedTextBoxNumber.Mask = "00"; maskedTextBoxNumber.Name = "maskedTextBoxNumber"; maskedTextBoxNumber.Size = new Size(125, 27); @@ -386,7 +449,7 @@ namespace Trolleybus // // buttonRemoveBus // - buttonRemoveBus.Location = new Point(17, 409); + buttonRemoveBus.Location = new Point(17, 493); buttonRemoveBus.Name = "buttonRemoveBus"; buttonRemoveBus.Size = new Size(170, 40); buttonRemoveBus.TabIndex = 1; @@ -396,7 +459,7 @@ namespace Trolleybus // // buttonAddBus // - buttonAddBus.Location = new Point(17, 311); + buttonAddBus.Location = new Point(17, 395); buttonAddBus.Name = "buttonAddBus"; buttonAddBus.Size = new Size(170, 40); buttonAddBus.TabIndex = 0; @@ -410,7 +473,7 @@ namespace Trolleybus menuStrip.Items.AddRange(new ToolStripItem[] { fileToolStripMenuItem }); menuStrip.Location = new Point(0, 0); menuStrip.Name = "menuStrip"; - menuStrip.Size = new Size(482, 28); + menuStrip.Size = new Size(882, 28); menuStrip.TabIndex = 2; menuStrip.Text = "menuStrip1"; // @@ -446,7 +509,7 @@ namespace Trolleybus // // FormBusesCollection // - ClientSize = new Size(482, 553); + ClientSize = new Size(882, 653); Controls.Add(panelTools); Controls.Add(pictureBoxCollection); Controls.Add(menuStrip); @@ -463,7 +526,8 @@ namespace Trolleybus ResumeLayout(false); PerformLayout(); } - + private Button buttonSortByColor; + private Button buttonSortByType; private PictureBox pictureBoxCollection; private Panel panelTools; private Button buttonRefreshCollection; diff --git a/Trolleybus/Trolleybus/SetGeneric.cs b/Trolleybus/Trolleybus/SetGeneric.cs index 3ad7ebd..163ef73 100644 --- a/Trolleybus/Trolleybus/SetGeneric.cs +++ b/Trolleybus/Trolleybus/SetGeneric.cs @@ -35,18 +35,23 @@ namespace Trolleybus.Generics _maxCount = count; _places = new List(count); } + + /// + /// Сортировка набора объектов + /// + /// + public void SortSet(IComparer comparer) => _places.Sort(comparer); + /// /// Добавление объекта в начало набора /// /// Добавляемый автобус /// - public int Insert(T bus) + public int Insert(T bus, IEqualityComparer? equal = null) { if (Count + 1 <= _maxCount) { - _places.Insert(0, bus); - //0 в данном случае место, на котоорое добавился элемннт, вставка прошла успешно - return 0; + return Insert(bus, 0, equal); } //если при добавлении в списке станет больше макс. кол-ва элементов, то как бы вставлять будет некуда throw new StorageOverflowException(_maxCount); @@ -57,7 +62,7 @@ namespace Trolleybus.Generics /// Добавляемый автобус /// Позиция /// - public int Insert(T bus, int position) + public int Insert(T bus, int position, IEqualityComparer? equal = null) { if (position >= _maxCount || position < 0) { @@ -66,6 +71,10 @@ namespace Trolleybus.Generics } if (Count + 1 <= _maxCount) { + if (equal != null && _places.Contains(bus, equal)) + { + throw new ArgumentException("Объект уже существует"); + } _places.Insert(position, bus); //место в списке, по которому вставили, вставка прошла успешно return position;