Changeset 2428

Show
Ignore:
Timestamp:
10/09/08 12:02:29 (2 months ago)
Author:
wrobe..@pld-linux.org
Message:

- started to reimplement folded interface connections (not finished yet,

see bug #140 as well)

  • created specialized connectors to connect interface item with
    dependency or implementation
  • disallow folding/unfolding when there are any lines connected to an
    interface
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • gaphor/branches/ports/gaphor/adapters/__init__.py

    r2384 r2428  
    33import gaphor.adapters.editors 
    44 
     5import gaphor.adapters.classes.interfaceconnect 
     6 
     7import gaphor.adapters.components.connector 
     8 
    59import gaphor.adapters.states.vertexconnect 
    610import gaphor.adapters.states.propertypages 
    7  
    8 import gaphor.adapters.components.connector 
  • gaphor/branches/ports/gaphor/adapters/classes/tests/test_implementation.py

    • Property svn:mergeinfo set
    r2427 r2428  
    11""" 
    2 Test implementation (interfecae realization) item connectors. 
     2Test implementation (interface realization) item connectors. 
    33""" 
    44 
     
    5757 
    5858 
    59     def test_folded_interface_connection(self): 
    60         """Test connecting implementation to folded interface 
    61         """ 
    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._solid 
    67         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 interface 
    73         """ 
    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._solid 
    79         self.connect(impl, impl.head, iface) 
    80         assert impl._solid 
    81  
    82         self.disconnect(impl, impl.head) 
    83         self.assertTrue(not impl._solid) 
    84  
    8559 
    8660# vim:sw=4:et:ai 
  • gaphor/branches/ports/gaphor/adapters/connectors.py

    r2427 r2428  
    1717from gaphor.diagram.interfaces import IConnect 
    1818from gaphor.diagram import items 
    19 from gaphor.misc.ipair import ipair 
    2019 
    2120 
     
    458457                    ('implementatingClassifier', 'implementation')) 
    459458        self.line.subject = relation 
    460  
    461  
    462     def connect(self, handle, port): 
    463         """ 
    464         Implementation item can be changed to draw in solid mode, when 
    465         connected to folded interface. 
    466         """ 
    467  
    468         super(ImplementationConnect, self).connect(handle, port) 
    469         item = self.line.head.connected_to 
    470         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, then 
    477         draw in non-solid mode. 
    478         """ 
    479         super(ImplementationConnect, self).disconnect(handle) 
    480         if handle is self.line.head: 
    481             self.line._solid = False 
    482459 
    483460 
  • gaphor/branches/ports/gaphor/adapters/propertypages.py

    r2378 r2428  
    697697        # Fold toggle 
    698698        hbox = gtk.HBox() 
    699         label = gtk.Label(_("Fold")) 
     699        label = gtk.Label(_("Folded")) 
    700700        label.set_justify(gtk.JUSTIFY_LEFT) 
    701701        self.size_group.add_widget(label) 
    702702        hbox.pack_start(label, expand=False) 
     703 
    703704        button = gtk.CheckButton() 
    704705        button.set_active(self.context.folded) 
    705706        button.connect('toggled', self._on_fold_change) 
     707        item = self.context 
     708        button.set_sensitive(len(item.canvas.get_connected_items(item)) == 0) 
    706709        hbox.pack_start(button) 
    707710        hbox.show_all() 
     
    714717    @transactional 
    715718    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 
    728725 
    729726 
    730727component.provideAdapter(InterfacePropertyPage, name='Properties') 
     728 
    731729 
    732730 
  • gaphor/branches/ports/gaphor/diagram/classes/dependency.py

    r2255 r2428  
    6767        self._dependency_type = UML.Dependency 
    6868        self.auto_dependency = True 
    69         self._dash_style = Tru
     69        self._solid = Fals
    7070 
    7171    def save(self, save_func): 
     
    103103                               set_dependency_type, set_dependency_type) 
    104104 
    105     def post_update(self, context): 
    106         super(DependencyItem, self).post_update(context) 
    107  
    108         from interface import InterfaceItem 
    109         dependency_type = self._dependency_type 
    110         c1 = self.head.connected_to 
    111         if c1 and dependency_type is UML.Usage \ 
    112            and isinstance(c1, InterfaceItem) and c1.is_folded(): 
    113             self._dash_style = False 
    114         else: 
    115             self._dash_style = True 
    116105 
    117106    def draw_head(self, context): 
    118107        cr = context.cairo 
    119         if self._dash_style
     108        if not self._solid
    120109            cr.set_dash((), 0) 
    121110            cr.move_to(15, -6) 
     
    126115     
    127116    def draw(self, context): 
    128         if self._dash_style
     117        if not self._solid
    129118            context.cairo.set_dash((7.0, 5.0), 0) 
    130119        super(DependencyItem, self).draw(context) 
     
    132121    @staticmethod 
    133122    def is_usage(s): 
    134         """Return true if dependency should be usage dependency. 
     123        """ 
     124        Return true if dependency should be usage dependency. 
    135125        """ 
    136126        return isinstance(s, UML.Interface) 
     
    139129    @staticmethod 
    140130    def is_realization(ts, hs): 
    141         """Return true if dependency should be realization dependency. 
     131        """ 
     132        Return true if dependency should be realization dependency. 
    142133        """ 
    143134        return isinstance(ts, UML.Classifier) and isinstance(hs, UML.Component) 
  • gaphor/branches/ports/gaphor/diagram/classes/interface.py

    r2378 r2428  
    11""" 
    2 Interface item. 
     2Interface 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 
     9Folded Interface Item 
     10===================== 
     11Folded interface notation is reserved for very simple situations. 
     12When 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 
     18Above 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 
     23For examples, see 
     24 
     25    http://martinfowler.com/bliki/BallAndSocket.html 
     26 
     27Folding and Connecting 
     28---------------------- 
     29Current approach to folding and connecting lines to an interface is as 
     30follows 
     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 
     39Above solution is bit restrictive, for example we could allow folding when 
     40there is only one implementation connected. Such solution would require 
     41reconnection on appropriate ports, therefore it is postoned for now. 
     42 
     43Folding and unfolding is performed by `InterfacePropertyPage` class. 
    344""" 
    445 
     
    748from gaphas.item import NW, SE, NE, SW 
    849from gaphas.state import observed, reversible_property 
    9 from gaphas.constraint import CenterConstraint, EqualsConstraint 
    10 from gaphas.connector import Handle, PointPort 
    1150 
    1251from gaphor import UML 
    13 from dependency import DependencyItem 
    14 from implementation import ImplementationItem 
    1552from klass import ClassItem 
    1653from gaphor.diagram.nameditem import NamedItem 
     
    2057class InterfaceItem(ClassItem): 
    2158    """ 
    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. 
    2560 
    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. 
    2966    """ 
    3067 
     
    5188    RADIUS_REQUIRED = 14 
    5289 
     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 
    5398    def __init__(self, id=None): 
    5499        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 
    84101 
    85102        self.add_watch(UML.Interface.ownedAttribute, self.on_class_owned_attribute) 
     
    107124            self.request_update() 
    108125 
     126 
    109127    drawing_style = reversible_property(lambda self: self._drawing_style, set_drawing_style) 
    110128 
    111     def is_folded(self): 
     129 
     130    def _is_folded(self): 
    112131        """ 
    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. 
    115133        """ 
    116         return self.drawing_style == self.DRAW_ICON 
     134        return self._folded 
    117135 
    118136    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: 
    120147            self.drawing_style = self.DRAW_ICON 
    121         else: 
    122             self.drawing_style = self.DRAW_COMPARTMENT 
     148        self._folded = folded 
    123149 
    124     folded = property(is_folded, _set_folded) 
     150    folded = property(_is_folded, _set_folded) 
    125151 
    126152    def on_implementation_contract(self, event): 
     
    129155            self.request_update() 
    130156 
     157 
    131158    def pre_update_icon(self, context): 
    132159        """ 
    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. 
    135161        """ 
    136  
    137         self._draw_required = self._draw_provided = False 
    138         for item, handle in self.canvas.get_connected_items(self): 
    139             if gives_required(item, handle): 
    140                 self._draw_required = True 
    141             elif gives_provided(item, handle): 
    142                 self._draw_provided = True 
    143162        radius = self.RADIUS_PROVIDED 
    144163        self.style.icon_size = self.style.icon_size_provided 
    145         if self._draw_required
     164        if self._folded == self.FOLDED_REQUIRED
    146165            radius = self.RADIUS_REQUIRED 
    147166            self.style.icon_size = self.style.icon_size_required 
     
    162181        super(InterfaceItem, self).pre_update_icon(context) 
    163182 
     183 
    164184    def draw_icon(self, context): 
    165185        cr = context.cairo 
    166186        h_nw = self._handles[NW] 
    167187        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
    169189            cr.move_to(cx, cy + self.RADIUS_REQUIRED) 
    170190            cr.arc_negative(cx, cy, self.RADIUS_REQUIRED, pi/2, pi*1.5) 
    171191            cr.stroke() 
    172         if self._draw_provided or not self._draw_required
     192        else
    173193            cr.move_to(cx + self.RADIUS_PROVIDED, cy) 
    174194            cr.arc(cx, cy, self.RADIUS_PROVIDED, 0, pi*2) 
     
    177197 
    178198 
    179 def gives_provided(item, handle): 
    180     """ 
    181     Check if an item connected to an interface changes semantics of this 
    182     interface to be provided. 
    183  
    184     handle - handle of an item 
    185     """ 
    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 this 
    192     interface to be required. 
    193  
    194     handle - handle of an item 
    195     TODO: check subject.clientDependency and subject.supplierDependency 
    196     """ 
    197     # check for dependency item, interfaces is required if 
    198     # - connecting handle is head one 
    199     # - is in auto dependency 
    200     # - if is not in auto dependency then its UML type is Usage 
    201     return isinstance(item, DependencyItem) and item.handles()[0] == handle \ 
    202         and (not item.auto_dependency and item.dependency_type is UML.Usage 
    203             or item.auto_dependency) 
    204  
    205  
    206199# vim:sw=4:et