О будущей функциональности векторного редактора изображений
LWP 15 Tools :
Библиотека LWP 15 Tools содержит набор классов, которые могут быть использованы для работы с документами в приложении Windows Forms. Экземпляры классов, из библиотеки LWP 15 Tools хранятся на главной форме проекта LWP 15 Draw и используются для общих операций, связанных с файлом документа.
Библиотека LWP 15 Tools будет состоять из следующих полноценных классов:
· Класс DocManager: осуществляет операции, связанные с файлом: открытие, создание, сохранение, обновление названия формы и регистрация типа файлов для оболочки Windows.
· Класс DragDropManager: позволяет открывать файлы из проводника Windows в приложении Windows Forms.
· Класс MruManager: список управляет наиболее часто используемыми файлами (Последние файлы в пункте меню Файл).
· Класс PersistWindowState: позволяет сохранить последнее состояние окна в реестре и восстановить его при загрузке главной формы.
LWP 15 Draw :
Структура классов приложения и наследование реализовано следующим образом:
Рис. 4. 1. Классы проекта LWP 15 Draw
Назначения классов (файлов) следующее:
· DrawArea — пользовательский элемент управления, который заполняет главное окно клиентской области. Содержит экземпляр класса GraphicsList. Рисует графические объекты, обрабатывает ввод от мыши передачей команд в GraphicsList. Реализует графическое пространство в явном виде для интерфейса формы.
· GraphicsList — список графических объектов. Содержит ArrayList графических объектов. «Общается» с графическими объектами в общем виде, с использованием методов DrawObject. Реализует графическое пространство в виртуальном виде приложения.
|
|
· DrawObject — абстрактный базовый класс для всех графических объектов.
· DrawRectangle — рисование графического объекта прямоугольника.
· DrawEllipise — рисование графического объекта эллипса.
· DrawLine — рисование графического объекта линии.
· DrawPolygon — рисование графического объекта непрерывной линии/карандаш.
· Tool — абстрактный базовый класс для всех инструментов рисования.
· ToolPointer — указатель инструмента (нейтральный инструмент). Содержит реализации для выбора, перемещения, изменения размера графических объектов.
· ToolObject — абстрактный базовый класс для всех инструментов, создающих новый графический объект.
· ToolRectangle — реализует инструмент «прямоугольник».
· ToolEllipse — реализует инструмент «эллипс».
· ToolLine — реализует инструмент «линия».
· ToolPolygon — реализует инструмент «непрерывная линия/карандаш».
Сериализация:
Класс GraphicList реализует интерфейс ISerializable, который позволяет производить двоичной сериализации объекта класса. Класс DrawObject имеет две virtual-функции, используемые для сериализации:
|
|
public virtual void SaveToStream(SerializationInfo info, int orderNumber)
{
// ...
}
public virtual void LoadFromStream(SerializationInfo info, int orderNumber)
{
// ...
}
Эти функции реализованы в каждом производном классе. Двоичный сохранённый файл имеет следующий формат:
Число объектов
Имя типа
Объект
Имя типа
Объект
...
Имя типа
Объект
Это позволяет писать код общий сериализации в классе GraphicList не зная никаких подробностей о сериализованных объектов (абстрактно, для любого объекта):
private const string entryCount = "Count";
private const string entryType = "Type";
// Сохранить список в поток
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
// Число объектов
info.AddValue(entryCount, graphicsList.Count);
int i = 0;
foreach (DrawObject o in graphicsList)
{
// Тип объекта
info.AddValue(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}",
entryType, i),
o.GetType().FullName);
// Сам объект
o.SaveToStream(info, i);
i++;
}
}
// Загружаем из потока
protected GraphicsList(SerializationInfo info, StreamingContext context)
|
|
{
graphicsList = new ArrayList();
// Число объектов
int n = info.GetInt32(entryCount);
string typeName;
object drawObject;
for ( int i = 0; i < n; i++ )
{
// Тип объекта
typeName = info.GetString(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}",
entryType, i));
// Создаём объект по имени типа через using Reflection)
drawObject = Assembly.GetExecutingAssembly().CreateInstance(
typeName);
// Заполняем объект из потока
((DrawObject)drawObject).LoadFromStream(info, i);
graphicsList.Add(drawObject);
}
}
Проверка нажатия кнопки мыши :
Как определить, что под указателем мыши находится нарисованный ранее объект?
Класс DrawObject имеет virtual-функцию HitTest, которая определяет, принадлежит ли точка графическому объекту (проверят, куда нажал пользователь):
public virtual int HitTest(Point point)
{
return -1;
}
Производные классы используют virtual PointInObject для проверки нажатия. Эта функция вызывается из HitTest. Класс DrawRectangle реализует эту функцию:
protected override bool PointInObject(Point point)
{
return rectangle.Contains(point);
// rectangle - принадлежит типу Rectangle
}
Чуть более сложный вариант определения нажатия по линии:
|
|
protected override bool PointInObject(Point point)
{
GraphicsPath areaPath;
Pen areaPen;
Region areaRegion;
// Создаём путь, который содержит широкую линию
// Для лёгкого выбора мышью
AreaPath = new GraphicsPath();
AreaPen = new Pen(Color.Black, 7);
AreaPath.AddLine(startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
// startPoint и endPoint - принадлежат типу Point
AreaPath.Widen(AreaPen);
// Создаём область из пути
AreaRegion = new Region(AreaPath);
return AreaRegion.IsVisible(point);
}
Обработка состояния бездействия приложения:
Каждое Windows Forms приложение в своём составе имеет элементы управления такие как кнопки пунктов меню, кнопки панелей инструментов и прочее. В зависимости от текущей ситуации и команды пользователя, эти элементы управления могут иметь различные состояния: включены/выключены, отмечены/не отмечены, видимые/невидимые и так далее. Действие пользователя может изменить это состояние. Настройка состояний элементов управления в каждом обработчике сообщений вызывать ошибку. Вместо этого, это управлять состояние элемента управления лучше через функции, которые вызываются после каждого действия пользователя. В MFC (Visaul C ++) существует функция ON_UPDATE_COMMAND_UI, которая позволяет обновить состояние кнопок панели инструментов во время бездействия приложения. Такая возможность может осуществляться также и в .NET программе.
Рассмотрим ситуацию, когда пользователь нажимает кнопку на панели инструментов (Прямоугольник). Эта кнопка должна активироваться, а ранее активный инструмент должен быть снят. Обработчик сообщений кнопки (Прямоугольник) не изменяет состояние элементов управления формы, он просто сохраняет текущее выделение кнопки в некоторой переменной. Обработчик сообщений Idle активирует инструмент и снимает выделение с неактивного инструмента. Передача изменения состояния кнопок происходит через метод, а не напрямую:
public void SetStateOfControls()
{
// Выбор активного инструмента
tbPointer.Pushed = (drawArea.ActiveTool == DrawArea.DrawToolType.Pointer);
tbRectangle.Pushed = (drawArea.ActiveTool == DrawArea.DrawToolType.Rectangle);
tbEllipse.Pushed = (drawArea.ActiveTool == DrawArea.DrawToolType.Ellipse);
tbLine.Pushed = (drawArea.ActiveTool == DrawArea.DrawToolType.Line);
tbPolygon.Pushed = (drawArea.ActiveTool == DrawArea.DrawToolType.Polygon);
menuDrawPointer.Checked = (drawArea.ActiveTool == DrawArea.DrawToolType.Pointer);
menuDrawRectangle.Checked = (drawArea.ActiveTool == DrawArea.DrawToolType.Rectangle);
menuDrawEllipse.Checked = (drawArea.ActiveTool == DrawArea.DrawToolType.Ellipse);
menuDrawLine.Checked = (drawArea.ActiveTool == DrawArea.DrawToolType.Line);
menuDrawPolygon.Checked = (drawArea.ActiveTool == DrawArea.DrawToolType.Polygon);
// ...
}
// Инструмент "Прямоугольник" выбран
private void CommandRectangle()
{
drawArea.ActiveTool = DrawArea.DrawToolType.Rectangle;
}
Дата добавления: 2019-09-13; просмотров: 213; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!