Compare commits

...

13 Commits

42 changed files with 4066 additions and 51 deletions

View File

@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.8.34525.116 VisualStudioVersion = 17.8.34525.116
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectAirPlane", "ProjectAirPlane\ProjectAirPlane.csproj", "{36780227-CEDB-4504-AF69-0EB987304B89}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProjectAirPlane", "ProjectAirPlane\ProjectAirPlane.csproj", "{36780227-CEDB-4504-AF69-0EB987304B89}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@ -0,0 +1,118 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ProjectAirPlane.Drawnings;
namespace ProjectAirPlane.CollectionGenericObjects;
public abstract class AbstractCompany
{
/// <summary>
/// Размер места (ширина)
/// </summary>
protected readonly int _placeSizeWidth = 210;
/// <summary>
/// Размер места (высота)
/// </summary>
protected readonly int _placeSizeHeight = 80;
/// <summary>
/// Ширина окна
/// </summary>
protected readonly int _pictureWidth;
/// <summary>
/// Высота окна
/// </summary>
protected readonly int _pictureHeight;
/// <summary>
/// Коллекция автомобилей
/// </summary>
protected ICollectionGenericObjects<DrawningPlane>? _collection = null;
/// <summary>
/// Вычисление максимального количества элементов, который можно разместить в окне
/// </summary>
private int GetMaxCount => _pictureWidth * _pictureHeight / (_placeSizeWidth * _placeSizeHeight);
/// <summary>
/// Конструктор
/// </summary>
/// <param name="picWidth">Ширина окна</param>
/// <param name="picHeight">Высота окна</param>
/// <param name="collection">Коллекция автомобилей</param>
public AbstractCompany(int picWidth, int picHeight, ICollectionGenericObjects<DrawningPlane> collection)
{
_pictureWidth = picWidth;
_pictureHeight = picHeight;
_collection = collection;
_collection.MaxCount = GetMaxCount;
}
/// <summary>
/// Перегрузка оператора сложения для класса
/// </summary>
/// <param name="company">Компания</param>
/// <param name="car">Добавляемый объект</param>
/// <returns></returns>
public static int operator +(AbstractCompany company, DrawningPlane plane)
{
return company._collection?.Insert(plane) ?? -1;
}
/// <summary>
/// Перегрузка оператора удаления для класса
/// </summary>
/// <param name="company">Компания</param>
/// <param name="position">Номер удаляемого объекта</param>
/// <returns></returns>
public static DrawningPlane operator -(AbstractCompany company, int position)
{
return company._collection?.Remove(position) ?? null;
}
/// <summary>
/// Получение случайного объекта из коллекции
/// </summary>
/// <returns></returns>
public DrawningPlane? GetRandomObject()
{
Random rnd = new();
return _collection?.Get(rnd.Next(GetMaxCount));
}
/// <summary>
/// Вывод всей коллекции
/// </summary>
/// <returns></returns>
public Bitmap? Show()
{
Bitmap bitmap = new(_pictureWidth, _pictureHeight);
Graphics graphics = Graphics.FromImage(bitmap);
DrawBackgound(graphics);
SetObjectsPosition();
for (int i = 0; i < (_collection?.Count ?? 0); ++i)
{
DrawningPlane? obj = _collection?.Get(i);
obj?.DrawTransport(graphics);
}
return bitmap;
}
/// <summary>
/// Вывод заднего фона
/// </summary>
/// <param name="g"></param>
protected abstract void DrawBackgound(Graphics g);
/// <summary>
/// Расстановка объектов
/// </summary>
protected abstract void SetObjectsPosition();
}

View File

@ -0,0 +1,22 @@
namespace ProjectAirPlane.CollectionGenericObjects;
/// <summary>
/// Тип коллекции
/// </summary>
public enum CollectionType
{
/// <summary>
/// Неопределено
/// </summary>
None = 0,
/// <summary>
/// Массив
/// </summary>
Massive = 1,
/// <summary>
/// Список
/// </summary>
List = 2
}

View File

@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectAirPlane.CollectionGenericObjects;
public interface ICollectionGenericObjects<T>
where T : class
{
/// <summary>
/// Количество объектов в коллекции
/// </summary>
int Count { get; }
/// <summary>
/// Установка максимального количества элементов
/// </summary>
int MaxCount { set; get; }
/// <summary>
/// Добавление объекта в коллекцию
/// </summary>
/// <param name="obj">Добавляемый объект</param>
/// <returns>true - вставка прошла удачно, false - вставка не удалась</returns>
int Insert(T obj);
/// <summary>
/// Добавление объекта в коллекцию на конкретную позицию
/// </summary>
/// <param name="obj">Добавляемый объект</param>
/// <param name="position">Позиция</param>
/// <returns>true - вставка прошла удачно, false - вставка не удалась</returns>
int Insert(T obj, int position);
/// <summary>
/// Удаление объекта из коллекции с конкретной позиции
/// </summary>
/// <param name="position">Позиция</param>
/// <returns>true - удаление прошло удачно, false - удаление не удалось</returns>
T? Remove(int position);
/// <summary>
/// Получение объекта по позиции
/// </summary>
/// <param name="position">Позиция</param>
/// <returns>Объект</returns>
T? Get(int position);
/// <summary>
/// Получение типа коллекции
/// </summary>
CollectionType GetCollectionType { get; }
/// <summary>
/// Получение объектов коллекции по одному
/// </summary>
/// <returns>Поэлементый вывод элементов коллекции</returns>
IEnumerable<T?> GetItems();
}

View File

@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ProjectAirPlane.Drawnings;
namespace ProjectAirPlane.CollectionGenericObjects;
public class ListGenericObjects<T> : ICollectionGenericObjects<T>
where T : class
{
/// <summary>
/// Список объектов, которые храним
/// </summary>
private readonly List<T?> _collection;
public CollectionType GetCollectionType => CollectionType.List;
/// <summary>
/// Максимально допустимое число объектов в списке
/// </summary>
private int _maxCount;
public int Count => _collection.Count;
public int MaxCount {
get
{
return Count;
}
set
{
if (value > 0)
{
_maxCount = value;
}
}
}
/// <summary>
/// Конструктор
/// </summary>
public ListGenericObjects()
{
_collection = new();
}
public T? Get(int position)
{
// TODO проверка позиции
if (position >= Count || position < 0) return null;
return _collection[position];
}
public int Insert(T obj)
{
// TODO проверка, что не превышено максимальное количество элементов
// TODO вставка в конец набора
if (Count == _maxCount) return -1;
_collection.Add(obj);
return Count;
}
public int Insert(T obj, int position)
{
// TODO проверка, что не превышено максимальное количество элементов
// TODO проверка позиции
// TODO вставка по позиции
if (Count == _maxCount) return -1;
if (position >= Count || position < 0) return -1;
_collection.Insert(position, obj);
return position;
}
public T Remove(int position)
{
// TODO проверка позиции
// TODO удаление объекта из списка
if (position >= Count || position < 0) return null;
T obj = _collection[position];
_collection.RemoveAt(position);
return obj;
}
public IEnumerable<T?> GetItems()
{
for (int i = 0; i < Count; ++i)
{
yield return _collection[i];
}
}
}

View File

@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectAirPlane.CollectionGenericObjects;
public class MassiveGenericObjects<T> : ICollectionGenericObjects<T>
where T : class
{
/// <summary>
/// Массив объектов, которые храним
/// </summary>
private T?[] _collection;
public int Count => _collection.Length;
public int MaxCount
{
get
{
return _collection.Length;
}
set
{
if (value > 0)
{
if (_collection.Length > 0)
{
Array.Resize(ref _collection, value);
}
else
{
_collection = new T?[value];
}
}
}
}
public CollectionType GetCollectionType => CollectionType.Massive;
/// <summary>
/// Конструктор
/// </summary>
public MassiveGenericObjects()
{
_collection = Array.Empty<T?>();
}
public T? Get(int position)
{
// TODO проверка позиции
if (position >= _collection.Length || position < 0) return null;
return _collection[position];
}
public int Insert(T obj)
{
// TODO вставка в свободное место набора
int index = 0;
while (index < _collection.Length)
{
if (_collection[index] == null)
{
_collection[index] = obj;
return index;
}
++index;
}
return -1;
}
public int Insert(T obj, int position)
{
// TODO проверка позиции
// TODO проверка, что элемент массива по этой позиции пустой, если нет, то
// ищется свободное место после этой позиции и идет вставка туда
// если нет после, ищем до
// TODO вставка
if (position >= _collection.Length || position < 0)
return -1;
if (_collection[position] == null)
{
_collection[position] = obj;
return position;
}
int index = position + 1;
while (index < _collection.Length)
{
if (_collection[index] == null)
{
_collection[index] = obj;
return index;
}
++index;
}
index = position - 1;
while (index >= 0)
{
if (_collection[index] == null)
{
_collection[index] = obj;
return index;
}
--index;
}
return -1;
}
public T Remove(int position)
{
// TODO проверка позиции
// TODO удаление объекта из массива, присвоив элементу массива значение null
if (position >= _collection.Length || position < 0)
{
return null;
}
T obj = _collection[position];
_collection[position] = null;
return obj;
}
public IEnumerable<T?> GetItems()
{
for (int i = 0; i < _collection.Length; ++i)
{
yield return _collection[i];
}
}
}

View File

@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ProjectAirPlane.Drawnings;
namespace ProjectAirPlane.CollectionGenericObjects;
public class PlaneSharingService : AbstractCompany
{
public PlaneSharingService(int picWidth, int picHeight, ICollectionGenericObjects<DrawningPlane> collection) : base(picWidth, picHeight, collection)
{
}
protected override void DrawBackgound(Graphics g)
{
int width = _pictureWidth / _placeSizeWidth;
int height = _pictureHeight / _placeSizeHeight;
Pen pen = new(Color.Black, 3);
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height + 1; ++j)
{
g.DrawLine(pen, i * _placeSizeWidth, j * _placeSizeHeight, i * _placeSizeWidth + _placeSizeWidth - 5, j * _placeSizeHeight);
}
}
}
protected override void SetObjectsPosition()
{
int width = _pictureWidth / _placeSizeWidth;
int height = _pictureHeight / _placeSizeHeight;
int curWidth = width - 1;
int curHeight = 0;
for (int i = 0; i < (_collection?.Count ?? 0); i++)
{
if (_collection.Get(i) != null)
{
_collection.Get(i).SetPictureSize(_pictureWidth, _pictureHeight);
_collection.Get(i).SetPosition(_placeSizeWidth * curWidth + 15, curHeight * _placeSizeHeight + 3);
}
if (curWidth > 0)
curWidth--;
else
{
curWidth = width - 1;
curHeight++;
}
if (curHeight > height)
{
return;
}
}
}
}

View File

@ -0,0 +1,217 @@
using System.Text;
using ProjectAirPlane.Drawnings;
namespace ProjectAirPlane.CollectionGenericObjects;
/// <summary>
/// Класс-хранилище коллекций
/// </summary>
/// <typeparam name="T"></typeparam>
public class StorageCollection<T>
where T : DrawningPlane
{
/// <summary>
/// Словарь (хранилище) с коллекциями
/// </summary>
readonly Dictionary<string, ICollectionGenericObjects<T>> _storages;
/// <summary>
/// Возвращение списка названий коллекций
/// </summary>
public List<string> Keys => _storages.Keys.ToList();
/// <summary>
/// Конструктор
/// </summary>
public StorageCollection()
{
_storages = new Dictionary<string, ICollectionGenericObjects<T>>();
}
/// <summary>
/// Добавление коллекции в хранилище
/// </summary>
/// <param name="name">Название коллекции</param>
/// <param name="collectionType">тип коллекции</param>
public void AddCollection(string name, CollectionType collectionType)
{
// TODO проверка, что name не пустой и нет в словаре записи с таким ключом
// TODO Прописать логику для добавления
if (!(collectionType == CollectionType.None) && !_storages.ContainsKey(name))
{
if (collectionType == CollectionType.List)
{
_storages.Add(name, new ListGenericObjects<T>());
}
else if (collectionType == CollectionType.Massive)
{
_storages.Add(name, new MassiveGenericObjects<T>());
}
}
}
/// <summary>
/// Удаление коллекции
/// </summary>
/// <param name="name">Название коллекции</param>
public void DelCollection(string name)
{
// TODO Прописать логику для удаления коллекции
if (_storages.ContainsKey(name)) { _storages.Remove(name); }
}
/// <summary>
/// Доступ к коллекции
/// </summary>
/// <param name="name">Название коллекции</param>
/// <returns></returns>
/// <summary>
/// Доступ к коллекции
/// </summary>
/// <param name="name">Название коллекции</param>
/// <returns></returns>
public ICollectionGenericObjects<T>? this[string name]
{
get
{
// TODO Продумать логику получения объекта
if (_storages.ContainsKey(name))
return _storages[name];
return null;
}
}
/// <summary>
/// Ключевое слово, с которого должен начинаться файл
/// </summary>
private readonly string _collectionKey = "CollectionsStorage";
/// <summary>
/// Разделитель для записи ключа и значения элемента словаря
/// </summary>
private readonly string _separatorForKeyValue = "|";
/// <summary>
/// Разделитель для записей коллекции данных в файл
/// </summary>
private readonly string _separatorItems = ";";
/// <summary>
/// Сохранение информации по автомобилям в хранилище в файл
/// </summary>
/// <param name="filename">Путь и имя файла</param>
/// <returns>true - сохранение прошло успешно, false - ошибка при сохранении данных</returns>
public bool SaveData(string filename)
{
if (_storages.Count == 0)
{
return false;
}
if (File.Exists(filename))
{
File.Delete(filename);
}
using (StreamWriter writer = new StreamWriter(filename))
{
writer.Write(_collectionKey);
foreach (KeyValuePair<string, ICollectionGenericObjects<T>> value in _storages)
{
StringBuilder sb = new();
sb.Append(Environment.NewLine);
// не сохраняем пустые коллекции
if (value.Value.Count == 0)
{
continue;
}
sb.Append(value.Key);
sb.Append(_separatorForKeyValue);
sb.Append(value.Value.GetCollectionType);
sb.Append(_separatorForKeyValue);
sb.Append(value.Value.MaxCount);
sb.Append(_separatorForKeyValue);
foreach (T? item in value.Value.GetItems())
{
string data = item?.GetDataForSave() ?? string.Empty;
if (string.IsNullOrEmpty(data))
{
continue;
}
sb.Append(data);
sb.Append(_separatorItems);
}
writer.Write(sb);
}
}
return true;
}
/// <summary>
/// Загрузка информации по автомобилям в хранилище из файла
/// </summary>
/// <param name="filename">Путь и имя файла</param>
/// <returns>true - загрузка прошла успешно, false - ошибка при загрузке данных</returns>
public bool LoadData(string filename)
{
if (!File.Exists(filename))
{
return false;
}
using (StreamReader fs = File.OpenText(filename))
{
string str = fs.ReadLine();
if (str == null || str.Length == 0)
{
return false;
}
if (!str.StartsWith(_collectionKey))
{
return false;
}
_storages.Clear();
string strs = "";
while ((strs = fs.ReadLine()) != null)
{
string[] record = strs.Split(_separatorForKeyValue, StringSplitOptions.RemoveEmptyEntries);
if (record.Length != 4)
{
continue;
}
CollectionType collectionType = (CollectionType)Enum.Parse(typeof(CollectionType), record[1]);
ICollectionGenericObjects<T>? collection = StorageCollection<T>.CreateCollection(collectionType);
if (collection == null)
{
return false;
}
collection.MaxCount = Convert.ToInt32(record[2]);
string[] set = record[3].Split(_separatorItems, StringSplitOptions.RemoveEmptyEntries);
foreach (string elem in set)
{
if (elem?.CreateDrawningPlane() is T plane)
{
if (collection.Insert(plane) == -1)
{
return false;
}
}
}
_storages.Add(record[0], collection);
}
return true;
}
}
/// <summary>
/// Создание коллекции по типу
/// </summary>
/// <param name="collectionType"></param>
/// <returns></returns>
private static ICollectionGenericObjects<T>? CreateCollection(CollectionType collectionType)
{
return collectionType switch
{
CollectionType.Massive => new MassiveGenericObjects<T>(),
CollectionType.List => new ListGenericObjects<T>(),
_ => null,
};
}
}

