| 3 | | from alignment import * |
|---|
| | 5 | __version__ = "0.1" |
|---|
| | 6 | __author__ = "Jeroen Vloothuis" |
|---|
| | 7 | |
|---|
| | 8 | from zope import interface, component |
|---|
| | 9 | from gaphor.core import inject, transactional, action, build_action_group |
|---|
| | 10 | from gaphor.interfaces import IService, IActionProvider |
|---|
| | 11 | from gaphor.ui.interfaces import IDiagramSelectionChange |
|---|
| | 12 | |
|---|
| | 13 | |
|---|
| | 14 | class Alignment(object): |
|---|
| | 15 | |
|---|
| | 16 | interface.implements(IService, IActionProvider) |
|---|
| | 17 | |
|---|
| | 18 | gui_manager = inject('gui_manager') |
|---|
| | 19 | |
|---|
| | 20 | menu_xml = """ |
|---|
| | 21 | <ui> |
|---|
| | 22 | <menubar action="mainwindow"> |
|---|
| | 23 | <menu action="diagram"> |
|---|
| | 24 | <placeholder name="ternary"> |
|---|
| | 25 | <separator /> |
|---|
| | 26 | <menuitem action="align-horizontal" /> |
|---|
| | 27 | <menuitem action="align-vertical" /> |
|---|
| | 28 | </placeholder> |
|---|
| | 29 | </menu> |
|---|
| | 30 | </menubar> |
|---|
| | 31 | </ui>""" |
|---|
| | 32 | |
|---|
| | 33 | def __init__(self): |
|---|
| | 34 | self.action_group = build_action_group(self) |
|---|
| | 35 | self._last_update = None |
|---|
| | 36 | |
|---|
| | 37 | def init(self, app): |
|---|
| | 38 | self._app = app |
|---|
| | 39 | app.registerHandler(self.update) |
|---|
| | 40 | |
|---|
| | 41 | def shutdown(self): |
|---|
| | 42 | self._app.unregisterHandler(self.update) |
|---|
| | 43 | |
|---|
| | 44 | @component.adapter(IDiagramSelectionChange) |
|---|
| | 45 | def update(self, event=None): |
|---|
| | 46 | self._last_update = event |
|---|
| | 47 | sensitive = event and len(event.selected_items) > 1 |
|---|
| | 48 | self.action_group.get_action('align-horizontal').set_sensitive(sensitive) |
|---|
| | 49 | self.action_group.get_action('align-vertical').set_sensitive(sensitive) |
|---|
| | 50 | |
|---|
| | 51 | def get_items(self): |
|---|
| | 52 | return (self._last_update and self._last_update.selected_items) or [] |
|---|
| | 53 | |
|---|
| | 54 | def moveItemsToTarget(self, items, target_x, target_y): |
|---|
| | 55 | for item in items: |
|---|
| | 56 | if target_x is not None: |
|---|
| | 57 | x = target_x - item.matrix[4] |
|---|
| | 58 | else: |
|---|
| | 59 | x = 0 |
|---|
| | 60 | if target_y is not None: |
|---|
| | 61 | y = target_y - item.matrix[5] |
|---|
| | 62 | else: |
|---|
| | 63 | y = 0 |
|---|
| | 64 | item.matrix.translate(x,y) |
|---|
| | 65 | item.request_update() |
|---|
| | 66 | |
|---|
| | 67 | def getXCoords(self, items): |
|---|
| | 68 | return [item.matrix[4] for item in items] |
|---|
| | 69 | |
|---|
| | 70 | @action(name='align-vertical', label='Align vertical', |
|---|
| | 71 | tooltip="Align diagram elements vertically") |
|---|
| | 72 | @transactional |
|---|
| | 73 | def align_vertical(self): |
|---|
| | 74 | items = self.get_items() |
|---|
| | 75 | target_x=min(self.getXCoords(items)) |
|---|
| | 76 | target_y=None |
|---|
| | 77 | self.moveItemsToTarget(items, target_x, target_y) |
|---|
| | 78 | |
|---|
| | 79 | def getYCoords(self, items): |
|---|
| | 80 | return [item.matrix[5] for item in items] |
|---|
| | 81 | |
|---|
| | 82 | @action(name='align-horizontal', label='Align horizontal', |
|---|
| | 83 | tooltip="Align diagram elements horizontally") |
|---|
| | 84 | @transactional |
|---|
| | 85 | def align_horizontal(self): |
|---|
| | 86 | items = self.get_items() |
|---|
| | 87 | target_y = min(self.getYCoords(items)) |
|---|
| | 88 | target_x = None |
|---|
| | 89 | self.moveItemsToTarget(items, target_x, target_y) |
|---|
| | 90 | |
|---|
| | 91 | |
|---|
| | 92 | # vim:sw=4:et:ai |
|---|