Редактор LiteView

Библиотека и редактор интерактивной векторной графики LiteView
Реализация: C# DotNet 2.0.

В проект входит:
1. Библиотека основных классов LiteView,
2. Библиотека пользовательских элементов управления LiteViewControls,
3. Приложение редактор для тестов и демонстрации.
4. Этот документ описания и история версий.

Проект предназначен для создания встраиваемых редакторов схем, диаграмм, графиков и презентаций. В основу положен 15 летний опыт разработки подобных редакторов. Наиболее близким аналогом является библиотека Objective View от Stingray.
Отличительной особенностью LiteView является сочетание простоты и функциональности, что позволяет её гибко расширять и настраивать под конкретные задачи.

Основа LiteView зависит только от сборок System и System.Drawing. LiteViewControls зависит ещё и от WindowsForms.
Такая слабая зависимость от системных библиотек позволяет её легко портировать на другую платформу или подключить альтернативное графическое ядро.

Основным классом является LContext. Через него происходит взаимодействие редактора с пользовательскими контролами.
Этот класс похож на контроллер из модели MVC. Однако его полномочия намного шире. Он доступен для любых объектов, т.к. объявлен как статический член LContext.Current. Для реализации нескольких редакторов, документов и видов, этот контекст надо переключать при активизации соответствующего элемента управления. Это небольшая плата за простоту и гибкость.

Иерархия объектов приложения может выглядеть следующим образом:
1. Приложение,
2. Документ,
3. Фрейм,
4. LControlView, - пользовательский элемент управления,
5. LContext, - контекст,
6. LComponentView, - вид,
7. LComponentCanvas, - холст или страницы,
8. LComponentGroup, - группа (опционно),
9. LComponentXXX, - любой другой компонент.

В библиотеке реализовано несколько иерархий:
1. Иерархия компонентов LComponent и фигур LShape.
2. Иерархия стилей LStyle, для шрифта, кисти и пера.
3. Иерархия команд LCommand для стеков Undo/Redo.
4. Иерархия действий для реакции на пользователя LUIAction, LUITracker.

Ещё есть ряд специализированных классов.



Базовый класс LComponent реализует несколько механизмов:
1. Механизм композиции Parent – LComponentGroup.Childs, предназначен для установления агрегатных отношений в модели.
2. Механизм обновлений Invalidate() – OnUpdate(),предназначен для оптимизации внутренних расчётов и реализован через флаг NeedUpdate.
3. Механизм каскадной отрисовки компонентов OnDraw() с опционной буферизацией и трансформацией.
4. Механизм каскадной проверки попаданий HitTest().
5. Механизм манипуляторов LHandle, для выделенных компонентов.
6. Опциональные механизмы трансформации и буферизации.

Контекст LContext реализует несколько механизмов:
1. Статический указатель на текущий контекст.
2. Состояние пользовательского интерфейса LUIState.
3. Процесс обработки действий пользователя LUIProcessor.
4. Список выбранных компонентов Selection и HitComponent.
5. Стеки Undo/Redo LCommandStack.
6. Компонент вида LComponentView.
7. Таблица стилей LStyleSheet.
8. Список настроек LSettings.
9. LHandleBuffer – для оптимизации отрисовки манипуляторов.

Диспетчеризация пользовательского управления (обработчиков) осуществляется в LUIProcessor и подразделяется на мгновенные действия LUIAction и протяжённые трекеры LUITracker. Каждый из них может запускаться либо от клавиатуры и мышки (осуществляется проверка нажатия последовательности клавиш), либо от кнопок тулбаров (осуществляется прямой вызов).
Определение множества действий и трекеров в LUIProcessor делается на стороне приложения (вне библиотеки). Это позволяет гибко настраивать пользовательский интерфейс. Однако следует иметь ввиду, что порядок следования обработчиков в процессоре играет роль. Каждый обработчик (производный от LUIAction), имеет ключ – комбинацию нажатых клавиш, которая сопоставляется с текущим состоянием LUIState. Таким образом осуществляется управление.
Затем, при удачном выполнении действия, LUIAction или LUITracker формируют обратную команду LCommand и кладут её в стек отмены операций LCommandStack. В случае выделения нескольких компонентов, действие формирует макрокоманду LCommandMacro.

Теперь хочется отметить ряд оригинальных решений и их побочные эффекты:
1. Реализация множества документов и видов в одном приложении, зависит от своевременного переключения текущего контекста LContext.Current.
2. Доступ к большинству параметров и к визуальной модели, осуществляется через текущий глобальный контекст LContext.Current. Это даёт огромные возможности, но усложняет отладку поведения.
3. Реализация множества страниц не является однозначным решением. Это может быть разбивка холста на страницы, а может быть многостраничной презентацией. Этот вопрос пока пропускаю.
4. Настройка интерактивного взаимодействия (семейство LUI_ классов) вынесена на уровень пользовательского приложения. Считаю это ценным решением, однако оно требует аккуратности в использовании.
5. Методы обратного вызова реализованы через действия LUIAction, который передаёт клиенту фазу действия.
6. Ряд возможностей компонента являются опциональными. Такие опции, как трансформация и буферизация определены в базовом компоненте. С другой стороны фигуры представляют собой семейство классов, унаследованных от LShape, в которой есть GraphicPath. Однако расширение в сторону эффектов, декораторов, анимации и т.п., требует либо развивать LComponent, либо плодить производные семейства классов, что приводит к их комбинаторному взрыву.

Действия пользователя проходят несколько этапов:
1. Вначале их перехватывает оконный контрол LControlView.
2. Затем эти действия изменяют состояние LUIState.
3. После этого управление передаётся в LUIProcessor.
4. Происходит поиск действия LUIAction или LUITracker.
5. Выполняется действие, которое может вызвать события callback.
6. Действие порождает команду LCommand и изменяет свойство компонента.
7. Команда попадает в стек отмены LCommandStack.

Для предотвращения комбинаторного взрыва компонентов, был выведен ряд ортогональных и опциональных способностей:
1. Свойства,
2. Стили,
3. Связи,
4. Трансформации,
5. Буферизация,
6. Растровые эффекты,
7. Декораторы,
8. Анимация,

Однако ряд компонентов имеет свои особенности, выходящие за рамки ортогональных способностей. Это:
1. Фигуры,
2. Картинки, Видео,
3. Текст,
4. Связки,
5. Группы,
6. Таблицы,
7. Графики, Диаграммы,
8. Формулы, Ноты, Шрифты,

Исходный код,
Мануал,
История версий,
Исполняемый файл,
В архиве:
https://yadi.sk/d/1ZAVRfsb3RGb9S


Рецензии
Работа периодически обновляется.

Владимир Евгеньевич Липатов   08.01.2018 16:33     Заявить о нарушении