Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
oop7.docx
Скачиваний:
3
Добавлен:
07.04.2025
Размер:
99.49 Кб
Скачать

Министерство науки и высшего образования Российской Федерации

Федеральное государственное бюджетное

Образовательное учреждение высшего образования

«Уфимский университет науки и технологий»

Факультет информатики и робототехники

Кафедра ВМиК

Отчет по лабораторной работе № 7

по дисциплине «Объектно-ориентированное программирование»

Выполнил:

Студент группы ПРО-232Б Э. А. Ихсанова

Проверил:

Доцент кафедры ВМИК В. А. Котельников

Уфа 2023

Цель работы

Изучение методов группировки, сохранения данных, продолжение изучения работы с классами.

Задание

  • Группировка, разгруппировка объектов и групп объектов (сгруппированные объекты изменяются только совместно). Реализация группировки объектов должна быть выполнена с помощью паттерна Composite:

    • выделение нескольких объектов в рабочей области и их группировка (с изъятием из хранилища и помещением в специальный объект класса Group, который затем обратно помещается в хранилище);

    • группа ведет себя как единый объект: перемещается, сохраняет относительное положение входящих в нее объектов, не выходит за границы;

    • в группу могут входить другие группы, и т.д.

    • класс группы не должен зависеть от классов конкретных объектов (или зависеть от других объектов, которые, в свою очередь, зависят от классов конкретных объектов).

  • Реализация сохранения и восстановления хранилища из Л.Р.3 с помощью паттерна Abstract Factory или Factory Method:

    • сохранение всех объектов хранилища в (человеко-читаемый) текстовый файл

    • восстановление всех объектов хранилища из текстового файла

  • Факультативно:

    • манипуляции объектами не только с клавиатуры, но и с мыши

    • реализация команд пользовательского интерфейса с помощью паттерна Command (с возможностью функциональности «undo» - отмены последовательности операций)

    • команды пользовательского интерфейса и типы объектов создаются с помощью подключаемых динамических библиотек (DLL)

Ход работы

Лабораторная построена на основе ЛР 6, дополняет и расширяет ее возможности. Появляется возможность группирования объектов, а также сохранения и загрузки.

Рисунок 1 Скриншот работы программы

Вывод

По ходу выполнения работы были изучены методы группировки, чтения и записи массивов в файлы.

Ссылка на GitHub[branch oop7v2]: https://github.com/eikhovna/oop6

Приложение 1

Form1.cs:

using System;

using System.Drawing.Drawing2D;

using System.Windows.Forms.VisualStyles;

using static oop6.Form1;

using System.Drawing.Printing;

using System.Security.Policy;

using System.Text;

using System.Collections.Generic;

using System.Drawing;

using System.Windows.Forms;

using static System.Windows.Forms.VisualStyles.VisualStyleElement.Button;

using static System.Collections.Specialized.BitVector32;

using System.IO;

using System.Linq;

using System.Runtime.CompilerServices;

namespace oop6

