Changeset 1001
- Timestamp:
- 09/07/06 00:28:11 (2 years ago)
- Files:
-
- gaphas/trunk/ChangeLog (modified) (1 diff)
- gaphas/trunk/demo.py (modified) (3 diffs)
- gaphas/trunk/gaphas/examples.py (modified) (3 diffs)
- gaphas/trunk/gaphas/tool.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
gaphas/trunk/ChangeLog
r999 r1001 3 3 * item.py, canvas.py: item removal (with connected handles) solved, 4 4 use a callback method on the handle. 5 * demo.py, examples.py: Moved handle tool hacks into a nice example 6 handle tool class. 5 7 6 8 2006-09-06 Arjan Molenaar <arjan_at_yirdis_dot_nl> gaphas/trunk/demo.py
r999 r1001 13 13 import gtk 14 14 from gaphas import Canvas, View 15 from gaphas.examples import Box, Text 15 from gaphas.examples import Box, Text, DefaultExampleTool 16 16 from gaphas.item import Line, NW, SE 17 17 from gaphas.tool import PlacementTool, HandleTool 18 from gaphas.constraint import LineConstraint19 from gaphas.geometry import point_on_rectangle, distance_rectangle_point20 21 DEFAULT_POINTER = gtk.gdk.LEFT_PTR22 23 24 def handle_tool_glue(self, view, item, handle, wx, wy):25 """MixIn method for HandleTool. It allows the tool to glue26 to a Box or (other) Line item.27 The distance from the item to the handle is determined in canvas28 coordinates, using a 10 pixel glue distance.29 """30 if not handle.connectable:31 return32 matrix_w2i = view.canvas.get_matrix_w2i33 matrix_i2w = view.canvas.get_matrix_i2w34 35 # Make glue distance depend on the zoom ratio (should be about 10 pixels)36 glue_distance, dummy = view.transform_distance_c2w(10, 0)37 glue_point = None38 glue_item = None39 for i in view.canvas.get_all_items():40 if not i is item:41 ix, iy = matrix_w2i(i).transform_point(wx, wy)42 try:43 distance, point = i.glue(item, handle, ix, iy)44 #print distance, point45 # Transform distance to world coordinates46 distance, dumy = matrix_i2w(i).transform_distance(distance, 0)47 if distance < glue_distance:48 glue_distance = distance49 glue_point = matrix_i2w(i).transform_point(*point)50 glue_item = i51 except AttributeError:52 pass53 if glue_point:54 handle.x, handle.y = matrix_w2i(item).transform_point(*glue_point)55 return glue_item56 57 HandleTool.glue = handle_tool_glue58 59 60 def handle_tool_connect(self, view, item, handle, wx, wy):61 """Connect a handle to another item.62 63 In this "method" the following assumptios are made:64 1. The only item that accepts handle connections are the MyBox instances65 2. The only items with connectable handles are Line's66 67 """68 def side(handle, glued):69 hx, hy = view.canvas.get_matrix_i2w(item).transform_point(handle.x, handle.y)70 ax, ay = view.canvas.get_matrix_i2w(glued).transform_point(glued.handles()[0].x, glued.handles()[0].y)71 bx, by = view.canvas.get_matrix_i2w(glued).transform_point(glued.handles()[2].x, glued.handles()[2].y)72 if abs(hx - ax) < 0.01:73 side = 374 elif abs(hy - ay) < 0.01:75 side = 076 elif abs(hx - bx) < 0.01:77 side = 178 else:79 side = 280 return side81 82 #print 'Handle.connect', view, item, handle, wx, wy83 glue_item = self.glue(view, item, handle, wx, wy)84 if glue_item and glue_item is handle.connected_to:85 s = side(handle, glue_item)86 view.canvas.solver.remove_constraint(handle._connect_constraint)87 handle._connect_constraint = LineConstraint(view.canvas, glue_item, glue_item.handles()[s], glue_item.handles()[(s+1)%4], item, handle)88 view.canvas.solver.add_constraint(handle._connect_constraint)89 def handle_disconnect():90 view.canvas.solver.remove_constraint(handle._connect_constraint)91 handle._connect_constraint = None92 handle.disconnect = handle_disconnect93 return94 95 # drop old connetion96 if handle.connected_to:97 # remove constraints98 try:99 view.canvas.solver.remove_constraint(handle._connect_constraint)100 except AttributeError:101 pass # no _connect_constraints attribute102 handle._connect_constraint = None103 handle.connected_to = None104 105 if glue_item:106 if isinstance(glue_item, MyBox):107 s = side(handle, glue_item)108 # Make a constraint that keeps into account item coordinates.109 handle._connect_constraint = LineConstraint(view.canvas, glue_item, glue_item.handles()[s], glue_item.handles()[(s+1)%4], item, handle)110 view.canvas.solver.add_constraint(handle._connect_constraint)111 handle.connected_to = glue_item112 113 114 HandleTool.connect = handle_tool_connect115 116 117 def handle_tool_disconnect(self, view, item, handle):118 if handle.connected_to:119 #print 'Handle.disconnect', view, item, handle120 handle._connect_constraint.disabled = True121 122 HandleTool.disconnect = handle_tool_disconnect123 124 18 125 19 class MyBox(Box): … … 127 21 """ 128 22 129 def glue(self, item, handle, x, y):130 h = self._handles131 hnw = h[NW]132 hse = h[SE]133 r = (float(hnw.x), float(hnw.y), float(hse.x), float(hse.y))134 por = point_on_rectangle(r, (x, y), border=True)135 #print 'Point', r, (x, y), por136 return distance_rectangle_point(r, (x, y)), por137 138 def constrain(self, handle, x, y):139 pass140 23 141 24 class MyLine(Line): … … 153 36 def create_window(canvas, zoom=1.0): 154 37 view = View() 155 38 view.tool = DefaultExampleTool() 39 156 40 w = gtk.Window() 157 41 h = gtk.HBox() gaphas/trunk/gaphas/examples.py
r945 r1001 9 9 from item import NW, NE,SW, SE 10 10 from solver import solvable 11 11 import tool 12 from constraint import LineConstraint 13 from geometry import point_on_rectangle, distance_rectangle_point 12 14 13 15 class Box(Element): … … 34 36 context.draw_children() 35 37 38 def glue(self, item, handle, x, y): 39 """Special glue method used by the ConnectingHandleTool to find 40 a connection point. 41 """ 42 h = self._handles 43 hnw = h[NW] 44 hse = h[SE] 45 r = (float(hnw.x), float(hnw.y), float(hse.x), float(hse.y)) 46 por = point_on_rectangle(r, (x, y), border=True) 47 #print 'Point', r, (x, y), por 48 return distance_rectangle_point(r, (x, y)), por 49 36 50 37 51 class Text(Item): 52 """Simple item shoring some text on the canvas. 53 """ 38 54 39 55 def __init__(self): … … 49 65 return 0 50 66 67 68 class ConnectingHandleTool(tool.HandleTool): 69 """This is a HandleTool which supports a simple connection algerithm, 70 Using LineConstraint. 71 """ 72 73 def glue(self, view, item, handle, wx, wy): 74 """It allows the tool to glue to a Box or (other) Line item. 75 The distance from the item to the handle is determined in canvas 76 coordinates, using a 10 pixel glue distance. 77 """ 78 if not handle.connectable: 79 return 80 matrix_w2i = view.canvas.get_matrix_w2i 81 matrix_i2w = view.canvas.get_matrix_i2w 82 83 # Make glue distance depend on the zoom ratio (should be about 10 pixels) 84 glue_distance, dummy = view.transform_distance_c2w(10, 0) 85 glue_point = None 86 glue_item = None 87 for i in view.canvas.get_all_items(): 88 if not i is item: 89 ix, iy = matrix_w2i(i).transform_point(wx, wy) 90 try: 91 distance, point = i.glue(item, handle, ix, iy) 92 #print distance, point 93 # Transform distance to world coordinates 94 distance, dumy = matrix_i2w(i).transform_distance(distance, 0) 95 if distance < glue_distance: 96 glue_distance = distance 97 glue_point = matrix_i2w(i).transform_point(*point) 98 glue_item = i 99 except AttributeError: 100 pass 101 if glue_point: 102 handle.x, handle.y = matrix_w2i(item).transform_point(*glue_point) 103 return glue_item 104 105 def connect(self, view, item, handle, wx, wy): 106 """Connect a handle to another item. 107 108 In this "method" the following assumptios are made: 109 1. The only item that accepts handle connections are the Box instances 110 2. The only items with connectable handles are Line's 111 112 """ 113 def side(handle, glued): 114 hx, hy = view.canvas.get_matrix_i2w(item).transform_point(handle.x, handle.y) 115 ax, ay = view.canvas.get_matrix_i2w(glued).transform_point(glued.handles()[0].x, glued.handles()[0].y) 116 bx, by = view.canvas.get_matrix_i2w(glued).transform_point(glued.handles()[2].x, glued.handles()[2].y) 117 if abs(hx - ax) < 0.01: 118 side = 3 119 elif abs(hy - ay) < 0.01: 120 side = 0 121 elif abs(hx - bx) < 0.01: 122 side = 1 123 else: 124 side = 2 125 return side 126 127 128 def handle_disconnect(): 129 try: 130 view.canvas.solver.remove_constraint(handle._connect_constraint) 131 except KeyError: 132 pass # constraint was alreasy removed 133 handle._connect_constraint = None 134 handle.connected_to = None 135 # Remove disconnect handler: 136 handle.disconnect = lambda: 0 137 138 #print 'Handle.connect', view, item, handle, wx, wy 139 glue_item = self.glue(view, item, handle, wx, wy) 140 if glue_item and glue_item is handle.connected_to: 141 s = side(handle, glue_item) 142 view.canvas.solver.remove_constraint(handle._connect_constraint) 143 handle._connect_constraint = LineConstraint(view.canvas, glue_item, glue_item.handles()[s], glue_item.handles()[(s+1)%4], item, handle) 144 view.canvas.solver.add_constraint(handle._connect_constraint) 145 handle.disconnect = handle_disconnect 146 return 147 148 # drop old connetion 149 if handle.connected_to: 150 handle.disconnect() 151 152 if glue_item: 153 if isinstance(glue_item, Box): 154 s = side(handle, glue_item) 155 # Make a constraint that keeps into account item coordinates. 156 handle._connect_constraint = LineConstraint(view.canvas, glue_item, glue_item.handles()[s], glue_item.handles()[(s+1)%4], item, handle) 157 view.canvas.solver.add_constraint(handle._connect_constraint) 158 handle.connected_to = glue_item 159 handle.disconnect = handle_disconnect 160 161 def disconnect(self, view, item, handle): 162 if handle.connected_to: 163 #print 'Handle.disconnect', view, item, handle 164 view.canvas.solver.remove_constraint(handle._connect_constraint) 165 166 167 def DefaultExampleTool(): 168 """The default tool chain build from HoverTool, ItemTool and HandleTool. 169 """ 170 chain = tool.ToolChain() 171 chain.append(tool.HoverTool()) 172 chain.append(ConnectingHandleTool()) 173 chain.append(tool.ItemTool()) 174 chain.append(tool.TextEditTool()) 175 chain.append(tool.RubberbandTool()) 176 return chain 177 178 51 179 if __name__ == '__main__': 52 180 import doctest gaphas/trunk/gaphas/tool.py
r994 r1001 298 298 299 299 class HandleTool(Tool): 300 """Tool for moving handles around. By default this tool does not provide 301 connecting handles to another item (see examples.ConnectingHandleTool for 302 an example). 303 """ 300 304 301 305 def __init__(self):
