О будущей функциональности векторного редактора изображений



 

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; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!