{

public partial class Form1 : Form

{

SavedData savedData = new SavedData();

SaverLoader loader = new SaverLoader();

private List<CFigure> figures = new List<CFigure>(); // Лист для хранения всех фигур

public int objectSize = 30;

public bool Cntrl;

Color color = Color.Khaki;

Color hotPink = Color.HotPink;

Color white = Color.White;

Color purple = Color.Purple;

Color black = Color.Black;

int colorIndex = 0;

int selectedFigure = 0;

public Form1()

{

InitializeComponent();

}

private void Form1_Load(object sender, EventArgs e)

{

foreach (Control control in this.Controls)

{

control.PreviewKeyDown += new PreviewKeyDownEventHandler(control_PreviewKeyDown);

}

}

private void Form1_Paint(object sender, PaintEventArgs e)// Метод отрисовки кругов

{

e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; // Сглаживание

foreach (CFigure figure in figures)

{

figure.SelfDraw(e.Graphics); // Метод круга для отрисовки самого себя

}

}

private void Form1_MouseClick(object sender, MouseEventArgs e)

{

if (!Cntrl)//на нажат cntl

{

foreach (CFigure figure in figures) // снятие выделения со всех объектов

{

figure.setCondition(false);

}

switch (selectedFigure)

{

case 0:

CCircle newcircle = new CCircle(e.X, e.Y, objectSize, color);

newcircle.setCondition(true);

figures.Add(newcircle);

newcircle.observers += new System.EventHandler(this.check_size);

newcircle.returnFigure();

break;

case 1:

CSquare newsquare = new CSquare(e.X, e.Y, objectSize, color);

newsquare.setCondition(true);

figures.Add((newsquare));

newsquare.observers += new System.EventHandler(this.check_size);

newsquare.returnFigure();

break;

case 2:

CTriangle newtriangle = new CTriangle(e.X, e.Y, objectSize, color);

newtriangle.setCondition(true);

figures.Add((newtriangle));

newtriangle.observers += new System.EventHandler(this.check_size);

newtriangle.returnFigure();

break;

case 3:

CSection newsection = new CSection(e.X, e.Y, objectSize, color);

newsection.setCondition(true);

figures.Add((newsection));

newsection.observers += new System.EventHandler(this.check_size);

newsection.returnFigure();

break;

}

Refresh();

}

else if (Cntrl) // Выделение кругов, если зажат cntrl

{

foreach (CFigure figure in figures)

{

if (figure.MouseCheck(e))

{

figure.setCondition(true);

break;

}

}

Refresh();

}

}

public void check_size(object sender, EventArgs e)

{

int x = (sender as CFigure).coords.X;

int y = (sender as CFigure).coords.Y;

int rad = (sender as CFigure).rad;

if (x + rad >= this.ClientSize.Width)

(sender as CFigure).coords.X = this.ClientSize.Width - rad;

else if (x - rad <= 0)

(sender as CFigure).coords.X = rad;

if (y + rad >= this.ClientSize.Height)

(sender as CFigure).coords.Y = this.ClientSize.Height - rad;

else if (y - rad <= 0)

(sender as CFigure).coords.Y = rad;

}

private void Form1_KeyUp(object sender, KeyEventArgs e)// Отжатие кнопки

{

checkBox1.Checked = false;

}

private void Form1_KeyDown(object sender, KeyEventArgs e)// Нажатие кнопок delete и ctrl

{

if (Control.ModifierKeys == Keys.Control)

{

checkBox1.Checked = true;

}

else if (e.KeyCode == Keys.Delete)

{

DelFigures();

}

else if (e.KeyCode == Keys.Up)

{

foreach (CFigure figure in figures)

{

figure.MoveUp(this);

}

Refresh();

}

else if (e.KeyCode == Keys.Down)

{

foreach (CFigure figure in figures)

{

figure.MoveDown(this);

}

Refresh();

}

else if (e.KeyCode == Keys.Left)

{

foreach (CFigure figure in figures)

{

figure.MoveLeft(this);

}

Refresh();

}

else if (e.KeyCode == Keys.Right)

{

foreach (CFigure figure in figures)

{

figure.MoveRight(this);

}

Refresh();

}

else if (e.KeyCode == Keys.Oemplus)

{

foreach (CFigure figure in figures)

{

GetBigger();

}

Refresh();

}

else if (e.KeyCode == Keys.OemMinus)

{

foreach (CFigure figure in figures)

{

GetSmaller();

}

Refresh();

}

}

private void checkBox1_CheckedChanged(object sender, EventArgs e)

{

Cntrl = checkBox1.Checked;

foreach (CFigure figure in figures)

{

figure.fcntrl = Cntrl;

}

}

private void button1_Click(object sender, EventArgs e)//увеличение объекта

{

foreach (CFigure figure in figures)

{

figure.GetBigger();

}

Refresh();

}

private void button2_Click(object sender, EventArgs e)//уменьшение объекта

{

foreach (CFigure figure in figures)

{

figure.GetSmaller();

}

Refresh();

}

private void button3_Click(object sender, EventArgs e)//удаление

{

DelFigures();

}

private void button5_Click(object sender, EventArgs e)

{

foreach (CFigure figure in figures) // снятие выделения со всех объектов

{

figure.setCondition(false);

}

Refresh();

}

private void button_circle_Click(object sender, EventArgs e)

{

selectedFigure = 0;

}

private void button_square_Click(object sender, EventArgs e)

{

selectedFigure = 1;

}

private void button_triangle_Click(object sender, EventArgs e)

{

selectedFigure = 2;

}

private void button_section_Click(object sender, EventArgs e)

{

selectedFigure = 3;

}

private void GetSmaller()//метод умньшения фигур

{

foreach (CFigure figure in figures)

{

if (figure.selected && figure.rad > 10)

{

figure.rad -= 5;

}

}

Refresh();

}

private void GetBigger()//метод увеличения фигур

{

foreach (CFigure figure in figures)

{

if (figure.selected && figure.rad <= 95)

figure.rad += 5;

figure.returnFigure();

}

Refresh();

}

void DelFigures() // Метод удаления фигур

{

for (int i = 0; i < figures.Count; i++)

{

if (figures[i].selected == true)

{

figures.Remove(figures[i]);

i--;

}

}

Refresh();

}

private void button6_Click(object sender, EventArgs e)//смена цвета

{

if (colorIndex < 3)

colorIndex++;

else

colorIndex = 0;

switch (colorIndex)

{

case 0:

color = hotPink;

break;

case 1:

color = white;

break;

case 2:

color = purple;

break;

case 3:

color = black;

break;

}

button6.BackColor = color;

foreach (CFigure figure in figures)

{

if (figure.selected)

figure.colorF = color;

}

}

void control_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)

{

if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down || e.KeyCode == Keys.Left || e.KeyCode == Keys.Right)

{

e.IsInputKey = true;

}

button6.BackColor = color;

foreach (CFigure figure in figures)

{

if (figure.selected)

figure.colorF = color;

}

}

