Changeset 2428
- Timestamp:
- 10/09/08 12:02:29 (2 months ago)
- Files:
-
- gaphor/branches/ports/gaphor/adapters/__init__.py (modified) (1 diff)
- gaphor/branches/ports/gaphor/adapters/classes (added)
- gaphor/branches/ports/gaphor/adapters/classes/__init__.py (added)
- gaphor/branches/ports/gaphor/adapters/classes/interfaceconnect.py (added)
- gaphor/branches/ports/gaphor/adapters/classes/tests (added)
- gaphor/branches/ports/gaphor/adapters/classes/tests/__init__.py (added)
- gaphor/branches/ports/gaphor/adapters/classes/tests/test_implementation.py (moved) (moved from gaphor/branches/ports/gaphor/adapters/tests/test_implementation.py) (2 diffs, 1 prop)
- gaphor/branches/ports/gaphor/adapters/classes/tests/test_interfaceconnect.py (added)
- gaphor/branches/ports/gaphor/adapters/connectors.py (modified) (2 diffs)
- gaphor/branches/ports/gaphor/adapters/propertypages.py (modified) (2 diffs)
- gaphor/branches/ports/gaphor/diagram/classes/dependency.py (modified) (5 diffs)
- gaphor/branches/ports/gaphor/diagram/classes/interface.py (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
gaphor/branches/ports/gaphor/adapters/__init__.py
r2384 r2428 3 3 import gaphor.adapters.editors 4 4 5 import gaphor.adapters.classes.interfaceconnect 6 7 import gaphor.adapters.components.connector 8 5 9 import gaphor.adapters.states.vertexconnect 6 10 import gaphor.adapters.states.propertypages 7 8 import gaphor.adapters.components.connectorgaphor/branches/ports/gaphor/adapters/classes/tests/test_implementation.py
- Property svn:mergeinfo set
r2427 r2428 1 1 """ 2 Test implementation (interf ecae realization) item connectors.2 Test implementation (interface realization) item connectors. 3 3 """ 4 4 … … 57 57 58 58 59 def test_folded_interface_connection(self):60 """Test connecting implementation to folded interface61 """62 iface = self.create(items.InterfaceItem, UML.Interface)63 iface.set_drawing_style(items.InterfaceItem.DRAW_ICON)64 impl = self.create(items.ImplementationItem)65 66 assert not impl._solid67 self.connect(impl, impl.head, iface)68 self.assertTrue(impl._solid)69 70 71 def test_folded_interface_disconnection(self):72 """Test disconnection implementation from folded interface73 """74 iface = self.create(items.InterfaceItem, UML.Interface)75 iface.set_drawing_style(items.InterfaceItem.DRAW_ICON)76 impl = self.create(items.ImplementationItem)77 78 assert not impl._solid79 self.connect(impl, impl.head, iface)80 assert impl._solid81 82 self.disconnect(impl, impl.head)83 self.assertTrue(not impl._solid)84 85 59 86 60 # vim:sw=4:et:ai gaphor/branches/ports/gaphor/adapters/connectors.py
r2427 r2428 17 17 from gaphor.diagram.interfaces import IConnect 18 18 from gaphor.diagram import items 19 from gaphor.misc.ipair import ipair20 19 21 20 … … 458 457 ('implementatingClassifier', 'implementation')) 459 458 self.line.subject = relation 460 461 462 def connect(self, handle, port):463 """464 Implementation item can be changed to draw in solid mode, when465 connected to folded interface.466 """467 468 super(ImplementationConnect, self).connect(handle, port)469 item = self.line.head.connected_to470 if isinstance(item, items.InterfaceItem):471 self.line._solid = item.is_folded()472 473 474 def disconnect(self, handle):475 """476 If implementation item is no longer connected to an interface, then477 draw in non-solid mode.478 """479 super(ImplementationConnect, self).disconnect(handle)480 if handle is self.line.head:481 self.line._solid = False482 459 483 460 gaphor/branches/ports/gaphor/adapters/propertypages.py
r2378 r2428 697 697 # Fold toggle 698 698 hbox = gtk.HBox() 699 label = gtk.Label(_("Fold "))699 label = gtk.Label(_("Folded")) 700 700 label.set_justify(gtk.JUSTIFY_LEFT) 701 701 self.size_group.add_widget(label) 702 702 hbox.pack_start(label, expand=False) 703 703 704 button = gtk.CheckButton() 704 705 button.set_active(self.context.folded) 705 706 button.connect('toggled', self._on_fold_change) 707 item = self.context 708 button.set_sensitive(len(item.canvas.get_connected_items(item)) == 0) 706 709 hbox.pack_start(button) 707 710 hbox.show_all() … … 714 717 @transactional 715 718 def _on_fold_change(self, button): 716 self.context.folded = button.get_active() 717 ports = self.context.ports() 718 handles = self.context.handles() 719 for p in ports[:4]: 720 p.connectable = not self.context.folded 721 for h in handles[:4]: 722 h.visible = not self.context.folded 723 724 for p in ports[-2:]: 725 p.connectable = self.context.folded 726 for h in handles[-2:]: 727 h.visible = self.context.folded 719 item = self.context 720 assert len(item.canvas.get_connected_items(item)) == 0 721 if button.get_active(): 722 item.folded = item.FOLDED_PROVIDED 723 else: 724 item.folded = item.FOLDED_NONE 728 725 729 726 730 727 component.provideAdapter(InterfacePropertyPage, name='Properties') 728 731 729 732 730 gaphor/branches/ports/gaphor/diagram/classes/dependency.py
r2255 r2428 67 67 self._dependency_type = UML.Dependency 68 68 self.auto_dependency = True 69 self._ dash_style = True69 self._solid = False 70 70 71 71 def save(self, save_func): … … 103 103 set_dependency_type, set_dependency_type) 104 104 105 def post_update(self, context):106 super(DependencyItem, self).post_update(context)107 108 from interface import InterfaceItem109 dependency_type = self._dependency_type110 c1 = self.head.connected_to111 if c1 and dependency_type is UML.Usage \112 and isinstance(c1, InterfaceItem) and c1.is_folded():113 self._dash_style = False114 else:115 self._dash_style = True116 105 117 106 def draw_head(self, context): 118 107 cr = context.cairo 119 if self._dash_style:108 if not self._solid: 120 109 cr.set_dash((), 0) 121 110 cr.move_to(15, -6) … … 126 115 127 116 def draw(self, context): 128 if self._dash_style:117 if not self._solid: 129 118 context.cairo.set_dash((7.0, 5.0), 0) 130 119 super(DependencyItem, self).draw(context) … … 132 121 @staticmethod 133 122 def is_usage(s): 134 """Return true if dependency should be usage dependency. 123 """ 124 Return true if dependency should be usage dependency. 135 125 """ 136 126 return isinstance(s, UML.Interface) … … 139 129 @staticmethod 140 130 def is_realization(ts, hs): 141 """Return true if dependency should be realization dependency. 131 """ 132 Return true if dependency should be realization dependency. 142 133 """ 143 134 return isinstance(ts, UML.Classifier) and isinstance(hs, UML.Component) gaphor/branches/ports/gaphor/diagram/classes/interface.py
r2378 r2428 1 1 """ 2 Interface item. 2 Interface item implementation. There are several notations supported 3 4 - class box with interface stereotype 5 - folded interface 6 - ball is drawn to indicate provided interface 7 - socket is drawn to indicate required interface 8 9 Folded Interface Item 10 ===================== 11 Folded interface notation is reserved for very simple situations. 12 When interface is folded 13 14 - only an implementation can be connected (ball - provided interface) 15 - or only usage dependency can be connected (socket - required interface) 16 - normal dependencies can be connected as well 17 18 Above means that interface cannot be folded when 19 20 - both, usage dependency and implementation are connected 21 - any other lines, beside normal dependecies, are connected 22 23 For examples, see 24 25 http://martinfowler.com/bliki/BallAndSocket.html 26 27 Folding and Connecting 28 ---------------------- 29 Current approach to folding and connecting lines to an interface is as 30 follows 31 32 - allow folding/unfolding of an interface only when there are _no_ lines 33 connected 34 - when interface is folded, allow only one implementation or depenedency 35 usage to be connected 36 - when interface is folded, allow normal dependencies to be connected as 37 well 38 39 Above solution is bit restrictive, for example we could allow folding when 40 there is only one implementation connected. Such solution would require 41 reconnection on appropriate ports, therefore it is postoned for now. 42 43 Folding and unfolding is performed by `InterfacePropertyPage` class. 3 44 """ 4 45 … … 7 48 from gaphas.item import NW, SE, NE, SW 8 49 from gaphas.state import observed, reversible_property 9 from gaphas.constraint import CenterConstraint, EqualsConstraint10 from gaphas.connector import Handle, PointPort11 50 12 51 from gaphor import UML 13 from dependency import DependencyItem14 from implementation import ImplementationItem15 52 from klass import ClassItem 16 53 from gaphor.diagram.nameditem import NamedItem … … 20 57 class InterfaceItem(ClassItem): 21 58 """ 22 This item represents an interface drawn as a dot. The class-like 23 representation is provided by ClassItem. These representations can be 24 switched by using the Fold and Unfold actions. 59 Interface item supporting class box and folded notations. 25 60 26 TODO (see also DependencyItem): when a Usage dependency is connected to 27 the interface, draw a line, but not all the way to the connecting 28 handle. Stop drawing the line 'x' points earlier. 61 When in folded mode, provided (ball) notation is used by default. 62 63 :Atributes: 64 folded 65 Check or set folded notation, see FOLDED_* constants. 29 66 """ 30 67 … … 51 88 RADIUS_REQUIRED = 14 52 89 90 # Non-folded mode. 91 FOLDED_NONE = 0 92 # Folded mode, provided (ball) notation. 93 FOLDED_PROVIDED = 1 94 # Folded mode, required (socket) notation. 95 FOLDED_REQUIRED = 2 96 97 53 98 def __init__(self, id=None): 54 99 ClassItem.__init__(self, id) 55 self._draw_required = False 56 self._draw_provided = False 57 58 h_ne, h_nw, h_sw, h_se = self._handles[:4] 59 60 # create additional connection ports for folded mode 61 h1 = Handle() 62 h2 = Handle() 63 h1.visible = False 64 h1.movable = False 65 h2.visible = False 66 h2.movable = False 67 p1 = PointPort(h1) 68 p2 = PointPort(h2) 69 p1.connectable = False 70 p2.connectable = False 71 72 # keep first port in the middle of the left edge 73 cc1 = CenterConstraint(a=h_ne.y, b=h_se.y, center=h1.y) 74 eq1 = EqualsConstraint(a=h_ne.x, b=h1.x) 75 # keep second port in the middle of the right edge 76 cc2 = CenterConstraint(a=h_nw.y, b=h_sw.y, center=h2.y) 77 eq2 = EqualsConstraint(a=h_nw.x, b=h2.x) 78 self._constraints.extend((cc1, eq1, cc2, eq2)) 79 80 self._handles.append(h1) 81 self._handles.append(h2) 82 self._ports.append(p1) 83 self._ports.append(p2) 100 self._folded = self.FOLDED_NONE 84 101 85 102 self.add_watch(UML.Interface.ownedAttribute, self.on_class_owned_attribute) … … 107 124 self.request_update() 108 125 126 109 127 drawing_style = reversible_property(lambda self: self._drawing_style, set_drawing_style) 110 128 111 def is_folded(self): 129 130 def _is_folded(self): 112 131 """ 113 Returns True if the interface is drawn as a circle/dot. 114 Unfolded means it's drawn like a classifier. 132 Check if interface item is folded interface item. 115 133 """ 116 return self. drawing_style == self.DRAW_ICON134 return self._folded 117 135 118 136 def _set_folded(self, folded): 119 if folded: 137 """ 138 Set folded notation. 139 140 :Parameters: 141 folded 142 Folded state, see FOLDED_* constants. 143 """ 144 if folded == self.FOLDED_NONE: 145 self.drawing_style = self.DRAW_COMPARTMENT 146 else: 120 147 self.drawing_style = self.DRAW_ICON 121 else: 122 self.drawing_style = self.DRAW_COMPARTMENT 148 self._folded = folded 123 149 124 folded = property( is_folded, _set_folded)150 folded = property(_is_folded, _set_folded) 125 151 126 152 def on_implementation_contract(self, event): … … 129 155 self.request_update() 130 156 157 131 158 def pre_update_icon(self, context): 132 159 """ 133 Figure out if this interface represents a required, provided, 134 assembled (wired) or dotted (minimal) look. 160 Change style to use icon style information. 135 161 """ 136 137 self._draw_required = self._draw_provided = False138 for item, handle in self.canvas.get_connected_items(self):139 if gives_required(item, handle):140 self._draw_required = True141 elif gives_provided(item, handle):142 self._draw_provided = True143 162 radius = self.RADIUS_PROVIDED 144 163 self.style.icon_size = self.style.icon_size_provided 145 if self._ draw_required:164 if self._folded == self.FOLDED_REQUIRED: 146 165 radius = self.RADIUS_REQUIRED 147 166 self.style.icon_size = self.style.icon_size_required … … 162 181 super(InterfaceItem, self).pre_update_icon(context) 163 182 183 164 184 def draw_icon(self, context): 165 185 cr = context.cairo 166 186 h_nw = self._handles[NW] 167 187 cx, cy = h_nw.x + self.width/2, h_nw.y + self.height/2 168 if self._ draw_required:188 if self._folded == self.FOLDED_REQUIRED: 169 189 cr.move_to(cx, cy + self.RADIUS_REQUIRED) 170 190 cr.arc_negative(cx, cy, self.RADIUS_REQUIRED, pi/2, pi*1.5) 171 191 cr.stroke() 172 if self._draw_provided or not self._draw_required:192 else: 173 193 cr.move_to(cx + self.RADIUS_PROVIDED, cy) 174 194 cr.arc(cx, cy, self.RADIUS_PROVIDED, 0, pi*2) … … 177 197 178 198 179 def gives_provided(item, handle):180 """181 Check if an item connected to an interface changes semantics of this182 interface to be provided.183 184 handle - handle of an item185 """186 return isinstance(item, ImplementationItem)187 188 189 def gives_required(item, handle):190 """191 Check if an item connected to an interface changes semantics of this192 interface to be required.193 194 handle - handle of an item195 TODO: check subject.clientDependency and subject.supplierDependency196 """197 # check for dependency item, interfaces is required if198 # - connecting handle is head one199 # - is in auto dependency200 # - if is not in auto dependency then its UML type is Usage201 return isinstance(item, DependencyItem) and item.handles()[0] == handle \202 and (not item.auto_dependency and item.dependency_type is UML.Usage203 or item.auto_dependency)204 205 206 199 # vim:sw=4:et
