Мови Моделювання

Починаючи з версії 2.0, Gaphor підтримує концепцію мов моделювання. Це дозволяє розробляти окремі мови моделювання окремо від основної програми Gaphor.

Основною мовою був і буде UML. Gaphor тепер також підтримує підмножину SysML, RAAML і модель C4.

Мова моделювання в Gaphor визначається класом, що реалізує абстрактний базовий клас gaphor.abc.ModelingLanguage. Мова моделювання повинна бути зареєстрована як точка входу gaphor.modelinglanguages.

Інтерфейс ModelingLanguage є досить мінімальним. Він дозволяє іншим службам шукати елементи та елементи діаграм, а також панель інструментів і типи діаграм. Однак на цьому обов’язки мови моделювання не закінчуються. Частину функціональності буде реалізовано шляхом реєстрації обробників для набору загальних функцій.

Але не будемо забігати наперед. Які функціональні можливості може запропонувати реалізація мови моделювання?

[ModelingLanguage екземпляр] (#modeling-language) відкриває три функції:

  • Модель даних (елементи) та елементи діаграми

  • Типи діаграм

  • Визначення панелі інструментів

Інші функціональні можливості можна розширити, додавши обробники до відповідних загальних функцій:

  • З’єднувачі, дозволяють об’єднувати елементи діаграми

  • Format/parse моделює елементи до текстового представлення та з нього

  • Поведінка Copy/paste, коли копіювання елемента не є тривіальним, наприклад, із залученням кількох елементів

  • Групування, дозволяє елементам бути вкладеними один в одного

  • Dropping, дозволяє перетягувати елементи з перегляду дерева на діаграму

  • Правила автоматичного очищення, щоб підтримувати узгодженість моделі

Мови моделювання також можуть надавати нові компоненти інтерфейсу користувача. Ці компоненти не завантажуються безпосередньо під час імпортування пакунка мови моделювання. Замість цього їх слід імпортувати через точку входу gaphor.modules.

Мова моделювання

class gaphor.abc.ModelingLanguage[source]

Постачальник моделі — це спеціальна служба, яка надає точку входу до реалізації моделі, наприклад UML, SysML, RAAML.

abstract property diagram_types: Iterable[DiagramType]

Ітерація типів діаграм.

abstract property element_types: Iterable[ElementCreateInfo]

Ітерація типів елементів.

abstractmethod lookup_element(name: str, ns: str | None = None) type[Base] | None[source]

Знайдіть тип елемента моделі за назвою (класу).

Може бути надано простір імен. Це дозволить завантажувати модель лише з цієї конкретної мови моделювання.

abstract property model_browser_model: type[TreeModel]

Модель для використання в переглядачі моделей.

abstract property name: str

Зрозуміла назва мови моделювання.

abstract property toolbox_definition: ToolboxDefinition

Отримати структуру для панелі інструментів.

За домовленістю пакет, що містить мову моделювання, повинен мати атрибут __modeling_language__, який має те саме значення, що й назва мови моделювання в точці входу.

Щоб проілюструвати:

Файл mytool/mylang/__init__.py містить запис:

__modeling_language__ = "MyLang"

pyproject.toml містить точку входу:

[project.entry-points."gaphor.modelinglanguages"]
"MyLang" = "mytool.mylang.modelinglanguage:MyLangModelingLanguage"

Роз’єми

З’єднувачі служать для з’єднання одного елемента з іншим.

Конектори мають відповідати ConnectorProtocol. Зазвичай ви успадкуєте від BaseConnector.

class gaphor.diagram.connectors.BaseConnector(element: Presentation[Base], line: Presentation[Base])[source]

Адаптер підключення для елементів схеми Gaphor.

Елемент прейскуранта line з’єднується за допомогою маркера з element елемента, який можна підключити.

Параметри:
  • line – сполучний елемент

  • element – підключається елемент

За домовленістю адаптери реєструються за (елементом, лінією) – у такому порядку.

allow(handle: Handle, port: Port) bool[source]

Визначте, чи можна з’єднати елементи.

Чи дозволено підключення взагалі (під час руху миші, наприклад)?

Повертає True, якщо підключення дозволено.

connect(handle: Handle, port: Port) bool[source]

Підключитися до елемента.

Встановіть зв’язок між елементом і лінією. Також піклується про роз’єднання, якщо потрібно (наприклад, відносини 1:1).

Зауважте, що на цьому етапі лінія може бути з’єднана з іншим або тим же елементом. З’єднання на рівні моделі все ще існує.

Повертає True, якщо з’єднання встановлено.

disconnect(handle: Handle) None[source]

Від’єднайте з’єднання рівня моделі.

Розірвати з’єднання, викликається, коли дескриптор опускається в точку, де він не може з’єднатися.

get_connected(handle: Handle) Presentation[Base] | None[source]

Приєднайте предмет до ручки.

Форматування та аналіз

Елементи моделі можна відформатувати до простого текстового представлення. Наприклад, це використовується в переглядачі моделей. Це не повна серіалізація елемента моделі.

У деяких випадках корисно розібрати текст назад в об’єкт. Це робиться, коли ви редагуєте атрибути та операції над класом.

Не кожен format() повинен мати еквівалентну parse() функцію.

gaphor.core.format.format(element: Element) str

Повертає зрозуміле для людини представлення елемента моделі. У більшості випадків це лише ім’я, однак властивості (атрибути) та операції відформатовані більш широко:

+ attr: str
+ format(element: Element): string
gaphor.core.format.parse(element: Element, text: str) None

Проаналізуйте текст і заповніть елемент. Елемент заповнюється елементами з тексту. Це може означати, що нові елементи моделі створюються як частина процесу аналізу.

Скопіюйте та вставте

Копіювання та вставка працює «з коробки» для простих елементів: один елемент діаграми з одним елементом моделі («об’єкт»). Він використовує методи load() і ave() елементів, щоб забезпечити копіювання всіх необхідних даних.

Іноді для роботи елементів потрібно більше ніж один елемент моделі. Наприклад, асоціація: вона має два кінці асоціації.

У цих конкретних випадках вам потрібно реалізувати власні функції копіювання та вставлення. Щоб створити таку річ, вам потрібно буде створити дві функції: одну для копіювання та одну для вставки.

gaphor.diagram.copypaste.copy(obj: Base | Iterable) Iterator[tuple[Id, Opaque]]

Створити копію елемента (або списку елементів). Тип, що повертається, має бути відмінним, щоб функція paste() могла коректно виконати копіювання. Функція копіювання зазвичай копіює лише елемент і обов’язково пов’язані з ним елементи. Наприклад, асоціація потребує два кінці асоціації.

gaphor.diagram.copypaste.paste(copy_data: Opaque, diagram: Diagram, lookup: Callable[[str], Base | None]) Iterator[Base]

Вставте раніше скопійовані дані. На основі типу даних, створеного у функції copy(), спробуйте скопіювати скопійовані елементи. Повертає щойно створений елемент або елемент.

Gaphor надає деякі зручні функції:

gaphor.diagram.copypaste.copy_full(items: Collection[Base], lookup: Callable[[Id], Base | None] | None = None) CopyData:

Копіювати items. Функція lookup використовується для пошуку належних елементів (відображених як дочірні вузли у браузері моделей).

Вставте копію елемента Presentation на діаграму, але спробуйте зв’язати базовий елемент моделі. Неглибока копія.

gaphor.diagram.copypaste.paste_full(copy_data: CopyData, diagram: Diagram) set[~gaphor.core.modeling.Presentation]:

Вставте копію презентації та елемента моделі. Глибока копія.

Групування

Групування здійснюється шляхом перетягування одного елемента поверх іншого, на діаграмі чи в ієрархічній панелі.

gaphor.diagram.group.owner(element: Base) Base | RootType | None

Повернути власника для element. Власником може бути Root, що означає, що елемент має бути розміщено в корені ієрархії власності. Якщо повернено None, власника немає.

gaphor.diagram.group.owns(element: Base) list[Base]

Повертає всі елементи, що належать `element

gaphor.diagram.group.group(parent: Base, element: Base) bool

Згрупуйте елемент у батьківському елементі. Групування може базуватися на власності, але можливі й інші типи групування.

gaphor.diagram.group.ungroup(parent: Base, element: Base) bool

Видалити групування з елемента. Функція повинна перевірити, чи наданий батьківський вузол є правильним.

gaphor.diagram.group.can_group(parent_type: type[Base], element_or_type: type[Base] | Base) bool

Ця функція намагається визначити, чи можливе групування, фактично не виконуючи групову операцію. Це не 100% точне.

Падіння

Відкидання виконується шляхом перетягування елемента з перегляду дерева та перетягування його на діаграму. Це простий спосіб розширити діаграму за допомогою вже існуючих елементів моделі.

Крім того, елемент презентації можна опустити поверх іншого елемента.

gaphor.diagram.drop.drop(element: Base | Presentation, diagram: Diagram | Presentation, x: float, y: float) Presentation | None

Функція drop створює нове представлення для елемента на діаграмі, якщо він ще не є представленням. Для зв’язків drop спрацьовує лише тоді, коли обидва зв’язані елементи присутні на одній діаграмі.

У той час як групування стосується з’єднання елементів моделі, видалення має справу зі створенням і розміщенням елементів презентації на правому елементі діаграми.

Автоматизоване очищення моделі

Gaphor хоче, щоб модель була синхронізована з діаграмами.

Невелика функція диспетчеризації використовується, щоб визначити, чи можна видалити елемент моделі.

gaphor.diagram.deletable.deletable(element: Base) bool

Визначте, чи можна безпечно видалити елемент моделі.

Сторінки редактора властивостей

Сторінка редактора складається з фрагментів. Наприклад: майже кожен елемент має назву, тому є фрагмент інтерфейсу користувача, який дозволяє редагувати назву.

Кожна сторінка властивостей (фрагмент) має успадкувати від PropertyPageBase.

class gaphor.diagram.propertypages.PropertyPageBase[source]

Сторінка властивостей, яка може відображатися в блокноті.

close() None[source]

Called when a property page is removed.

This allows us to clean up.

abstractmethod construct() Gtk.Widget | None[source]

Створіть сторінку (Gtk.Widget), яка належить до сторінки властивостей.

Повертає віджет верхнього рівня сторінки (Gtk.Widget).

Спливаючі вікна редактора миттєвих (схем)

Коли ви двічі клацаєте елемент на діаграмі, може з’явитися спливаюче вікно, тож ви можете легко змінити назву.

За замовчуванням це працює для будь-якого іменованого елемента. За потреби ви можете зареєструвати власну функцію вбудованого редактора.

gaphor.diagram.instanteditors.instant_editor(item: Item, view, event_manager: EventManager, pos: tuple[int, int] | None = None) bool

Показати невелике спливаюче вікно редактора на схемі. Спрощує редагування, не вдаючись до редактора елементів.

У разі події натискання миші також надається положення миші (відносно елемента).