private void button4_Click(object sender, EventArgs e)

{

foreach (CFigure figure in figures) // выделения всех объектов

{

figure.setCondition(true);

}

Refresh();

}

void Group()

{

CGroup newgroup = new CGroup();

foreach (CFigure figure in figures)

{

if (figure.selected)

{

newgroup.Add(figure);

}

}

newgroup.iAmGroup = true;

foreach (CFigure figure in newgroup.childrens)

{

figures.Remove(figure);

}

figures.Add(newgroup);

Refresh();

}

private void button7_Click_1(object sender, EventArgs e)

{

Group();

}

private void saveMe()//сохранение

{

foreach (CFigure figure in figures)

{

figure.SelfSave(savedData);

}

}

private void button8_Click(object sender, EventArgs e)

{

saveMe();

loader.Save(savedData, "D:\\test.txt");

}

CFigure read(StreamReader sr)

{

string line = sr.ReadLine();

string[] data = line.Split(';');

switch (data[0])

{

case "CGroup":

{

int count = int.Parse(data[1]);

CGroup newfigure = new CGroup();

for (int i = 0; i < count; i++)

{

newfigure.Add(read(sr));

}

return newfigure;

}

default:

{

int x = int.Parse(data[2]);

int y = int.Parse(data[3]);

int rad = int.Parse(data[4]);

bool selected = bool.Parse(data[5]);

Color color = Color.FromArgb(int.Parse(data[1]));

switch (data[0])

{

case "CCircle":

{

CCircle newfigure = new CCircle(x, y, rad, color);

newfigure.setCondition(selected);

return newfigure;

}

case "CSquare":

{

CSquare newfigure = new CSquare(x, y, rad, color);

newfigure.setCondition(selected);

return newfigure;

}

case "CTriangle":

{

CTriangle newfigure = new CTriangle(x, y, rad, color);

newfigure.setCondition(selected);

return newfigure;

}

case "CSection":

{

CSection newfigure = new CSection(x, y, rad, color);

newfigure.setCondition(selected);

return newfigure;

}

}

return null;

}

}

}

private void button9_Click(object sender, EventArgs e)

{

foreach (CFigure figure in figures)

{

figure.setCondition(true);

}

DelFigures();

StreamReader sr = new StreamReader("D:\\test.txt");

while (!sr.EndOfStream)

{

figures.Add(read(sr));

}

sr.Close();

Refresh();

}

}

}

public class CFigure//описание объектов

