"Орешек знаний тверд, Но все же мы не привыкли отступать..." (с)
Шаг 7 (графический векторный редактор) Версия 0.1
Запись от ashsvis размещена 13.11.2018 в 12:18
Показов 8018
Комментарии 4
Метки c#, векторная графика
|
Сегодня хороший день, господа программисты, ибо я выпускаю в первое плавание мою лодку, под названием "Простой векторный графический редактор". Пока это только корпус, никаких мачт, рей и такелажа, но корпус, я надеюсь, достаточно прочный, чтобы сразу не пойти ко дну... ![]() Я подготовил небольшой демо проект для демонстрации и обсуждения: SimpleVectorGraphicsEditor Demo V0_1.zip Проект состоит из шести классов редактора, всё остальное необходимо для демонстрации работы. На центральной части формы расположена панель типа Panel, у которой размер Dock = Dock.Fill привязан ко внешней таблице компоновки и установлено свойство AutoSize = true. На этой панели расположен компонент PictureBox, который и будет контейнером для нашего редактора. В свойство PictureBox BackgroundImage загружена картинка, имитирующая координатную сетку. Наш редактор подключается в конструкторе формы:
затем подключаются два контекстных меню: pbCanvas.BackgoundContextMenu = cmsBkgPopup - для случая, когда ни одна фигура не выбрана (для общих настроек) pbCanvas.FigureContextMenu = cmsFigPopup - для вызова на выбранных фигурах. Содержимое контекстных меню подготавливается в дизайнере VS, а наш редактор только управляет их вызовом. Обработчики всех пунктов контекстных меню и главного меню также пишутся и подключаются в дизайнере VS. Редактор формирует два события: при выборе фигуры и при изменении расположения фигур, когда они перетаскиваются. Внешний обработчик синхронизируют внешние для редактора компоненты формы. Размер контейнера изменяется при изменении положения фигур в редакторе. [здесь хочу отступ]Во внешнем обработчике этого события размер контейнера подгоняется под текущий размер поля редактора, а панель, на которой находится контейнер, отображает полосы прокрутки, если это необходимо. На данный момент жесткий размер поля редактирования не предусмотрен. Хотя он нужен, например, для проверок на возможность размещения. Для начала рисования фигур пользователь должен выбрать фигуру, нажав на значок с её изображением. При нажатии на любую из этих кнопочек выполняется обработчик:
Далее переключаем режим редактора в зависимости от выбора пользователя. Пока всего только две фигуры можно нарисовать. Это полилиния и полигон. После выбора фигуры нажимаем мышкой на первую точку и, не отпуская левой кнопки, "тянем" до необходимого размера, потом отпускаем. Нужная фигура зафиксируется. Потом мы можем перемещать её, изменять размер, трансформировать и прочее. Дополнительно я тут подготовил небольшие "плюшки", как то копирование и вырезание выделенных фигур в буфер обмена, вставку фигур из буфера обмена. Любопытно, что эта штука работает, даже если мы скопируем фигуры в одном приложении редактора, а вставим в другом запущенном приложении редактора. Другой "плюшкой" является поддержка возможности отмены действий редактирования и возврат после отмены. Для этой цели создан класс-помощник StackMemory:
Применение этого класса также довольно простое, сначала создаем два стека Undo и Redo:
предстоит что-то изменить, например, закончили перетаскивание и перед тем как сместить фигуры, нужно присвоить свойству FileChanged значение True. В сеттере выполняться два метода подготовки для Undo и Redo.
помещаем этот поток в стек. Вот код метода SaveToStream():
Большое спасибо за внимание! Буду благодарен за ваши советы, указание на ошибки (которые буду исправлять по возможности) и наставления. | ||||||||||||||||||||||||||||||||||||||||
Метки c#, векторная графика
Размещено в Простой векторный графический редактор
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 4
Комментарии
-
Запись от ashsvis размещена 13.11.2018 в 14:28
-
Работает нормально (плюс-минус), но вот техническая реализация - не очень.
Много повторяющегося кода, примитивное undo/redo (без команд), объектная модель рассыпется как только нужно будет добавить больше функционала. А функционал очень бедный. Даже нет окружности, не говоря уже о более сложном.
Сначала бы неплохо было бы добавить элементарный набор фигур, хотя бы уровня Paint.Запись от Storm23 размещена 13.11.2018 в 20:23
-
undo/redo (без команд) - дайте ссылочку, где посмотреть по-подробнее.
функционал очень бедный - у меня нет цели "переплюнуть" векторные редакторы на рынке. Нужен только необходимый функционал. А "мясо" нарастает со временем. Главное, чтобы это было кому-то нужным.
Даже нет окружности
- да не успел я пока, надо перенести из проектов...
О переносе маркеров в фигуры. - если переносим маркеры, то и рисовать себя фигура должна сама. Я так думаю.
Сделаю.Запись от ashsvis размещена 13.11.2018 в 20:36
-
Паттерн команда. Также здесь.
Дело в том, что у вас нельзя нарастить мясо. Модель не позволяет. Посмотрите как у вас отрисовка происходит:
И таких фрагментов по программе раскидано десяток. Если, допустим, вы добавите отрисовку окружностей, вы во всех местах будете писать такой паровоз:C# 1 2 3 4
if (kind == DrawingKind.Polygon) graphics.DrawPolygon(pen, points); // рисование контура else graphics.DrawLines(pen, points);
Во всех тринадцати местах?C# 1 2 3 4 5 6 7
if (kind == DrawingKind.Polygon) graphics.DrawPolygon(pen, points); // рисование контура else if (kind == DrawingKind.Circle) graphics.DrawEllipse(pen, ...); // рисование окружности else graphics.DrawLines(pen, points);
Я потому особо и не критиковал предыдущий код, потому что его придется почти полностью переписать, как только вы решите нарастить функционал. Поэтому текущий код все равно в мусорку уйдет, и рассматривать его нет смысла.
Ну а если ограничится рисованием только прямоугольников, то можно наверное оставить как есть... И так сойдет
Исходите из аксиомы, что это никому не нужно
Я таких статей тут десяток накропал, отдача - почти нулевая.
Этот форум для студентов-двоечников. Максимум что они сделают - это скачают ваш проект и сдадут как лабу. Это все.Запись от Storm23 размещена 13.11.2018 в 21:19


- да не успел я пока, надо перенести из проектов...