View File

@ -0,0 +1,32 @@
namespace ProjectAirPlane.Drawnings;
/// <summary>
/// Направление перемещения
/// </summary>
public enum DirectionType
{
/// <summary>
/// Неизвестное направление
/// </summary>
Unknow = -1,
/// <summary>
/// Вверх
/// </summary>
Up = 1,
/// <summary>
/// Вниз
/// </summary>
Down = 2,
/// <summary>
/// Влево
/// </summary>
Left = 3,
/// <summary>
/// Вправо
/// </summary>
Right = 4
}

View File

@ -0,0 +1,87 @@
using ProjectAirPlane.Entites;
namespace ProjectAirPlane.Drawnings;
/// <summary>
/// Класс, отвечающий за прорисовку и перемещение объекта-сущности
/// </summary>
public class DrawningAirPlane : DrawningPlane
{
/// <summary>
/// Конструктор
/// </summary>
/// <param name="speed">Скорость</param>
/// <param name="weight">Вес</param>
/// <param name="bodyColor">Основной цвет</param>
/// <param name="additionalColor">Дополнительный цвет</param>
/// <param name="radar">Признак наличия обвеса</param>
/// <param name="dopBak">Признак наличия антикрыла</param>
/// <param name="chassi">Признак наличия гоночной полосы</param>
public DrawningAirPlane(int speed, double weight, Color bodyColor, Color additionalColor, bool radar, bool dopBak) : base(195, 70)
{
EntityPlane = new EntityAirPlane(speed, weight, bodyColor, additionalColor, radar, dopBak);
}
public DrawningAirPlane(EntityAirPlane plane) : base(195, 70)
{
EntityPlane = new EntityAirPlane(plane.Speed, plane.Weight, plane.BodyColor, plane.AdditionalColor, plane.Radar, plane.DopBak);
}
public override void DrawTransport(Graphics g)
{
if (EntityPlane == null || EntityPlane is not EntityAirPlane airPlane || !_startPosX.HasValue || !_startPosY.HasValue)
{
return;
}
Pen pen = new(Color.Black);
Brush additionalBrush = new SolidBrush(airPlane.AdditionalColor);
if (airPlane.Chassi)
{
//шасси
g.DrawLine(pen, _startPosX.Value + 50, _startPosY.Value + 55, _startPosX.Value + 50, _startPosY.Value + 70);
g.DrawLine(pen, _startPosX.Value + 150, _startPosY.Value + 55, _startPosX.Value + 150, _startPosY.Value + 70);
g.FillEllipse(additionalBrush, _startPosX.Value + 40, _startPosY.Value + 65, 10, 10);
g.FillEllipse(additionalBrush, _startPosX.Value + 50, _startPosY.Value + 65, 10, 10);
g.FillEllipse(additionalBrush, _startPosX.Value + 145, _startPosY.Value + 65, 10, 10);
}
base.DrawTransport(g);
if (airPlane.DopBak)
{
//бак
g.FillEllipse(additionalBrush, _startPosX.Value, _startPosY.Value + 45, 40, 20);
g.DrawEllipse(pen, _startPosX.Value, _startPosY.Value + 45, 40, 20);
}
if (airPlane.Radar)
{
//радар
g.DrawLine(pen, _startPosX.Value + 60, _startPosY.Value + 25, _startPosX.Value + 60, _startPosY.Value + 15);
g.DrawLine(pen, _startPosX.Value + 60, _startPosY.Value + 15, _startPosX.Value + 67, _startPosY.Value + 11);
Point point7 = new Point(_startPosX.Value + 60, _startPosY.Value + 15);
Point point8 = new Point(_startPosX.Value + 60, _startPosY.Value + 5);
Point point9 = new Point(_startPosX.Value + 70, _startPosY.Value + 25);
Point[] curvePoints3 =
{
point7,
point8,
point9,
};
g.FillPolygon(additionalBrush, curvePoints3);
}
}
}

View File

@ -0,0 +1,265 @@
using ProjectAirPlane.Entites;
namespace ProjectAirPlane.Drawnings;
public class DrawningPlane
{
/// <summary>
/// Класс-сущность
/// </summary>
public EntityPlane? EntityPlane { get; protected set; }
/// <summary>
/// Ширина окна
/// </summary>
private int? _pictureWidth;
/// <summary>
/// Высота окна
/// </summary>
private int? _pictureHeight;
/// <summary>
/// Левая координата прорисовки автомобиля
/// </summary>
protected int? _startPosX;
/// <summary>
/// Верхняя кооридната прорисовки автомобиля
/// </summary>
protected int? _startPosY;
/// <summary>
/// Ширина прорисовки самолёта
/// </summary>
private readonly int _drawningAirPlaneWidth = 195;
/// <summary>
/// Высота прорисовки самолёта
/// </summary>
private readonly int _drawningAirPlaneHeight = 70;
/// <summary>
/// Координата X объекта
/// </summary>
public int? GetPosX => _startPosX;
/// <summary>
/// Координата Y объекта
/// </summary>
public int? GetPosY => _startPosY;
/// <summary>
/// Ширина объекта
/// </summary>
public int GetWidth => _drawningAirPlaneWidth;
/// <summary>
/// Высота объекта
/// </summary>
public int GetHeight => _drawningAirPlaneHeight;
/// <summary>
/// Пустой конструктор
/// </summary>
private DrawningPlane()
{
_pictureWidth = null;
_pictureHeight = null;
_startPosX = null;
_startPosY = null;
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="speed">Скорость</param>
/// <param name="weight">Вес</param>
/// <param name="bodyColor">Основной цвет</param>
public DrawningPlane(int speed, double weight, Color bodyColor) : this()
{
EntityPlane = new EntityPlane(speed, weight, bodyColor);
}
/// <summary>
/// Конструктор для наследования
/// </summary>
/// <param name="drawningAirPlaneWidth">Ширина прорисовки самолёта </param>
/// <param name="drawningAirPlaneHeight">Высота прорисовки самолёта</param>
protected DrawningPlane(int drawningPlaneWidth, int drawningPlaneHeight) : this()
{
_drawningAirPlaneWidth = drawningPlaneWidth;
_drawningAirPlaneHeight = drawningPlaneHeight;
}
public DrawningPlane(EntityPlane plane) : this()
{
EntityPlane = new EntityPlane(plane.Speed, plane.Weight, plane.BodyColor);
}
/// <summary>
/// Установка границ поля
/// </summary>
/// <param name="width">Ширина поля</param>
/// <param name="height">Высота поля</param>
/// <returns>true - границы заданы, false - проверка не пройдена, нельзя разместить объект в этих размерах</returns>
public bool SetPictureSize(int width, int height)
{
// TODO проверка, что объект "влезает" в размеры поля
if (_drawningAirPlaneWidth > width || _drawningAirPlaneHeight > height)
{
return false;
}
_pictureWidth = width;
_pictureHeight = height;
if (_startPosX.HasValue || _startPosY.HasValue)
{
if (_startPosX + _drawningAirPlaneWidth > _pictureWidth)
{
_startPosX = _pictureWidth - _drawningAirPlaneWidth;
}
else if (_startPosX < 0) _startPosX = 0;
if (_startPosY + _drawningAirPlaneHeight > _pictureHeight)
{
_startPosY = _pictureHeight - _drawningAirPlaneHeight;
}
else if (_startPosY < 0) _startPosY = 0;
}
return true;
}
/// <summary>
/// Установка позиции
/// </summary>
/// <param name="x">Координата X</param>
/// <param name="y">Координата Y</param>
public void SetPosition(int x, int y)
{
if (!_pictureHeight.HasValue || !_pictureWidth.HasValue)
{
return;
}
// TODO если при установке объекта в эти координаты, он будет "выходить" за границы формы
if (x + _drawningAirPlaneWidth >= _pictureWidth || y + _drawningAirPlaneHeight >= _pictureHeight)
{
x = y = 10;
_startPosX = x;
_startPosY = y;
}
// то надо изменить координаты, чтобы он оставался в этих границах
_startPosX = x;
_startPosY = y;
}
/// <summary>
/// Изменение направления перемещения
/// </summary>
/// <param name="direction">Направление</param>
/// <returns>true - перемещене выполнено, false - перемещение невозможно</returns>
public bool MoveTransport(DirectionType direction)
{
if (EntityPlane == null || !_startPosX.HasValue || !_startPosY.HasValue)
{
return false;
}
switch (direction)
{
//влево
case DirectionType.Left:
if (_startPosX.Value - EntityPlane.Step > 0)
{
_startPosX -= (int)EntityPlane.Step;
}
return true;
//вверх
case DirectionType.Up:
if (_startPosY.Value - EntityPlane.Step > 0)
{
_startPosY -= (int)EntityPlane.Step;
}
return true;
// вправо
case DirectionType.Right:
//TODO прописать логику сдвига вправо
if (_startPosX + EntityPlane.Step + _drawningAirPlaneWidth < _pictureWidth)
{
_startPosX += (int)EntityPlane.Step;
}
return true;
//вниз
case DirectionType.Down:
//TODO прописать логику сдвига ввниз
if (_startPosY + EntityPlane.Step + _drawningAirPlaneHeight < _pictureHeight)
{
_startPosY += (int)EntityPlane.Step;
}
return true;
default:
return false;
}
}
/// <summary>
/// Прорисовка объекта
/// </summary>
/// <param name="g"></param>
public virtual void DrawTransport(Graphics g)
{
if (EntityPlane == null || !_startPosX.HasValue || !_startPosY.HasValue)
{
return;
}
Pen pen = new(Color.Black);
Brush additionalBrush = new SolidBrush(EntityPlane.BodyColor);
//шасси
g.DrawLine(pen, _startPosX.Value + 50, _startPosY.Value + 55, _startPosX.Value + 50, _startPosY.Value + 70);
g.DrawLine(pen, _startPosX.Value + 150, _startPosY.Value + 55, _startPosX.Value + 150, _startPosY.Value + 70);
g.FillEllipse(additionalBrush, _startPosX.Value + 40, _startPosY.Value + 65, 10, 10);
g.FillEllipse(additionalBrush, _startPosX.Value + 50, _startPosY.Value + 65, 10, 10);
g.FillEllipse(additionalBrush, _startPosX.Value + 145, _startPosY.Value + 65, 10, 10);
// корпус
Brush br = new SolidBrush(EntityPlane.BodyColor);
g.DrawRectangle(pen, _startPosX.Value, _startPosY.Value + 25, 170, 30);
g.FillRectangle(br, _startPosX.Value, _startPosY.Value + 25, 170, 30);
// бак
Brush blackBrush = new SolidBrush(Color.Black);
g.FillEllipse(blackBrush, _startPosX.Value + 75, _startPosY.Value + 30, 50, 10);
// нос самолёта
Pen blackPen = new Pen(Color.Black, 2);
Brush blueBrush = new SolidBrush(Color.LightBlue);
Point point1 = new Point(_startPosX.Value + 170, _startPosY.Value + 25);
Point point2 = new Point(_startPosX.Value + 200, _startPosY.Value + 40);
Point point3 = new Point(_startPosX.Value + 170, _startPosY.Value + 55);
Point[] curvePoints =
{
point1,
point2,
point3,
};
g.FillPolygon(blueBrush, curvePoints);
g.DrawPolygon(blackPen, curvePoints);
g.DrawLine(blackPen, _startPosX.Value + 170, _startPosY.Value + 40, _startPosX.Value + 200, _startPosY.Value + 40);
// хвост
Brush bw = new SolidBrush(EntityPlane.BodyColor);
g.FillPolygon(bw, new Point[]
{
new Point((int) _startPosX, (int) _startPosY + 40 ), new Point((int) _startPosX + 80, (int) _startPosY + 30),
new Point((int) _startPosX, (int) _startPosY), new Point((int) _startPosX , (int) _startPosY + 40),
}
);
}
}

View File

@ -0,0 +1,49 @@

using ProjectAirPlane.Entites;
namespace ProjectAirPlane.Drawnings;
/// <summary>
/// Расширение для класса EntityPlane
/// </summary>
public static class ExtentionDrawningPlane
{
/// <summary>
/// Разделитель для записи информации по объекту в файл
/// </summary>
private static readonly string _separatorForObject = ":";
/// <summary>
/// Создание объекта из строки
/// </summary>
/// <param name="info">Строка с данными для создания объекта</param>
/// <returns>Объект</returns>
public static DrawningPlane? CreateDrawningPlane(this string info)
{
string[] strs = info.Split(_separatorForObject);
EntityPlane? plane = EntityAirPlane.CreateEntityAirPlane(strs);
if (plane != null)
{
return new DrawningAirPlane((EntityAirPlane)plane);
}
plane = EntityPlane.CreateEntityPlane(strs);
if (plane != null)
{
return new DrawningPlane(plane);
}
return null;
}
/// <summary>
/// Получение данных для сохранения в файл
/// </summary>
/// <param name="drawningCar">Сохраняемый объект</param>
/// <returns>Строка с данными по объекту</returns>
public static string GetDataForSave(this DrawningPlane drawningPlane)
{
string[]? array = drawningPlane?.EntityPlane?.GetStringRepresentation();
if (array == null)
{
return string.Empty;
}
return string.Join(_separatorForObject, array);
}
}

View File

@ -0,0 +1,84 @@
namespace ProjectAirPlane.Entites;
/// <summary>
/// Класс-сущность "Спортивный самолёт"
/// </summary>
public class EntityAirPlane : EntityPlane
{
/// <summary>
/// Дополнительный цвет (для опциональных элементов)
/// </summary>
public Color AdditionalColor { get; private set; }
/// <summary>
/// Присваивание цвета
/// </summary>
public void SetAdditionalColor(Color color)
{
AdditionalColor = color;
}
/// <summary>
/// Признак (опция) наличия радара
/// </summary>
public bool Radar { get; private set; }
/// <summary>
/// Признак (опция) наличия допбака
/// </summary>
public bool DopBak { get; private set; }
/// <summary>
/// Признак (опция) наличия шасси
/// </summary>
public bool Chassi { get; private set; }
/// <summary>
/// Шаг перемещения автомобиля
/// </summary>
/// <summary>
/// Инициализация полей объекта-класса спортивного автомобиля
/// </summary>
/// <param name="speed">Скорость</param>
/// <param name="weight">Вес автомобиля</param>
/// <param name="bodyColor">Основной цвет</param>
/// <param name="additionalColor">Дополнительный цвет</param>
/// <param name="radar">Признак наличия обвеса</param>
/// <param name="dopBak">Признак наличия антикрыла</param>
/// <param name="chassi">Признак наличия гоночной полосы</param>
public EntityAirPlane(int speed, double weight, Color bodyColor, Color additionalColor, bool radar, bool dopBak) : base(speed, weight, bodyColor)
{
AdditionalColor = additionalColor;
Radar = radar;
DopBak = dopBak;
}
/// <summary>
/// Получение строк со значениями свойств продвинутого объекта класса-сущности
/// </summary>
/// <returns></returns>
public override string[] GetStringRepresentation()
{
return new[] { nameof(EntityAirPlane), Speed.ToString(), Weight.ToString(), BodyColor.Name, AdditionalColor.Name,
Radar.ToString(), DopBak.ToString()};
}
/// <summary>
/// Создание продвинутого объекта из массива строк
/// </summary>
/// <param name="strs"></param>
/// <returns></returns>
public static EntityAirPlane? CreateEntityAirPlane(string[] strs)
{
if (strs.Length != 7 || strs[0] != nameof(EntityAirPlane))
{
return null;
}
return new EntityAirPlane(Convert.ToInt32(strs[1]), Convert.ToDouble(strs[2]), Color.FromName(strs[3]),
Color.FromName(strs[4]), Convert.ToBoolean(strs[5]), Convert.ToBoolean(strs[6]));
}
}

View File

@ -0,0 +1,73 @@
namespace ProjectAirPlane.Entites;
/// <summary>
/// Класс-сущность "Обычный самолёт"
/// </summary>
public class EntityPlane
{
/// <summary>
/// Скорость
/// </summary>
public int Speed { get; private set; }
/// <summary>
/// Вес
/// </summary>
public double Weight { get; private set; }
/// <summary>
/// Основной цвет
/// </summary>
public Color BodyColor { get; private set; }
/// <summary>
/// Присваивание цвета
/// </summary>
public void SetBodyColor(Color color)
{
BodyColor = color;
}
/// <summary>
/// Шаг перемещения автомобиля
/// </summary>
public double Step => Speed * 100 / Weight;
/// <summary>
/// Конструктор сущности
/// </summary>
/// <param name="speed">Скорость</param>
/// <param name="weight">Вес автомобиля</param>
/// <param name="bodyColor">Основной цвет</param>
public EntityPlane(int speed, double weight, Color bodyColor)
{
Speed = speed;
Weight = weight;
BodyColor = bodyColor;
}
/// <summary>
/// Получение строк со значениями свойств объекта класса-сущности
/// </summary>
/// <returns></returns>
public virtual string[] GetStringRepresentation()
{
return new[] { nameof(EntityPlane), Speed.ToString(), Weight.ToString(), BodyColor.Name };
}
/// <summary>
/// Создание объекта из массива строк
/// </summary>
/// <param name="strs"></param>
/// <returns></returns>
public static EntityPlane? CreateEntityPlane(string[] strs)
{
if (strs.Length != 4 || strs[0] != nameof(EntityPlane))
{
return null;
}
return new EntityPlane(Convert.ToInt32(strs[1]), Convert.ToDouble(strs[2]), Color.FromName(strs[3]));
}
}

View File

@ -1,39 +0,0 @@
namespace ProjectAirPlane
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "Form1";
}
#endregion
}
}