{

public List<CFigure> childrens;

public Point coords;// координаты

public int rad;//радиус

public bool selected = false;

public bool fcntrl = false;

public bool iAmGroup = false;

public System.EventHandler observers;

public Color colorT = Color.CornflowerBlue;

public Color colorF = Color.Purple;

public virtual void Cntrled(bool pressed)

{

fcntrl = pressed;

}

public virtual void setCondition(bool cond) // метод переключения выделения

{

selected = cond;

}

public virtual void SelfDraw(Graphics g) // Метод для отрисовки самого себя

{

}

public virtual void SelfSave(SavedData savedData) // Метод для сохранения самого себя

{

StringBuilder line = new StringBuilder();

line.Append(ToString()).Append(";");

line.Append(colorF.ToArgb()).Append(";");

line.Append(coords.X.ToString()).Append(";");

line.Append(coords.Y.ToString()).Append(";");

line.Append(rad.ToString()).Append(";");

line.Append(selected.ToString()).Append(";");

savedData.linesToWrite.Add(line.ToString());

}

public virtual bool MouseCheck(MouseEventArgs e) // Проверка объекта на попадание в него курсора

{

return false;

}

public void returnFigure()

{

observers.Invoke(this, null);

}

public virtual void GetSmaller()//уменьшает объект

{

if (selected && rad > 10)

{

rad -= 5;

}

}

public virtual void GetBigger()

{

if (selected && rad <= 95)

{

rad += 5;

}

}

public virtual bool CanMoveUp(Form form)

{

if (((coords.Y - rad) > 0))

{

return true;

}

else

{

return false;

}

}

public virtual bool CanMoveDown(Form form)

{

if ((coords.Y + rad) < (int)form.ClientSize.Height)

{

return true;

}

else

{

return false;

}

}

public virtual bool CanMoveLeft(Form form)

{

if ((coords.X - rad) > 0)

{

return true;

}

else

{

return false;

}

}

public virtual bool CanMoveRight(Form form)

{

if ((coords.X + rad) < (int)form.ClientSize.Width)

{

return true;

}

else

{

return false;

}

}

public virtual void MoveUp(Form form)

{

if (selected && CanMoveUp(form))

{

coords.Y -= 20;

}

}

public virtual void MoveDown(Form form)

{

if (selected && CanMoveDown(form))

{

coords.Y += 20;

}

}

public virtual void MoveLeft(Form form)

{

if (selected && CanMoveLeft(form))

{

coords.X -= 20;

}

}

public virtual void MoveRight(Form form)

{

if (selected && CanMoveRight(form))

{

coords.X += 20;

}

}

}

public class CCircle : CFigure// класс круга

{

public CCircle(int x, int y, int radius, Color color) // конструктор по умолчанию

{

coords.X = x;

coords.Y = y;

rad = radius;

colorF = color;

}

public override void SelfDraw(Graphics g) // Метод для отрисовки самого себя

{

if (selected == true)

g.DrawEllipse(new Pen(colorT, 3), coords.X - rad, coords.Y - rad, rad * 2, rad * 2);

else

g.DrawEllipse(new Pen(colorF, 3), coords.X - rad, coords.Y - rad, rad * 2, rad * 2);

}

public override bool MouseCheck(MouseEventArgs e) // Проверка объекта на попадание в него курсора

{

if (fcntrl)

{

if (Math.Pow(e.X - coords.X, 2) + Math.Pow(e.Y - coords.Y, 2) <= Math.Pow(rad, 2) && !selected)

{

setCondition(true);

return true;

}

}

return false;

}

}

public class CSquare : CFigure // класс квадрата

{

public CSquare(int x, int y, int radius, Color color) // конструктор по умолчанию

{

coords.X = x;

coords.Y = y;

rad = radius;

colorF = color;

}

public override void SelfDraw(Graphics g) // Метод для отрисовки самого себя

{

if (selected == true)

g.DrawRectangle(new Pen(colorT, 3), coords.X - rad, coords.Y - rad, rad * 2, rad * 2);

else

g.DrawRectangle(new Pen(colorF, 3), coords.X - rad, coords.Y - rad, rad * 2, rad * 2);

}

public override bool MouseCheck(MouseEventArgs e) // Проверка объекта на попадание в него курсора

{

if (fcntrl)

{

if (Math.Pow(e.X - coords.X, 2) + Math.Pow(e.Y - coords.Y, 2) <= Math.Pow(rad, 2) && !selected)

{

setCondition(true);

return true;

}

}

return false;

}

}

public class CTriangle : CFigure // класс треугольника

{

public CTriangle(int x, int y, int radius, Color color) // конструктор по умолчанию

{

coords.X = x;

coords.Y = y;

rad = radius;

colorF = color;

}

public override void SelfDraw(Graphics g) // Метод для отрисовки самого себя

{

Point point1 = new Point(coords.X, coords.Y - rad);

Point point2 = new Point(coords.X + rad, coords.Y + rad);

Point point3 = new Point(coords.X - rad, coords.Y + rad);

Point[] curvePoints = { point1, point2, point3 };

if (selected == true)

g.DrawPolygon(new Pen(colorT, 1), curvePoints);

else

g.DrawPolygon(new Pen(colorF, 1), curvePoints);

}

public override bool MouseCheck(MouseEventArgs e) // Проверка объекта на попадание в него курсора

{

if (fcntrl)

{

if (Math.Pow(e.X - coords.X, 2) + Math.Pow(e.Y - coords.Y, 2) <= Math.Pow(rad, 2) && !selected)

{

setCondition(true); ;

return true;

}

}

return false;

}

}

public class CSection : CFigure // класс отрезка

{

public CSection(int x, int y, int radius, Color color) // конструктор по умолчанию

{

coords.X = x;

coords.Y = y;

rad = radius;

colorF = color;

}

public override void SelfDraw(Graphics g) // Метод для отрисовки самого себя

{

Point point1 = new Point(coords.X - rad, coords.Y);

Point point2 = new Point(coords.X + rad, coords.Y);

Point[] curvePoints = { point1, point2 };

if (selected == true)

g.DrawPolygon(new Pen(colorT, 3), curvePoints);

else

g.DrawPolygon(new Pen(colorF, 3), curvePoints);

}

public override bool MouseCheck(MouseEventArgs e) // Проверка объекта на попадание в него курсора

{

if (fcntrl)

{

if (Math.Pow(e.X - coords.X, 2) + Math.Pow(e.Y - coords.Y, 2) <= Math.Pow(rad, 2) && !selected)

{

setCondition(true);

return true;

}

}

return false;

}

}

class CGroup : CFigure

{

public new List<CFigure> childrens = new List<CFigure>();

public CGroup()

{

}

public void Add(CFigure component)

{

component.colorF = Color.DarkCyan;

component.setCondition(false);

childrens.Add(component);

}

public override void Cntrled(bool pressed)

{

foreach (CFigure component in childrens)

{

component.fcntrl = pressed;

}

fcntrl = pressed;

}

virtual public void setCondition(bool cond)

{

foreach (CFigure child in childrens)

{

child.setCondition(cond);

}

selected = cond;

}

public override void SelfDraw(Graphics g)

{

foreach (CFigure child in childrens)

{

child.SelfDraw(g);

}

}

public override void SelfSave(SavedData savedData)

{

StringBuilder tmp = new StringBuilder();

tmp.Append(ToString()).Append(";");

tmp.Append(childrens.Count().ToString()).Append(";");

savedData.linesToWrite.Add(tmp.ToString());

foreach (CFigure figure in childrens)

{

figure.SelfSave(savedData);

}

}

public override bool MouseCheck(MouseEventArgs e)

{

foreach (CFigure child in childrens)

{

if (child.MouseCheck(e))

{

return true;

}

}

return false;

}

public override void GetSmaller()

{

foreach (CFigure child in childrens)

{

child.GetSmaller();

}

}

public override void GetBigger()

{

foreach (CFigure child in childrens)

{

child.GetBigger();

}

}

public override bool CanMoveUp(Form form)

{

foreach (CFigure child in childrens)

{

if (!child.CanMoveUp(form))

{

return false;

}

}

return true;

}

public override bool CanMoveDown(Form form)

{

foreach (CFigure child in childrens)

{

if (!child.CanMoveDown(form))

{

return false;

}

}

return true;

}

public override bool CanMoveLeft(Form form)

{

foreach (CFigure child in childrens)

{

if (!child.CanMoveLeft(form))

{

return false;

}

}

return true;

}

public override bool CanMoveRight(Form form)

{

foreach (CFigure child in childrens)

{

if (!child.CanMoveRight(form))

{

return false;

}

}

return true;

}

public override void MoveUp(Form form)

{

if (CanMoveUp(form))

{

foreach (CFigure child in childrens)

{

child.MoveUp(form);

}

}

}

public override void MoveDown(Form form)

{

if (CanMoveDown(form))

{

foreach (CFigure child in childrens)

{

child.MoveDown(form);

}

}

}

public override void MoveLeft(Form form)

{

if (CanMoveLeft(form))

{

foreach (CFigure child in childrens)

{

child.MoveLeft(form);

}

}

}

public override void MoveRight(Form form)

{

if (CanMoveRight(form))

{

foreach (CFigure child in childrens)

{

child.MoveRight(form);

}

}

}

}

public class SavedData

{

public List<string> linesToWrite = new List<string>();

public void Add(string line)

{

linesToWrite.Add(line);

}

}

public class SaverLoader

{

public void Save(SavedData savedData, string way)

{

File.WriteAllLines(way, savedData.linesToWrite);

}

}

Соседние файлы в предмете Объектно ориентированное программирование