View File

@ -1,10 +0,0 @@
namespace ProjectAirPlane
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,147 @@
namespace ProjectAirPlane
{
partial class FormAirPlane
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormAirPlane));
pictureBoxAirPlane = new PictureBox();
buttonLeft = new Button();
buttonUp = new Button();
buttonDown = new Button();
buttonRight = new Button();
comboBoxStrategy = new ComboBox();
buttonStrategyStepS = new Button();
((System.ComponentModel.ISupportInitialize)pictureBoxAirPlane).BeginInit();
SuspendLayout();
//
// pictureBoxAirPlane
//
pictureBoxAirPlane.Dock = DockStyle.Fill;
pictureBoxAirPlane.Location = new Point(0, 0);
pictureBoxAirPlane.Name = "pictureBoxAirPlane";
pictureBoxAirPlane.Size = new Size(749, 523);
pictureBoxAirPlane.TabIndex = 0;
pictureBoxAirPlane.TabStop = false;
//
// buttonLeft
//
buttonLeft.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonLeft.BackgroundImage = (Image)resources.GetObject("buttonLeft.BackgroundImage");
buttonLeft.BackgroundImageLayout = ImageLayout.Stretch;
buttonLeft.Location = new Point(613, 476);
buttonLeft.Name = "buttonLeft";
buttonLeft.Size = new Size(35, 35);
buttonLeft.TabIndex = 2;
buttonLeft.UseVisualStyleBackColor = true;
buttonLeft.Click += ButtonMove_Click;
//
// buttonUp
//
buttonUp.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonUp.BackgroundImage = (Image)resources.GetObject("buttonUp.BackgroundImage");
buttonUp.BackgroundImageLayout = ImageLayout.Stretch;
buttonUp.Location = new Point(654, 435);
buttonUp.Name = "buttonUp";
buttonUp.Size = new Size(35, 35);
buttonUp.TabIndex = 3;
buttonUp.UseVisualStyleBackColor = true;
buttonUp.Click += ButtonMove_Click;
//
// buttonDown
//
buttonDown.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonDown.BackgroundImage = (Image)resources.GetObject("buttonDown.BackgroundImage");
buttonDown.BackgroundImageLayout = ImageLayout.Stretch;
buttonDown.Location = new Point(654, 476);
buttonDown.Name = "buttonDown";
buttonDown.Size = new Size(35, 35);
buttonDown.TabIndex = 4;
buttonDown.UseVisualStyleBackColor = true;
buttonDown.Click += ButtonMove_Click;
//
// buttonRight
//
buttonRight.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonRight.BackgroundImage = (Image)resources.GetObject("buttonRight.BackgroundImage");
buttonRight.BackgroundImageLayout = ImageLayout.Stretch;
buttonRight.Location = new Point(695, 476);
buttonRight.Name = "buttonRight";
buttonRight.Size = new Size(35, 35);
buttonRight.TabIndex = 5;
buttonRight.UseVisualStyleBackColor = true;
buttonRight.Click += ButtonMove_Click;
//
// comboBoxStrategy
//
comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxStrategy.FormattingEnabled = true;
comboBoxStrategy.Items.AddRange(new object[] { "К центру", "К краю" });
comboBoxStrategy.Location = new Point(628, 12);
comboBoxStrategy.Name = "comboBoxStrategy";
comboBoxStrategy.Size = new Size(121, 23);
comboBoxStrategy.TabIndex = 7;
//
// buttonStrategyStepS
//
buttonStrategyStepS.Location = new Point(654, 41);
buttonStrategyStepS.Name = "buttonStrategyStepS";
buttonStrategyStepS.Size = new Size(75, 23);
buttonStrategyStepS.TabIndex = 8;
buttonStrategyStepS.Text = "Шаг";
buttonStrategyStepS.UseVisualStyleBackColor = true;
buttonStrategyStepS.Click += ButtonStrategyStep_Click;
//
// FormAirPlane
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(749, 523);
Controls.Add(buttonStrategyStepS);
Controls.Add(comboBoxStrategy);
Controls.Add(buttonRight);
Controls.Add(buttonDown);
Controls.Add(buttonUp);
Controls.Add(buttonLeft);
Controls.Add(pictureBoxAirPlane);
Name = "FormAirPlane";
Text = "Спортивный автомобиль";
((System.ComponentModel.ISupportInitialize)pictureBoxAirPlane).EndInit();
ResumeLayout(false);
}
#endregion
private PictureBox pictureBoxAirPlane;
private Button buttonLeft;
private Button buttonUp;
private Button buttonDown;
private Button buttonRight;
private ComboBox comboBoxStrategy;
private Button buttonStrategyStepS;
}
}

View File

@ -0,0 +1,133 @@
using ProjectAirPlane.Drawnings;
using ProjectAirPlane.MovementStrategy;
namespace ProjectAirPlane;
/// <summary>
/// Ôîðìà ðàáîòû ñ îáúåêòîì "Êîíòåéíåðîâîç"
/// </summary>
public partial class FormAirPlane : Form
{
/// <summary>
/// Ïîëå-îáúåêò äëÿ ïðîðèñîâêè îáúåêòà
/// </summary>
private DrawningPlane? _drawningPlane;
/// <summary>
/// Ñòðàòåãèÿ ïåðåìåùåíèÿ
/// </summary>
private AbstractStrategy? _strategy;
public DrawningPlane SetPlane
{
set
{
_drawningPlane = value;
_drawningPlane.SetPictureSize(pictureBoxAirPlane.Width, pictureBoxAirPlane.Height);
comboBoxStrategy.Enabled = true;
_strategy = null;
Draw();
}
}
/// <summary>
/// Êîíñòðóêòîð ôîðìû
/// </summary>
public FormAirPlane()
{
InitializeComponent();
_strategy = null;
}
/// <summary>
/// Ìåòîä ïðîðèñîâêè êîíòåéíåðîâîçà
/// </summary>
private void Draw()
{
if (_drawningPlane == null)
{
return;
}
Bitmap bmp = new(pictureBoxAirPlane.Width, pictureBoxAirPlane.Height);
Graphics gr = Graphics.FromImage(bmp);
_drawningPlane.DrawTransport(gr);
pictureBoxAirPlane.Image = bmp;
}
/// <summary>
/// Ïåðåìåùåíèå îáúåêòà ïî ôîðìå (íàæàòèå êíîïîê íàâèãàöèè)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonMove_Click(object sender, EventArgs e)
{
if (_drawningPlane == null)
{
return;
}
string name = ((Button)sender)?.Name ?? string.Empty;
bool result = false;
switch (name)
{
case "buttonUp":
result = _drawningPlane.MoveTransport(DirectionType.Up);
break;
case "buttonDown":
result = _drawningPlane.MoveTransport(DirectionType.Down);
break;
case "buttonLeft":
result = _drawningPlane.MoveTransport(DirectionType.Left);
break;
case "buttonRight":
result = _drawningPlane.MoveTransport(DirectionType.Right);
break;
}
if (result)
{
Draw();
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonStrategyStep_Click(object sender, EventArgs e)
{
if (_drawningPlane == null) return;
if (comboBoxStrategy.Enabled)
{
_strategy = comboBoxStrategy.SelectedIndex switch
{
0 => new MoveToCenter(),
1 => new MoveToBorder(),
_ => null,
};
if (_strategy == null)
{
return;
}
_strategy.SetData(new MoveablePlane(_drawningPlane), pictureBoxAirPlane.Width, pictureBoxAirPlane.Height);
}
if (_strategy == null)
{
return;
}
comboBoxStrategy.Enabled = false;
_strategy.MakeStep();
Draw();
if (_strategy.GetStatus() == StrategyStatus.Finish)
{
comboBoxStrategy.Enabled = true;
_strategy = null;
}
}
}

View File

@ -0,0 +1,555 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="buttonLeft.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
AAAASUVORK5CYII=
</value>
</data>
<data name="buttonUp.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
CgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAb
xRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC6
1SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgA
oACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACw
UQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyh
W40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40C
AAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoA
G8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQ
utUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUo
AKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAA
sFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEM
oVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuN
AgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAK
ABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvF
ELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrV
KACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACg
ALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBR
DKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFb
jQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIA
CgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAb
xRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC6
1SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgA
oACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACw
UQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyh
W40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40C
AAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoA
G8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQ
utUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUo
AKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAA
sFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEM
oVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuN
AgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAK
ABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvF
ELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrV
KACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACg
ALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBR
DKFbjQIACgAbxRC61XxyWYJwVX8tvQ+4hxjCPdT84rII4Yr+XHobcA8xhHuo+YllEcIV/fH0NuAeYgj3
UPP9yyKEK/q29DbgHmII91Dz2WURwtV8sXwsvQ24hxjCPdT8prkI4Yq+N70LuJcYwr3U/JtlIcKV/P70
JuBeYgj3UvOZZSHCVfxAeg9wTzGEe6r5x8tihCv4HektwD3FEO6p5tPlZ+dihLP7zvQO4N5iCPdW8zvL
L80FCWf1T8tH0xuAe4sh7FDzh8v/LuvChLP4V+UT6duHHWIIu9T89uL/DuBs/mb51embh11iCDvVjL8m
4O+XXynrEoWj+W/lj6XvHHaLITyCmt9S/kn55bIuVXh0P1P+TPna9G3DI4ghPJKary9/tIw/KzD+wUE/
VfwFgzyKL5QfKZ8r31G+tbyTvmV4HF/6yP8FqdbUgRJva58AAAAASUVORK5CYII=
</value>
</data>
<data name="buttonDown.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAP
RAAAD0QBF63jCwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABrPSURBVHhe7d1f
yLZrWhbwWSM1hMM0SoEwzpL+7QdBYSlM4FbtFG1Y7bRV0FY0OyFBQUWCqZthG4JFRYVEErWTQwWRSkSS
JIKpYWmYNU0oSGM4nVdzTetaax3fn/d9n+e8nvu+fyf8dg5hRnju6zyPWbPmWx/50pe+BA+t5p3yjeU7
yufKj5cvlPF/hN2+WH62/Ej5++VPlK9N3zI8khjCI6j56vLny8+XdeHCo/vV8k/K70rfNjyCGMJuNX+y
/NeyLlU4ml8r468KfDp957BTDGGXml9f/mZZlygc3S+U35u+edglhrBDzSfKvyrr4oSz+N/lj6VvH3aI
IXSr+Wj5p2VdmHA2428Y/Kb0BqBbDKFbzXfOBQlnN/7rAH9PANvFEDrV/L65GOEq/nF6C9AphtCp5oeW
xQhX8Zn0HqBLDKFLzR9eFiJcyY+kNwFdYghdar5/WYhwNb89vQvoEEPoUPOx8ktzEcIVfTa9DegQQ+hQ
8y3LIoQr+sH0NqBDDKFDzZ9aFiFc0U+ntwEdYggdav7isgjhin4lvQ3oEEPoUPM9yyKEq/pkeh9wbzGE
DjXftyxBuKqvS+8D7i2G0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWA
TWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWII
HWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoU
AFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA
2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG
0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFG
AQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAF
gE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1i
CB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1q
FABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQ
ANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgk
htChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtCh
RgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEA
BYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBN
YggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggd
ahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQA
UADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADY
JIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQ
oUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYB
AAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWA
TWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWII
HWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoU
AFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA
2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG
0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFG
AQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAF
gE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1i
CB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1q
FABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQ
ANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgk
htChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtCh
RgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEA
BYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBN
YggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggd
ahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQA
UADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADY
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
</value>
</data>
<data name="buttonRight.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAP
RAAAD0QBF63jCwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABUVSURBVHhe7d1d
yK15WQbwNRM1hMM0SoKgjvTheRAYfYFBR3VSdGB10lFBR9GchAQFFQXjx2HUgVBRUiGRRJ3UUEGkEZEU
ieAnpkZa44SCpOF03+6le+3/vvfe78d67vU8/+d3wW+Yud72u9Z69rjva8rZHV566SUAYGfKEgCYW1kC
AHMrSwBgbmUJAMytLAGAuZUlADC3sgQA5laWAMDcyhIAmFtZAgBzK0sAYG5lCQDMrSwBgLmVJQAwt7IE
AOZWlgDA3MoSAJhbWQIAcytLAGBuZQkAzK0sAYC5lSUAMLeyBADmVpYAwNzKEgCYW1kCAHMrSwBgbmUJ
AMytLAGAuZUlADC3sgQA5laWAMDcyhIAmFtZAgBzK0sAYG5lCQDMrSwBgLmVJQAwt7IEAOZWlgDA3MoS
AJhbWQIAcytLAGBuZQkAzK0sAYC5lSUAMLeyBNiCyONVDzxaWQKsSeQV4U3hHeF94ZPhi+FL4d/De8Nv
hx8KT1TfA7hXWQKsQeTbwu+F/wtZXMXnwtvCy6vvCdxRlgCXFPnG8Jsh/wn/9Lhfxwvh58Nj1WvA3pUl
wKVEngn/FE6P+W38aXiyei3Ys7IEuITId4RPh9MDfg7/Ep6pXhP2qiwBukVeFT4eTg/3OX00vK56bdij
sgToFHkivCecHuwlGAFwVJYAnSK/cDzQHYwACGUJ0CWS/47/Z8PpkV6aEcDulSVAl8hzx6PczQhg18oS
oEPksfCJcHqYOxkB7FZZAnSIvOF4iC/JCGCXyhKgQ+RXjkf40owAdqcsATpE3nk8wGtgBLArZQnQIfLX
x+O7FkYAu1GWAB0iHzge3jUxAtiFsgToEPnY8eiujRHA9MoSoENkrQMgGQFMrSwBOkTWPACSEcC0yhKg
Q2TtAyAZAUypLAE6RLYwAJIRwHTKEqBDZCsDIBkBTKUsATpEtjQAkhHANMoSoENkawMgGQFMoSwBOkS2
OACSEcDmlSVAh8hWB0AyAti0sgToENnyAEhGAJtVlgAdIlsfAMkIYJPKEqBDZIYBkIwANqcsATpEZhkA
yQhgU8oSoENkpgGQjAA2oywBOkRmGwDJCGATyhKgQ2TGAZCMAFavLAE6RGYdAMkIYNXKEqBDZOYBkIwA
VqssATpEZh8AyQhglcoSoENkDwMgGQGsTlkCdIjsZQAkI4BVKUuADpE9DYBkBLAaZQnQIbK3AZCMAFah
LAE6RPY4AJIRwMWVJUCHyF4HQDICuKiyBOgQ2fMASEYAF1OWAB0iex8AyQjgIsoSoEPEALjDCKBdWQJ0
iBgAdxkBtCpLgA4RA+BeRgBtyhKgQ8QAuJ8RQIuyBOgQMQBqRgCLK0uADhED4MGMABZVlgAdIgbAwxkB
LKYsATpEDIBHMwJYRFkCdIgYAFdjBHB2ZQnQIWIAXN1HwjPVc4SbKEuADhED4HqMAM6mLAE6RAyA6zMC
OIuyBOgQMQBuxgjg1soSoEPEALg5I4BbKUuADhED4HaMAG6sLAE6RAyA2zMCuJGyBOgQMQDOwwjg2soS
oEPEADgfI4BrKUuADhED4LyMAK6sLAE6RAyA8zMCuJKyBOgQMQCWYQTwSGUJ0CFiACzHCOChyhKgQ8QA
WJYRwAOVJUCHiAGwPCOAUlkCdIgYAD2MAO5TlgAdIgZAHyOAe5QlQIeIAdDLCOBryhKgQ8QA6GcE8BVl
CdAhYgBchhFA/J1QlAAdIgbA5RgBO1eWAB0iBsBlGQE7VpYAHSIGwOUZATtVlgAdIgbAOhgBO1SWAB0i
BsB6GAE7U5YAHSIGwLoYATtSlgAdIgbA+hgBO1GWAB0iBsA6GQE7UJYAHSIGwHoZAZMrS4AOEQNg3YyA
iZUlQIeIAbB+RsCkyhKgQ8QA2AYjYEJlCdAhYgBshxEwmbIE6BAxALbFCJhIWQJ0iBgA22METKIsATpE
DIBtMgImUJYAHSIGwHYZARtXlgAdIgbAthkBG1aWAB0iBsD2GQEbVZYAHSIGwByMgA0qS4AOEQNgHkbA
xpQlQIeIATAXI2BDyhKgQ8QAmI8RsBFlCdAhYgDMyQjYgLIE6BAxAOZlBKxcWQJ0iBgAczMCVqwsAZYW
eSz8Tzg9GMzHCFipsgRYWuT1xwPB/D4cjICVKUuApUXedDwO7IMRsDJlCbC0yHPHw8B+5Ah4bfX3A/3K
EmBpkb89HgX2xQhYibIEWFLkR47HgH0yAlagLAGWEvnm8J/h9CCwP0bAhZUlwFIi7zoeADACLqgsAc4t
kv/e/5vD6QEAI+BCyhLgnCLfGv4mnP7CD19lBFxAWQKcQyT/qf9nw+fD6S/4MDICmpXlVUWeDq8COMp/
0v+x8Bvhr8Jnw+kv8vAwRkCjsqxEvj08G/I/1Pl7O38hnP7EAcBtGQFNyvJU5I3hH8LpTxAALMUIaFCW
KR9++LNw+pMCAB2MgIXV5eHwfcFv1AHAJRkBC7q/OBx+InwxnP4kAMAlGAELufcvDofvCf8bTh8+AFyS
EbCAu39y5//m73/tD8AaGQFndvdPDoc/Oj5kAFgjI+CM7vzhcPjO8OVw+qABYG2MgDO584fD4c+PDxYA
1s4IOIPMK8KXwviAAWCtjIBbyvxUGB8sAKydEXALGf/lPwC2ygi4oYzf5x+ALTMCbiDz8TA+TADYEiPg
mjJ+218AZmAEXENmfIAAsFVGwBVlxocHAFtmBFxBZnxwALB1RsAjZMaHBgAzMAIeIjM+MACYhRHwAJnx
YQHATIyAQmZ8UAAwGyNgkBkfEgDMyAg4kRkfEADMygg4yowPBwBmZgSEzPhgAGB2ux8BmfGhAMAe7HoE
ZMYHAgB7sdsRkBkfBgDsyS5HQGZ8EACwN7sbAZnxIQDAHu1qBGTGBwAAe7WbEZAZPzwA7NkuRkBm/OAA
sHfTj4DM+KEBgMPhQ2HaEZAZPzAAcMe0IyAzflgA4K4pR0Bm/KAAwL2mGwGZ8UMCAPebagRkxg8IANSm
GQGZ8cMBAA+WI+A11VHdksz4wQCAh9v8CMiMHwoAeLRNj4DM+IEAgKvZ7AjIjB8GALi6TY6AzPhBAIDr
2dwIyIwfAgC4vk2NgMz4AQCAm9nMCMiMbx4AuLlNjIDM+MYBgNtZ/QjIjG8aALi9VY+AzPiGAYDzWO0I
yIxvFgA4n1WOgMz4RgGA81rdCMiMbxIAOL9VjYDM+AYBgGWsZgRkxjcHACxnFSMgM74xAGBZFx8BmfFN
AQDLu+gIyIxvCADocbERkBnfDADQ5yIjIDO+EQCgV/sIyIxvAgDo1zoCMuMbAAAuo20EZMYXBwAup2UE
ZMYXBgAua/ERkBlfFAC4vEVHQGZ8QQBgHRYbAZnxxQCA9VhkBGTGFwIA1uXsIyAzvggAsD5nHQGZ8QUA
gHU62wjIjN8cAFivs4yAzPiNAYB1u/UIyIzfFABYv1uNgMz4DQGAbbjxCMiM3wwA2I4bjYDM+I0AgG25
9gjIjN8EANiea42AzPgNAIBt+mC40gjIjD8YANiuK42AzPgDAYBte+QIyIw/CADYvoeOgMz4AwCAOTxw
BGTG/2EAYB45Al5tAADA/vxzeJkBAAD78yfhMQMAAPbn5wwAANif/wpPGQAAsD+/agAAwP58JnxdKL8I
AMzr+0P5BQBgXm8J5RcAgHk9H8ovAADzen8ovwAAzOvFUH4BAJjX50P5BQBgXh8I5RcAgHn9ZSi/AADM
6+2h/AIAMK83hvILAMCc/jv4rYABYGfe4v8ZEADsywvh5QYAAOzLs3n8DQAA2I93h8cNAADYj/eFJ796
/A0AAJjfB8OrT4+/AQAAc8vj/5rx+BsAADCvBx7/lBl/AACwbQ89/ikz/iAAYLseefxTZvyBAMA2Xen4
p8z4gwGA7flQuNLxT5nxGwAA23Kt458y4zcBALbj2sc/ZcZvBABsw42Of8qM3wwAWL8bH/+UGb8hALBu
tzr+KTN+UwBgvW59/FNm/MYAwDqd5finzPjNAYD1OdvxT5nxBQCAdTnr8U+Z8UUAgPU4+/FPmfGFAIB1
WOT4p8z4YgDA5S12/FNmfEEA4LIWPf4pM74oAHA5ix//lBlfGAC4jJbjnzLjiwMA/dqOf8qMbwAA6NV6
/FNmfBMAQJ/2458y4xsBAHpc5PinzPhmAIDlXez4p8z4hgCAZV30+KfM+KYAgOVc/PinzPjGAIBlrOL4
p8z45gCA81vN8U+Z8Q0CAOe1quOfMuObBADOZ3XHP2XGNwoAnMcqj3/KjG8WALi91R7/lBnfMABwO6s+
/ikzvmkA4OZWf/xTZnzjAMDNbOL4p8z45gGA69vM8U+Z8QMAANezqeOfMuOHAACubnPHP2XGDwIAXM0m
j3/KjB8GAHi0zR7/lBk/EADwcJs+/ikzfigA4ME2f/xTZvxgAEAtj/9rq4O6NZnxwwEA95vm+KfM+AEB
gHtNdfxTZvyQAMBd0x3/lBk/KABwx5THP2XGDwsATHz8U2b8wACwdx8O0x7/lBk/NADs2fTHP2XGDw4A
e7WL458y44cHgD3azfFPmfEBAMDe7Or4p8z4EABgT3Z3/FNmfBAAsBe7PP4pMz4MANiD3R7/lBkfCADM
btfHP2XGhwIAM9v98U+Z8cEAwKwc/6PM+HAAYEaO/4nM+IAAYDaO/yAzPiQAmInjX8iMDwoAZuH4P0Bm
fFgAMAPH/yEy4wMDgK1z/B8hMz40ANgyx/8KMuODA4CtcvyvKPNiGB8gAGyN438NmfeH8SECwJY4/teU
eT6MDxIAtsLxv4HMc2F8mACwBY7/DWW+O4wPFADWzvG/hcxj4VNhfLAAsFaO/y3d+cPh8IvHBwoAa+f4
n8GdPxwOLwv/EU4fMACsjeN/Jnf/5HD46ePDBYA1cvzP6N6/OBx+9/iQAWBNHP8zu/cvDodvCH8XTh86
AFyS47+A+4vD4anwF+H04QPAJTj+C6nLw+Hx8NZw+pMAAJ0c/wWV5VdFvje8J5z+hADA0hz/hZXlKPKj
4V3hc+H0JwgAzs3xb1CWDxJ5Ivxg+Jnwy+G3wu8AHP1x+GD4cjj9BR2uyvFvUpYAtxF5OuQ/LLw5fDyc
/gIPD+L4NypLgHOJ5L9Z9I5w+gs9jBz/ZmUJcG6RHw6fDKe/6ENy/C+gLAGWEHl1eCGc/uLPvjn+F1KW
AEuJ/OTxF35w/C+oLAGWFMl/rfj0ELA/jv+FlSXAkiKvDJ8JpweB/XD8V6AsAZYW+YPjMWBfHP+VKEuA
pUWePR4E9sPxX5GyBFha5I3Ho8A+5PF/pvp7gcsoS4ClRb4p+C2D98HxX6GyBOgQ+cTxQDCvjwTHf4XK
EqBD5GPHI8GcHP8VK0uADhEDYF6O/8qVJUCHiAEwJ8d/A8oSoEPEAJiP478RZQnQIWIAzMXx35CyBOgQ
MQDm4fhvTFkCdIgYAHNw/DeoLAE6RAyA7XP8N6osATpEDIBtc/w3rCwBOkQMgO1y/DeuLAE6RAyAbXL8
J1CWAB0iBsD2OP6TKEuADhEDYFsc/4mUJUCHiAGwHY7/ZMoSoEPEANgGx39CZQnQIWIArJ/jP6myBOgQ
MQDWzfGfWFkCdIgYAOvl+E+uLAE6RAyAdXL8d6AsATpEDID1cfx3oiwBOkQMgHVx/HekLAE6RAyA9XD8
d6YsATpEDIB1cPx3qCwBOkQMgMtz/HeqLAE6RAyAy3L8d6wsATpEDIDLcfx3riwBOkQMgMtw/Im/E4oS
oEPEAOjn+PMVZQnQIWIA9HL8+ZqyBOgQMQD6OP7coywBOkQMgB6OP/cpS4AOEQNgeY4/pbIE6BAxAJbl
+PNAZQnQIWIALMfx56HKEqBDxABYhuPPI5UlQIeIAXB+jj9XUpYAHSIGwHk5/lxZWQJ0iBgA5+P4cy1l
CdAhYgCch+PPtZUlQIeIAXB7jj83UpYAHSIGwO04/txYWQJ0iBgAN+f4cytlCdAhYgDcjOPPrZUlQIeI
AXB9jj9nUZYAHSIGwPU4/pxNWQJ0iBgAV+f4c1ZlCdAhYgBczUfD66pnCDdVlgAdIgbAozn+LKIsATpE
DICHc/xZTFkCdIgYAA/m+LOosgToEDEAao4/iytLgA4RA+B+jj8tyhKgQ8QAuJfjT5uyBOgQMQDucvxp
VZYAHSIGwB2OP+3KEqBDxABw/LmQsgToENn7AHD8uZiyBOgQ2fMAcPy5qLIE6BDZ6wBw/Lm4sgToENnj
AHD8WYWyBOgQ2dsAcPxZjbIE6BDZ0wBw/FmVsgToENnLAHD8WZ2yBOgQ2cMAcPxZpbIE6BCZfQA4/qxW
WQJ0iMw8ABx/Vq0sATpEZh0Ajj+rV5YAHSIzDgDHn00oS4AOkdkGgOPPZpQlQIfITAPA8WdTyhKgQ2SW
AeD4szllCdAhMsMAcPzZpLIE6BDZ+gBw/NmssgToENnyAHD82bSyBOgQ2eoAcPzZvLIE6BDZ4gBw/JlC
WQJ0iGxtADj+TKMsATpEtjQAHH+mUpYAHSJbGQCOP9MpS4AOkS0MAMefKZUlQIfI2geA48+0yhKgQ2TN
A8DxZ2plCdDheGRPj+5aOP5MrywBOkT+9Xhw18TxZxfKEqBD5Pnj0V0Lx5/dKEuADpF3Hg/vGjj+7EpZ
AnSI/NLx+F6a48/ulCVAh8gbjgf4khx/dqksATpEHg+fCacHuZPjz26VJUCXyNuOx7ib48+ulSVAl8gr
w+fD6XFemuPP7pUlQKfIrx0PcwfHH0JZAnSKPBH+MZwe6iU4/nBUlgDdIs+EJf8LgY4/nChLgEuIfFf4
dDg93OeQv+XwM9Vrwl6VJcClRL4l/Fs4PeC38e7wZPVasGdlCXBJkafC28MXw+kxv44XwrPhseo1YO/K
EmANIq8Pfxi+EE6P+8O8GH49PF19T+COsgRYk8iT4cfD74f3hk+FL4fPhQ+Hvw9vDT8Qvr76HsC9yhJg
7SKPVz1wNWUJAMytLAGAuZUlADC3sgQA5laWAMDcyhIAmFtZAgBzK0sAYG5lCQDMrSwBgLmVJQAwt7IE
AOZWlgDA3MoSAJhbWQIAcytLAGBuZQkAzK0sAYC5lSUAMLeyBADmVpYAwNzKEgCYW1kCAHMrSwBgbmUJ
AMytLAGAuZUlADC3sgQA5laWAMDcyhIAmFtZAgBzK0sAYG5lCQDMrSwBgLmVJQAwt7IEAOZWlgDA3MoS
AJhbWQIAcytLAGBuZQkAzK0sAYC5lSUAMLeyBADmVpYAwNzKEgCYW1kCADN76fD/J/zUgYLnwZ0AAAAA
SUVORK5CYII=
</value>
</data>
</root>

View File

@ -0,0 +1,347 @@
namespace ProjectAirPlane
{
partial class FormPlaneCollection
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
groupBoxTools = new GroupBox();
panelCompanyTools = new Panel();
buttonAddPlane = new Button();
maskedTextBox = new MaskedTextBox();
buttonRefresh = new Button();
buttonRemovePlane = new Button();
buttonGoToCheck = new Button();
buttonCreateCompany = new Button();
panelStorage = new Panel();
buttonCollectionDel = new Button();
listBoxCollection = new ListBox();
buttonCollectionAdd = new Button();
radioButtonList = new RadioButton();
radioButtonMassive = new RadioButton();
textBoxCollectionName = new TextBox();
labelCollectionName = new Label();
comboBoxSelectorCompany = new ComboBox();
pictureBox = new PictureBox();
menuStrip = new MenuStrip();
файлToolStripMenuItem = new ToolStripMenuItem();
saveToolStripMenuItem = new ToolStripMenuItem();
loadToolStripMenuItem = new ToolStripMenuItem();
saveFileDialog = new SaveFileDialog();
openFileDialog = new OpenFileDialog();
groupBoxTools.SuspendLayout();
panelCompanyTools.SuspendLayout();
panelStorage.SuspendLayout();
((System.ComponentModel.ISupportInitialize)pictureBox).BeginInit();
menuStrip.SuspendLayout();
SuspendLayout();
//
// groupBoxTools
//
groupBoxTools.Controls.Add(panelCompanyTools);
groupBoxTools.Controls.Add(buttonCreateCompany);
groupBoxTools.Controls.Add(panelStorage);
groupBoxTools.Controls.Add(comboBoxSelectorCompany);
groupBoxTools.Dock = DockStyle.Right;
groupBoxTools.Location = new Point(686, 24);
groupBoxTools.Name = "groupBoxTools";
groupBoxTools.Size = new Size(195, 534);
groupBoxTools.TabIndex = 0;
groupBoxTools.TabStop = false;
groupBoxTools.Text = "Инструменты";
//
// panelCompanyTools
//
panelCompanyTools.Controls.Add(buttonAddPlane);
panelCompanyTools.Controls.Add(maskedTextBox);
panelCompanyTools.Controls.Add(buttonRefresh);
panelCompanyTools.Controls.Add(buttonRemovePlane);
panelCompanyTools.Controls.Add(buttonGoToCheck);
panelCompanyTools.Dock = DockStyle.Bottom;
panelCompanyTools.Enabled = false;
panelCompanyTools.Location = new Point(3, 343);
panelCompanyTools.Name = "panelCompanyTools";
panelCompanyTools.Size = new Size(189, 188);
panelCompanyTools.TabIndex = 8;
//
// buttonAddPlane
//
buttonAddPlane.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
buttonAddPlane.Location = new Point(3, 13);
buttonAddPlane.Name = "buttonAddPlane";
buttonAddPlane.Size = new Size(166, 28);
buttonAddPlane.TabIndex = 1;
buttonAddPlane.Text = "Добавление самолёта";
buttonAddPlane.UseVisualStyleBackColor = true;
buttonAddPlane.Click += ButtonAddPlane_Click;
//
// maskedTextBox
//
maskedTextBox.Location = new Point(6, 57);
maskedTextBox.Mask = "00";
maskedTextBox.Name = "maskedTextBox";
maskedTextBox.Size = new Size(166, 23);
maskedTextBox.TabIndex = 3;
maskedTextBox.ValidatingType = typeof(int);
maskedTextBox.MaskInputRejected += MaskedTextBox_MaskInputRejected;
//
// buttonRefresh
//
buttonRefresh.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
buttonRefresh.Location = new Point(6, 156);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(166, 25);
buttonRefresh.TabIndex = 6;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += ButtonRefresh_Click;
//
// buttonRemovePlane
//
buttonRemovePlane.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
buttonRemovePlane.Location = new Point(7, 86);
buttonRemovePlane.Name = "buttonRemovePlane";
buttonRemovePlane.Size = new Size(166, 24);
buttonRemovePlane.TabIndex = 4;
buttonRemovePlane.Text = "Удалить самолёт";
buttonRemovePlane.UseVisualStyleBackColor = true;
buttonRemovePlane.Click += ButtonRemovePlane_Click;
//
// buttonGoToCheck
//
buttonGoToCheck.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
buttonGoToCheck.Location = new Point(6, 125);
buttonGoToCheck.Name = "buttonGoToCheck";
buttonGoToCheck.Size = new Size(166, 25);
buttonGoToCheck.TabIndex = 5;
buttonGoToCheck.Text = "Передать на тесты";
buttonGoToCheck.UseVisualStyleBackColor = true;
buttonGoToCheck.Click += ButtonGoToCheck_Click;
//
// buttonCreateCompany
//
buttonCreateCompany.Location = new Point(6, 314);
buttonCreateCompany.Name = "buttonCreateCompany";
buttonCreateCompany.Size = new Size(177, 23);
buttonCreateCompany.TabIndex = 7;
buttonCreateCompany.Text = "Создать компанию";
buttonCreateCompany.UseVisualStyleBackColor = true;
buttonCreateCompany.Click += ButtonCreateCompany_Click;
//
// panelStorage
//
panelStorage.Controls.Add(buttonCollectionDel);
panelStorage.Controls.Add(listBoxCollection);
panelStorage.Controls.Add(buttonCollectionAdd);
panelStorage.Controls.Add(radioButtonList);
panelStorage.Controls.Add(radioButtonMassive);
panelStorage.Controls.Add(textBoxCollectionName);
panelStorage.Controls.Add(labelCollectionName);
panelStorage.Dock = DockStyle.Top;
panelStorage.Location = new Point(3, 19);
panelStorage.Name = "panelStorage";
panelStorage.Size = new Size(189, 260);
panelStorage.TabIndex = 7;
//
// buttonCollectionDel
//
buttonCollectionDel.Location = new Point(7, 226);
buttonCollectionDel.Name = "buttonCollectionDel";
buttonCollectionDel.Size = new Size(173, 23);
buttonCollectionDel.TabIndex = 6;
buttonCollectionDel.Text = "Удалить коллекцию";
buttonCollectionDel.UseVisualStyleBackColor = true;
buttonCollectionDel.Click += ButtonCollectionDel_Click;
//
// listBoxCollection
//
listBoxCollection.FormattingEnabled = true;
listBoxCollection.ItemHeight = 15;
listBoxCollection.Location = new Point(7, 113);
listBoxCollection.Name = "listBoxCollection";
listBoxCollection.Size = new Size(173, 109);
listBoxCollection.TabIndex = 5;
//
// buttonCollectionAdd
//
buttonCollectionAdd.Location = new Point(7, 81);
buttonCollectionAdd.Name = "buttonCollectionAdd";
buttonCollectionAdd.Size = new Size(174, 25);
buttonCollectionAdd.TabIndex = 4;
buttonCollectionAdd.Text = "Добавить коллекцию";
buttonCollectionAdd.UseVisualStyleBackColor = true;
buttonCollectionAdd.Click += ButtonCollectionAdd_Click;
//
// radioButtonList
//
radioButtonList.AutoSize = true;
radioButtonList.Location = new Point(114, 56);
radioButtonList.Name = "radioButtonList";
radioButtonList.Size = new Size(66, 19);
radioButtonList.TabIndex = 3;
radioButtonList.TabStop = true;
radioButtonList.Text = "Список";
radioButtonList.UseVisualStyleBackColor = true;
//
// radioButtonMassive
//
radioButtonMassive.AutoSize = true;
radioButtonMassive.Location = new Point(6, 56);
radioButtonMassive.Name = "radioButtonMassive";
radioButtonMassive.Size = new Size(67, 19);
radioButtonMassive.TabIndex = 2;
radioButtonMassive.TabStop = true;
radioButtonMassive.Text = "Массив";
radioButtonMassive.UseVisualStyleBackColor = true;
//
// textBoxCollectionName
//
textBoxCollectionName.Location = new Point(3, 27);
textBoxCollectionName.Name = "textBoxCollectionName";
textBoxCollectionName.Size = new Size(181, 23);
textBoxCollectionName.TabIndex = 1;
//
// labelCollectionName
//
labelCollectionName.AutoSize = true;
labelCollectionName.Location = new Point(40, 9);
labelCollectionName.Name = "labelCollectionName";
labelCollectionName.Size = new Size(122, 15);
labelCollectionName.TabIndex = 0;
labelCollectionName.Text = "Название коллекции";
//
// comboBoxSelectorCompany
//
comboBoxSelectorCompany.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
comboBoxSelectorCompany.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxSelectorCompany.FormattingEnabled = true;
comboBoxSelectorCompany.Items.AddRange(new object[] { "Хранилище" });
comboBoxSelectorCompany.Location = new Point(6, 285);
comboBoxSelectorCompany.Name = "comboBoxSelectorCompany";
comboBoxSelectorCompany.Size = new Size(178, 23);
comboBoxSelectorCompany.TabIndex = 0;
comboBoxSelectorCompany.SelectedIndexChanged += ComboBoxSelectorCompany_SelectedIndexChanged;
//
// pictureBox
//
pictureBox.Dock = DockStyle.Fill;
pictureBox.Location = new Point(0, 24);
pictureBox.Name = "pictureBox";
pictureBox.Size = new Size(686, 534);
pictureBox.TabIndex = 1;
pictureBox.TabStop = false;
//
// menuStrip
//
menuStrip.Items.AddRange(new ToolStripItem[] { файлToolStripMenuItem });
menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip";
menuStrip.Size = new Size(881, 24);
menuStrip.TabIndex = 2;
menuStrip.Text = "menuStrip";
//
// файлToolStripMenuItem
//
файлToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { saveToolStripMenuItem, loadToolStripMenuItem });
файлToolStripMenuItem.Name = айлToolStripMenuItem";
файлToolStripMenuItem.Size = new Size(48, 20);
файлToolStripMenuItem.Text = "Файл";
//
// saveToolStripMenuItem
//
saveToolStripMenuItem.Name = "saveToolStripMenuItem";
saveToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.S;
saveToolStripMenuItem.Size = new Size(181, 22);
saveToolStripMenuItem.Text = "Сохранение";
saveToolStripMenuItem.Click += SaveToolStripMenuItem_Click;
//
// loadToolStripMenuItem
//
loadToolStripMenuItem.Name = "loadToolStripMenuItem";
loadToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.L;
loadToolStripMenuItem.Size = new Size(181, 22);
loadToolStripMenuItem.Text = "Загрузка";
loadToolStripMenuItem.Click += LoadToolStripMenuItem_Click;
//
// saveFileDialog
//
saveFileDialog.Filter = "txt file | *.txt";
//
// openFileDialog
//
openFileDialog.Filter = "txt file | *.txt";
//
// FormPlaneCollection
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(881, 558);
Controls.Add(pictureBox);
Controls.Add(groupBoxTools);
Controls.Add(menuStrip);
MainMenuStrip = menuStrip;
Name = "FormPlaneCollection";
Text = "Коллекция самолётов";
groupBoxTools.ResumeLayout(false);
panelCompanyTools.ResumeLayout(false);
panelCompanyTools.PerformLayout();
panelStorage.ResumeLayout(false);
panelStorage.PerformLayout();
((System.ComponentModel.ISupportInitialize)pictureBox).EndInit();
menuStrip.ResumeLayout(false);
menuStrip.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
private GroupBox groupBoxTools;
private ComboBox comboBoxSelectorCompany;
private Button buttonAddPlane;
private PictureBox pictureBox;
private Button buttonRemovePlane;
private MaskedTextBox maskedTextBox;
private Button buttonGoToCheck;
private Button buttonRefresh;
private Panel panelStorage;
private Label labelCollectionName;
private TextBox textBoxCollectionName;
private RadioButton radioButtonMassive;
private RadioButton radioButtonList;
private Button buttonCollectionAdd;
private ListBox listBoxCollection;
private Button buttonCollectionDel;
private Button buttonCreateCompany;
private Panel panelCompanyTools;
private MenuStrip menuStrip;
private ToolStripMenuItem файлToolStripMenuItem;
private ToolStripMenuItem saveToolStripMenuItem;
private ToolStripMenuItem loadToolStripMenuItem;
private SaveFileDialog saveFileDialog;
private OpenFileDialog openFileDialog;
}
}

View File

@ -0,0 +1,288 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ProjectAirPlane.CollectionGenericObjects;
using ProjectAirPlane.Drawnings;
namespace ProjectAirPlane;
/// <summary>
/// Форма работы с компанией и ее коллекцией
/// </summary>
public partial class FormPlaneCollection : Form
{
/// <summary>
/// Хранилише коллекций
/// </summary>
private readonly StorageCollection<DrawningPlane> _storageCollection;
/// <summary>
/// Компания
/// </summary>
private AbstractCompany? _company = null;
/// <summary>
/// Конструктор
/// </summary>
public FormPlaneCollection()
{
InitializeComponent();
_storageCollection = new();
}
/// <summary>
/// Выбор компании
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ComboBoxSelectorCompany_SelectedIndexChanged(object sender, EventArgs e)
{
panelCompanyTools.Enabled = false;
}
private void ButtonAddPlane_Click(object sender, EventArgs e)
{
FormPlaneConfig form = new();
form.AddEvent(SetPlane);
form.Show();
}
/// <summary>
/// Добавление самолёта в коллекцию
/// </summary>
/// <param name="ship"></param>
private void SetPlane(DrawningPlane plane)
{
if (_company == null || plane == null)
{
return;
}
if (_company + plane != -1)
{
MessageBox.Show("Объект добавлен");
pictureBox.Image = _company.Show();
}
else
{
MessageBox.Show("Не удалось добавить объект");
}
}
private void MaskedTextBox_MaskInputRejected(object sender, MaskInputRejectedEventArgs e)
{
}
private void ButtonRemovePlane_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(maskedTextBox.Text) || _company == null)
{
return;
}
if (MessageBox.Show("Удалить объект?", "Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
{
return;
}
int pos = Convert.ToInt32(maskedTextBox.Text);
if (_company - pos != null)
{
MessageBox.Show("Объект удален");
pictureBox.Image = _company.Show();
}
else
{
MessageBox.Show("Не удалось удалить объект");
}
}
private void ButtonGoToCheck_Click(object sender, EventArgs e)
{
if (_company == null)
{
return;
}
DrawningPlane? plane = null;
int counter = 100;
while (plane == null)
{
plane = _company.GetRandomObject();
counter--;
if (counter <= 0)
{
break;
}
}
if (plane == null)
{
return;
}
FormAirPlane form = new()
{
SetPlane = plane
};
form.ShowDialog();
}
private void ButtonRefresh_Click(object sender, EventArgs e)
{
if (_company == null)
{
return;
}
pictureBox.Image = _company.Show();
}
/// <summary>
/// Добавление коллекции
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonCollectionAdd_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxCollectionName.Text) || (!radioButtonList.Checked && !radioButtonMassive.Checked))
{
MessageBox.Show("Не все данные заполнены", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
CollectionType collectionType = CollectionType.None;
if (radioButtonMassive.Checked)
{
collectionType = CollectionType.Massive;
}
else if (radioButtonList.Checked)
{
collectionType = CollectionType.List;
}
_storageCollection.AddCollection(textBoxCollectionName.Text, collectionType);
RerfreshListBoxItems();
}
/// <summary>
/// Обновление списка в listBoxCollection
/// </summary>
private void RerfreshListBoxItems()
{
listBoxCollection.Items.Clear();
for (int i = 0; i < _storageCollection.Keys?.Count; ++i)
{
string? colName = _storageCollection.Keys?[i];
if (!string.IsNullOrEmpty(colName))
{
listBoxCollection.Items.Add(colName);
}
}
}
/// <summary>
/// Удаление коллекции
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonCollectionDel_Click(object sender, EventArgs e)
{
if (listBoxCollection.SelectedIndex < 0 || listBoxCollection.SelectedItem == null)
{
MessageBox.Show("Коллекция не выбрана");
return;
}
if (MessageBox.Show("Удалить коллекцию?", "Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
{
return;
}
_storageCollection.DelCollection(listBoxCollection.SelectedItem.ToString());
RerfreshListBoxItems();
}
/// <summary>
/// Создание компании
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonCreateCompany_Click(object sender, EventArgs e)
{
if (listBoxCollection.SelectedIndex < 0 || listBoxCollection.SelectedItem == null)
{
MessageBox.Show("Коллекция не выбрана");
return;
}
ICollectionGenericObjects<DrawningPlane>? collection = _storageCollection[listBoxCollection.SelectedItem.ToString() ?? string.Empty];
if (collection == null)
{
MessageBox.Show("Коллекция не проинициализирована");
return;
}
switch (comboBoxSelectorCompany.Text)
{
case "Хранилище":
_company = new PlaneSharingService(pictureBox.Width, pictureBox.Height, collection);
break;
}
panelCompanyTools.Enabled = true;
RerfreshListBoxItems();
}
/// <summary>
/// Обработка нажатия "Сохранение"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SaveToolStripMenuItem_Click(object sender, EventArgs e)
{
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
if (_storageCollection.SaveData(saveFileDialog.FileName))
{
MessageBox.Show("Сохранение прошло успешно",
"Результат", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Не сохранилось", "Результат",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
/// <summary>
/// Обработка нажатия "Загрузка"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void LoadToolStripMenuItem_Click(object sender, EventArgs e)
{
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
if (_storageCollection.LoadData(openFileDialog.FileName))
{
MessageBox.Show("Загрузка прошла успешно",
"Результат", MessageBoxButtons.OK, MessageBoxIcon.Information);
RerfreshListBoxItems();
}
else
{
MessageBox.Show("Не сохранилось", "Результат",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="menuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="saveFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>126, 17</value>
</metadata>
<metadata name="openFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>261, 17</value>
</metadata>
</root>

View File

@ -0,0 +1,357 @@
namespace ProjectAirPlane
{
partial class FormPlaneConfig
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
groupBoxConfig = new GroupBox();
groupBoxColors = new GroupBox();
panelPurple = new Panel();
panelYellow = new Panel();
panelBlack = new Panel();
panelBlue = new Panel();
panelGray = new Panel();
panelWhite = new Panel();
panelGreen = new Panel();
panelRed = new Panel();
checkBoxDopBak = new CheckBox();
checkBoxRadar = new CheckBox();
numericUpDownWeight = new NumericUpDown();
labelWeight = new Label();
numericUpDownSpeed = new NumericUpDown();
labelSpeed = new Label();
labelModifiedObject = new Label();
labelSimpleObject = new Label();
pictureBoxObject = new PictureBox();
buttonAdd = new Button();
buttonCancel = new Button();
panelObject = new Panel();
labelAdditionalColor = new Label();
labelBodyColor = new Label();
groupBoxConfig.SuspendLayout();
groupBoxColors.SuspendLayout();
((System.ComponentModel.ISupportInitialize)numericUpDownWeight).BeginInit();
((System.ComponentModel.ISupportInitialize)numericUpDownSpeed).BeginInit();
((System.ComponentModel.ISupportInitialize)pictureBoxObject).BeginInit();
panelObject.SuspendLayout();
SuspendLayout();
//
// groupBoxConfig
//
groupBoxConfig.Controls.Add(groupBoxColors);
groupBoxConfig.Controls.Add(checkBoxDopBak);
groupBoxConfig.Controls.Add(checkBoxRadar);
groupBoxConfig.Controls.Add(numericUpDownWeight);
groupBoxConfig.Controls.Add(labelWeight);
groupBoxConfig.Controls.Add(numericUpDownSpeed);
groupBoxConfig.Controls.Add(labelSpeed);
groupBoxConfig.Controls.Add(labelModifiedObject);
groupBoxConfig.Controls.Add(labelSimpleObject);
groupBoxConfig.Dock = DockStyle.Left;
groupBoxConfig.Location = new Point(0, 0);
groupBoxConfig.Name = "groupBoxConfig";
groupBoxConfig.Size = new Size(491, 301);
groupBoxConfig.TabIndex = 0;
groupBoxConfig.TabStop = false;
groupBoxConfig.Text = "Параметры";
//
// groupBoxColors
//
groupBoxColors.Controls.Add(panelPurple);
groupBoxColors.Controls.Add(panelYellow);
groupBoxColors.Controls.Add(panelBlack);
groupBoxColors.Controls.Add(panelBlue);
groupBoxColors.Controls.Add(panelGray);
groupBoxColors.Controls.Add(panelWhite);
groupBoxColors.Controls.Add(panelGreen);
groupBoxColors.Controls.Add(panelRed);
groupBoxColors.Location = new Point(224, 13);
groupBoxColors.Name = "groupBoxColors";
groupBoxColors.Size = new Size(249, 127);
groupBoxColors.TabIndex = 9;
groupBoxColors.TabStop = false;
groupBoxColors.Text = "Цвета";
//
// panelPurple
//
panelPurple.BackColor = Color.Purple;
panelPurple.Location = new Point(194, 72);
panelPurple.Name = "panelPurple";
panelPurple.Size = new Size(31, 30);
panelPurple.TabIndex = 3;
//
// panelYellow
//
panelYellow.BackColor = Color.Yellow;
panelYellow.Location = new Point(194, 22);
panelYellow.Name = "panelYellow";
panelYellow.Size = new Size(31, 30);
panelYellow.TabIndex = 1;
//
// panelBlack
//
panelBlack.BackColor = Color.Black;
panelBlack.Location = new Point(136, 72);
panelBlack.Name = "panelBlack";
panelBlack.Size = new Size(31, 30);
panelBlack.TabIndex = 4;
//
// panelBlue
//
panelBlue.BackColor = Color.Blue;
panelBlue.Location = new Point(136, 22);
panelBlue.Name = "panelBlue";
panelBlue.Size = new Size(31, 30);
panelBlue.TabIndex = 1;
//
// panelGray
//
panelGray.BackColor = Color.Gray;
panelGray.Location = new Point(78, 72);
panelGray.Name = "panelGray";
panelGray.Size = new Size(31, 30);
panelGray.TabIndex = 5;
//
// panelWhite
//
panelWhite.BackColor = Color.White;
panelWhite.Location = new Point(18, 72);
panelWhite.Name = "panelWhite";
panelWhite.Size = new Size(31, 30);
panelWhite.TabIndex = 2;
//
// panelGreen
//
panelGreen.BackColor = Color.Green;
panelGreen.Location = new Point(78, 22);
panelGreen.Name = "panelGreen";
panelGreen.Size = new Size(31, 30);
panelGreen.TabIndex = 1;
//
// panelRed
//
panelRed.BackColor = Color.Red;
panelRed.Location = new Point(18, 22);
panelRed.Name = "panelRed";
panelRed.Size = new Size(31, 30);
panelRed.TabIndex = 0;
//
// checkBoxDopBak
//
checkBoxDopBak.AutoSize = true;
checkBoxDopBak.Location = new Point(12, 121);
checkBoxDopBak.Name = "checkBoxDopBak";
checkBoxDopBak.Size = new Size(177, 19);
checkBoxDopBak.TabIndex = 7;
checkBoxDopBak.Text = "Признак наличия доп. бака";
checkBoxDopBak.UseVisualStyleBackColor = true;
//
// checkBoxRadar
//
checkBoxRadar.AutoSize = true;
checkBoxRadar.Location = new Point(12, 96);
checkBoxRadar.Name = "checkBoxRadar";
checkBoxRadar.Size = new Size(164, 19);
checkBoxRadar.TabIndex = 6;
checkBoxRadar.Text = "Признак наличия радара";
checkBoxRadar.UseVisualStyleBackColor = true;
//
// numericUpDownWeight
//
numericUpDownWeight.Location = new Point(71, 50);
numericUpDownWeight.Maximum = new decimal(new int[] { 1000, 0, 0, 0 });
numericUpDownWeight.Minimum = new decimal(new int[] { 100, 0, 0, 0 });
numericUpDownWeight.Name = "numericUpDownWeight";
numericUpDownWeight.Size = new Size(98, 23);
numericUpDownWeight.TabIndex = 5;
numericUpDownWeight.Value = new decimal(new int[] { 100, 0, 0, 0 });
//
// labelWeight
//
labelWeight.AutoSize = true;
labelWeight.Location = new Point(12, 50);
labelWeight.Name = "labelWeight";
labelWeight.Size = new Size(26, 15);
labelWeight.TabIndex = 4;
labelWeight.Text = "Вес";
//
// numericUpDownSpeed
//
numericUpDownSpeed.Location = new Point(71, 17);
numericUpDownSpeed.Maximum = new decimal(new int[] { 1000, 0, 0, 0 });
numericUpDownSpeed.Minimum = new decimal(new int[] { 100, 0, 0, 0 });
numericUpDownSpeed.Name = "numericUpDownSpeed";
numericUpDownSpeed.Size = new Size(98, 23);
numericUpDownSpeed.TabIndex = 3;
numericUpDownSpeed.Value = new decimal(new int[] { 100, 0, 0, 0 });
//
// labelSpeed
//
labelSpeed.AutoSize = true;
labelSpeed.Location = new Point(6, 19);
labelSpeed.Name = "labelSpeed";
labelSpeed.Size = new Size(59, 15);
labelSpeed.TabIndex = 2;
labelSpeed.Text = "Скорость";
//
// labelModifiedObject
//
labelModifiedObject.BorderStyle = BorderStyle.FixedSingle;
labelModifiedObject.Location = new Point(373, 146);
labelModifiedObject.Name = "labelModifiedObject";
labelModifiedObject.Size = new Size(100, 23);
labelModifiedObject.TabIndex = 1;
labelModifiedObject.Text = "Продвинутый";
labelModifiedObject.TextAlign = ContentAlignment.MiddleCenter;
labelModifiedObject.MouseDown += LabelObject_MouseDown;
//
// labelSimpleObject
//
labelSimpleObject.BorderStyle = BorderStyle.FixedSingle;
labelSimpleObject.Location = new Point(242, 146);
labelSimpleObject.Name = "labelSimpleObject";
labelSimpleObject.Size = new Size(100, 23);
labelSimpleObject.TabIndex = 0;
labelSimpleObject.Text = "Простой";
labelSimpleObject.TextAlign = ContentAlignment.MiddleCenter;
labelSimpleObject.MouseDown += LabelObject_MouseDown;
//
// pictureBoxObject
//
pictureBoxObject.Location = new Point(20, 48);
pictureBoxObject.Name = "pictureBoxObject";
pictureBoxObject.Size = new Size(306, 149);
pictureBoxObject.TabIndex = 1;
pictureBoxObject.TabStop = false;
//
// buttonAdd
//
buttonAdd.Location = new Point(554, 250);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(75, 23);
buttonAdd.TabIndex = 2;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(721, 250);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(75, 23);
buttonCancel.TabIndex = 3;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
//
// panelObject
//
panelObject.AllowDrop = true;
panelObject.Controls.Add(labelAdditionalColor);
panelObject.Controls.Add(labelBodyColor);
panelObject.Controls.Add(pictureBoxObject);
panelObject.Location = new Point(497, 17);
panelObject.Name = "panelObject";
panelObject.Size = new Size(344, 200);
panelObject.TabIndex = 4;
panelObject.DragDrop += PanelObject_DragDrop;
panelObject.DragEnter += PanelObject_DragEnter;
//
// labelAdditionalColor
//
labelAdditionalColor.AllowDrop = true;
labelAdditionalColor.BorderStyle = BorderStyle.FixedSingle;
labelAdditionalColor.Location = new Point(226, 18);
labelAdditionalColor.Name = "labelAdditionalColor";
labelAdditionalColor.Size = new Size(100, 23);
labelAdditionalColor.TabIndex = 11;
labelAdditionalColor.Text = "Доп. цвет";
labelAdditionalColor.TextAlign = ContentAlignment.MiddleCenter;
labelAdditionalColor.DragDrop += LabelAdditionalColor_DragDrop;
labelAdditionalColor.DragEnter += LabelAdditionalColor_DragEnter;
//
// labelBodyColor
//
labelBodyColor.AllowDrop = true;
labelBodyColor.BorderStyle = BorderStyle.FixedSingle;
labelBodyColor.Location = new Point(20, 18);
labelBodyColor.Name = "labelBodyColor";
labelBodyColor.Size = new Size(100, 23);
labelBodyColor.TabIndex = 10;
labelBodyColor.Text = "Цвет";
labelBodyColor.TextAlign = ContentAlignment.MiddleCenter;
labelBodyColor.DragDrop += LabelBodyColor_DragDrop;
labelBodyColor.DragEnter += LabelBodyColor_DragEnter;
//
// FormPlaneConfig
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(869, 301);
Controls.Add(panelObject);
Controls.Add(buttonCancel);
Controls.Add(buttonAdd);
Controls.Add(groupBoxConfig);
Name = "FormPlaneConfig";
Text = "FormPlaneConfig";
groupBoxConfig.ResumeLayout(false);
groupBoxConfig.PerformLayout();
groupBoxColors.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)numericUpDownWeight).EndInit();
((System.ComponentModel.ISupportInitialize)numericUpDownSpeed).EndInit();
((System.ComponentModel.ISupportInitialize)pictureBoxObject).EndInit();
panelObject.ResumeLayout(false);
ResumeLayout(false);
}
#endregion
private GroupBox groupBoxConfig;
private Label labelSimpleObject;
private Label labelModifiedObject;
private Label labelSpeed;
private NumericUpDown numericUpDownSpeed;
private Label labelWeight;
private NumericUpDown numericUpDownWeight;
private CheckBox checkBoxDopBak;
private CheckBox checkBoxRadar;
private GroupBox groupBoxColors;
private Panel panelRed;
private Panel panelYellow;
private Panel panelBlue;
private Panel panelGreen;
private Panel panelPurple;
private Panel panelBlack;
private Panel panelGray;
private Panel panelWhite;
private PictureBox pictureBoxObject;
private Button buttonAdd;
private Button buttonCancel;
private Panel panelObject;
private Label labelBodyColor;
private Label labelAdditionalColor;
}
}

View File

@ -0,0 +1,174 @@

using ProjectAirPlane.Drawnings;
using ProjectAirPlane.Entites;
namespace ProjectAirPlane;
/// <summary>
/// Форма конфигурации объекта
/// </summary>
public partial class FormPlaneConfig : Form
{
/// <summary>
/// Объект - прорисовка самолёта
/// </summary>
private DrawningPlane? _plane;
/// <summary>
/// Событие для передачи объекта
/// </summary>
private event PlaneDelegate? PlaneDelegate;
/// <summary>
/// Конструктор
/// </summary>
public FormPlaneConfig()
{
InitializeComponent();
panelRed.MouseDown += Panel_MouseDown;
panelGreen.MouseDown += Panel_MouseDown;
panelBlue.MouseDown += Panel_MouseDown;
panelYellow.MouseDown += Panel_MouseDown;
panelWhite.MouseDown += Panel_MouseDown;
panelGray.MouseDown += Panel_MouseDown;
panelBlack.MouseDown += Panel_MouseDown;
panelPurple.MouseDown += Panel_MouseDown;
// TODO buttonCancel.Click привязать анонимный метод через lambda с закрытием формы
buttonCancel.Click += (sender, e) => Close();
}
/// <summary>
/// Привязка внешнего метода к событию
/// </summary>
/// <param name="boatDelegate"></param>
public void AddEvent(PlaneDelegate planeDelegate)
{
PlaneDelegate += planeDelegate;
}
/// <summary>
/// Прорисовка объекта
/// </summary>
private void DrawObject()
{
Bitmap bmp = new(pictureBoxObject.Width, pictureBoxObject.Height);
Graphics gr = Graphics.FromImage(bmp);
_plane?.SetPictureSize(pictureBoxObject.Width, pictureBoxObject.Height);
_plane?.SetPosition(80, 60);
_plane?.DrawTransport(gr);
pictureBoxObject.Image = bmp;
}
/// <summary>
/// Передаем информацию при нажатии на Label
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void LabelObject_MouseDown(object sender, MouseEventArgs e)
{
(sender as Label)?.DoDragDrop((sender as Label)?.Name ?? string.Empty, DragDropEffects.Move | DragDropEffects.Copy);
}
/// <summary>
/// Проверка получаемой информации (ее типа на соответствие требуемому)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PanelObject_DragEnter(object sender, DragEventArgs e)
{
e.Effect = e.Data?.GetDataPresent(DataFormats.Text) ?? false ? DragDropEffects.Copy : DragDropEffects.None;
}
/// <summary>
/// Действия при приеме перетаскиваемой информации
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PanelObject_DragDrop(object sender, DragEventArgs e)
{
switch (e.Data?.GetData(DataFormats.Text)?.ToString())
{
case "labelSimpleObject":
_plane = new DrawningPlane((int)numericUpDownSpeed.Value, (double)numericUpDownWeight.Value, Color.White);
break;
case "labelModifiedObject":
_plane = new DrawningAirPlane((int)numericUpDownSpeed.Value, (double)numericUpDownWeight.Value, Color.White,
Color.Black, checkBoxRadar.Checked, checkBoxDopBak.Checked);
break;
}
DrawObject();
}
/// <summary>
/// Передаем информацию при нажатии на Panel
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Panel_MouseDown(object? sender, MouseEventArgs e)
{
// TODO отправка цвета в Drag&Drop
(sender as Control)?.DoDragDrop((sender as Control).BackColor, DragDropEffects.Move | DragDropEffects.Copy);
}
// TODO Реализовать логику смены цветов: основного и дополнительного (для продвинутого объекта)
private void LabelBodyColor_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(Color)))
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
private void LabelBodyColor_DragDrop(object sender, DragEventArgs e)
{
if (_plane != null)
{
_plane.EntityPlane?.SetBodyColor((Color)e.Data.GetData(typeof(Color)));
DrawObject();
}
}
private void LabelAdditionalColor_DragEnter(object sender, DragEventArgs e)
{
if (_plane is DrawningAirPlane)
{
if (e.Data.GetDataPresent(typeof(Color)))
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
}
private void LabelAdditionalColor_DragDrop(object sender, DragEventArgs e)
{
if (_plane.EntityPlane is EntityAirPlane _airplane)
{
_airplane.SetAdditionalColor((Color)e.Data.GetData(typeof(Color)));
}
DrawObject();
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
if (_plane != null)
{
PlaneDelegate?.Invoke(_plane);
Close();
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,139 @@
namespace ProjectAirPlane.MovementStrategy;
/// <summary>
/// Класс-стратегия перемещения объекта
/// </summary>
public abstract class AbstractStrategy
{
/// <summary>
/// Перемещаемый объект
/// </summary>
private IMoveableObject? _moveableObject;
/// <summary>
/// Статус перемещения
/// </summary>
private StrategyStatus _state = StrategyStatus.NotInit;
/// <summary>
/// Ширина поля
/// </summary>
protected int FieldWidth { get; private set; }
/// <summary>
/// Высота поля
/// </summary>
protected int FieldHeight { get; private set; }
/// <summary>
/// Статус перемещения
/// </summary>
public StrategyStatus GetStatus() { return _state; }
/// <summary>
/// Установка данных
/// </summary>
/// <param name="moveableObject">Перемещаемый объект</param>
/// <param name="width">Ширина поля</param>
/// <param name="height">Высота поля</param>
public void SetData(IMoveableObject moveableObject, int width, int height)
{
if (moveableObject == null)
{
_state = StrategyStatus.NotInit;
return;
}
_state = StrategyStatus.InProgress;
_moveableObject = moveableObject;
FieldWidth = width;
FieldHeight = height;
}
/// <summary>
/// Шаг перемещения
/// </summary>
public void MakeStep()
{
if (_state != StrategyStatus.InProgress)
{
return;
}
if (IsTargetDestinaion())
{
_state = StrategyStatus.Finish;
return;
}
MoveToTarget();
}
/// <summary>
/// Перемещение влево
/// </summary>
/// <returns>Результат перемещения (true - удалось переместиться, false - неудача)</returns>
protected bool MoveLeft() => MoveTo(MovementDirection.Left);
/// <summary>
/// Перемещение вправо
/// </summary>
/// <returns>Результат перемещения (true - удалось переместиться, false - неудача)</returns>
protected bool MoveRight() => MoveTo(MovementDirection.Right);
/// <summary>
/// Перемещение вверх
/// </summary>
/// <returns>Результат перемещения (true - удалось переместиться, false - неудача)</returns>
protected bool MoveUp() => MoveTo(MovementDirection.Up);
/// <summary>
/// Перемещение вниз
/// </summary>
/// <returns>Результат перемещения (true - удалось переместиться, false - неудача)</returns>
protected bool MoveDown() => MoveTo(MovementDirection.Down);
/// <summary>
/// Параметры объекта
/// </summary>
protected ObjectParameters? GetObjectParameters => _moveableObject?.GetObjectPosition;
/// <summary>
/// Шаг объекта
/// </summary>
/// <returns></returns>
protected int? GetStep()
{
if (_state != StrategyStatus.InProgress)
{
return null;
}
return _moveableObject?.GetStep;
}
/// <summary>
/// Перемещение к цели
/// </summary>
protected abstract void MoveToTarget();
/// <summary>
/// Достигнута ли цель
/// </summary>
/// <returns></returns>
protected abstract bool IsTargetDestinaion();
/// <summary>
/// Попытка перемещения в требуемом направлении
/// </summary>
/// <param name="movementDirection">Направление</param>
/// <returns>Результат попытки (true - удалось переместиться, false - неудача)</returns>
private bool MoveTo(MovementDirection movementDirection)
{
if (_state != StrategyStatus.InProgress)
{
return false;
}
return _moveableObject?.TryMoveObject(movementDirection) ?? false;
}
}

View File

@ -0,0 +1,26 @@
namespace ProjectAirPlane.MovementStrategy;
/// <summary>
/// Интерфейс для работы с перемещаемым объектом
/// </summary>
public interface IMoveableObject
{
/// <summary>
/// Получение координаты объекта
/// </summary>
ObjectParameters? GetObjectPosition { get; }
/// <summary>
/// Шаг объекта
/// </summary>
int GetStep { get; }
/// <summary>
/// Попытка переместить объект в указанном направлении
/// </summary>
/// <param name="direction">Направление</param>
/// <returns>true - объект перемещен, false - перемещение невозможно</returns>
bool TryMoveObject(MovementDirection direction);
protected void Move();
}

View File

@ -0,0 +1,31 @@
namespace ProjectAirPlane.MovementStrategy;
public class MoveToBorder : AbstractStrategy
{
protected override bool IsTargetDestinaion()
{
ObjectParameters? objParams = GetObjectParameters;
if (objParams == null) return false;
return objParams.RightBorder + GetStep() >= FieldWidth
&& objParams.DownBorder + GetStep() >= FieldHeight;
}
protected override void MoveToTarget()
{
ObjectParameters? objParams = GetObjectParameters;
if (objParams == null) return;
int diffX = objParams.LeftBorder - FieldWidth;
if (Math.Abs(diffX) > GetStep())
{
MoveRight();
}
int diffY = objParams.DownBorder - FieldHeight;
if (Math.Abs(diffY) > GetStep())
{
MoveDown();
}
}
}

View File

@ -0,0 +1,52 @@

namespace ProjectAirPlane.MovementStrategy;
/// <summary>
/// Стратегия перемещения объекта в центр экрана
/// </summary>
public class MoveToCenter : AbstractStrategy
{
protected override bool IsTargetDestinaion()
{
ObjectParameters? objParams = GetObjectParameters;
if (objParams == null)
{
return false;
}
return objParams.ObjectMiddleHorizontal - GetStep() <= FieldWidth / 2 && objParams.ObjectMiddleHorizontal + GetStep() >= FieldWidth / 2 &&
objParams.ObjectMiddleVertical - GetStep() <= FieldHeight / 2 && objParams.ObjectMiddleVertical + GetStep() >= FieldHeight / 2;
}
protected override void MoveToTarget()
{
ObjectParameters? objParams = GetObjectParameters;
if (objParams == null)
{
return;
}
int diffX = objParams.ObjectMiddleHorizontal - FieldWidth / 2;
if (Math.Abs(diffX) > GetStep())
{
if (diffX > 0)
{
MoveLeft();
}
else
{
MoveRight();
}
}
int diffY = objParams.ObjectMiddleVertical - FieldHeight / 2;
if (Math.Abs(diffY) > GetStep())
{
if (diffY > 0)
{
MoveUp();
}
else
{
MoveDown();
}
}
}
}

View File

@ -0,0 +1,66 @@
using ProjectAirPlane.Drawnings;
namespace ProjectAirPlane.MovementStrategy;
public class MoveablePlane : IMoveableObject
{
/// <summary>
/// Поле-объект класса DrawningPlane или его наследника
/// </summary>
private readonly DrawningPlane? _plane = null;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="plane">Объект класса DrawningPlane</param>
public MoveablePlane(DrawningPlane plane)
{
_plane = plane;
}
public ObjectParameters? GetObjectPosition
{
get
{
if (_plane == null || _plane.EntityPlane == null || !_plane.GetPosX.HasValue || !_plane.GetPosY.HasValue)
{
return null;
}
return new ObjectParameters(_plane.GetPosX.Value, _plane.GetPosY.Value, _plane.GetWidth, _plane.GetHeight);
}
}
public int GetStep => (int)(_plane?.EntityPlane?.Step ?? 0);
public bool TryMoveObject(MovementDirection direction)
{
if (_plane == null || _plane.EntityPlane == null)
{
return false;
}
return _plane.MoveTransport(GetDirectionType(direction));
}
/// <summary>
/// Конвертация из MovementDirection в DirectionType
/// </summary>
/// <param name="direction">MovementDirection</param>
/// <returns>DirectionType</returns>
private static DirectionType GetDirectionType(MovementDirection direction)
{
return direction switch
{
MovementDirection.Left => DirectionType.Left,
MovementDirection.Right => DirectionType.Right,
MovementDirection.Up => DirectionType.Up,
MovementDirection.Down => DirectionType.Down,
_ => DirectionType.Unknow,
};
}
void IMoveableObject.Move()
{
throw new NotImplementedException();
}
}

View File

@ -0,0 +1,28 @@
namespace ProjectAirPlane.MovementStrategy;
/// <summary>
/// Направление перемещения
/// </summary>
public enum MovementDirection
{
/// <summary>
/// Вверх
/// </summary>
Up = 1,
/// <summary>
/// Вниз
/// </summary>
Down = 2,
/// <summary>
/// Влево
/// </summary>
Left = 3,
/// <summary>
/// Вправо
/// </summary>
Right = 4
}

View File

@ -0,0 +1,71 @@
namespace ProjectAirPlane.MovementStrategy;
/// <summary>
/// Параметры-координаты объекта
/// </summary>
public class ObjectParameters
{
/// <summary>
/// Координата X
/// </summary>
private readonly int _x;
/// <summary>
/// Координата Y
/// </summary>
private readonly int _y;
/// <summary>
/// Ширина объекта
/// </summary>
private readonly int _width;
/// <summary>
/// Высота объекта
/// </summary>
private readonly int _height;
/// <summary>
/// Левая граница
/// </summary>
public int LeftBorder => _x;
/// <summary>
/// Верхняя граница
/// </summary>
public int TopBorder => _y;
/// <summary>
/// Правая граница
/// </summary>
public int RightBorder => _x + _width;
/// <summary>
/// Нижняя граница
/// </summary>
public int DownBorder => _y + _height;
/// <summary>
/// Середина объекта
/// </summary>
public int ObjectMiddleHorizontal => _x + _width / 2;
/// <summary>
/// Середина объекта
/// </summary>
public int ObjectMiddleVertical => _y + _height / 2;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="x">Координата X</param>
/// <param name="y">Координата Y</param>
/// <param name="width">Ширина объекта</param>
/// <param name="height">Высота объекта</param>
public ObjectParameters(int x, int y, int width, int height)
{
_x = x;
_y = y;
_width = width;
_height = height;
}
}

View File

@ -0,0 +1,22 @@
namespace ProjectAirPlane.MovementStrategy;
/// <summary>
/// Статус выполнения операции перемещения
/// </summary>
public enum StrategyStatus
{
/// <summary>
/// Все готово к началу
/// </summary>
NotInit,
/// <summary>
/// Выполняется
/// </summary>
InProgress,
/// <summary>
/// Завершено
/// </summary>
Finish
}

View File

@ -0,0 +1,11 @@

using ProjectAirPlane.Drawnings;
namespace ProjectAirPlane;
/// <summary>
/// Делегат передачи объекта класса-прорисовки
/// </summary>
/// <param name="ship"></param>
public delegate void PlaneDelegate(DrawningPlane plane);

View File

@ -11,7 +11,8 @@ namespace ProjectAirPlane
// To customize application configuration such as set high DPI settings or default font, // To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration. // see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize(); ApplicationConfiguration.Initialize();
Application.Run(new Form1()); Application.Run(new FormPlaneCollection());
} }
} }
} }

View File

@ -8,4 +8,19 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Этот код создан программой.
// Исполняемая версия:4.0.30319.42000
//
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
// повторной генерации кода.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ProjectAirPlane.Properties {
using System;
/// <summary>
/// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д.
/// </summary>
// Этот класс создан автоматически классом StronglyTypedResourceBuilder
// с помощью такого средства, как ResGen или Visual Studio.
// Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen
// с параметром /str или перестройте свой проект VS.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ProjectAirPlane.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Перезаписывает свойство CurrentUICulture текущего потока для всех
/// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB