/[skencil]/skencil/trunk/Sketch/Editor/edittool.py
ViewVC logotype

Contents of /skencil/trunk/Sketch/Editor/edittool.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 504 - (show annotations)
Sat Dec 10 23:58:06 2005 UTC (17 years, 4 months ago) by bherzog
File MIME type: text/x-python
File size: 13106 byte(s)
Remove unused imports

1 # Sketch - A Python-based interactive drawing program
2 # Copyright (C) 2004, 2005 by Bernhard Herzog
3 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 by Bernhard Herzog
4 #
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Library General Public
7 # License as published by the Free Software Foundation; either
8 # version 2 of the License, or (at your option) any later version.
9 #
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Library General Public License for more details.
14 #
15 # You should have received a copy of the GNU Library General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19
20 import Sketch
21 from Sketch import Point, ContAngle, ContSmooth, ContSymmetrical, Bezier, \
22 Line
23 from Sketch.Base.const import SelectDrag, SELECTION, HANDLES
24 from Sketch.Editor import AddEditorBuiltin, PolyBezierEditor
25 import const
26 import tools
27 from selectiontool import SelectionRectangle
28
29 class MultiEditor:
30
31 def __init__(self):
32 self.editors = []
33 self.editormap = {}
34 self.offsets = []
35 self.drag = []
36 self.active = 0
37 self.undo = None
38
39 def UpdateEditors(self, selection):
40 self.editors = []
41 oldmap = self.editormap
42 self.editormap = {}
43 GetEditor = Sketch.Editor.GetEditor
44 for obj in selection.GetObjects():
45 if oldmap.has_key(id(obj)):
46 editor = oldmap[id(obj)]
47 else:
48 editor = GetEditor(obj)
49 if editor is not None:
50 self.editors.append(editor)
51 self.editormap[id(obj)] = editor
52 self.active = 0
53
54 def ButtonDown(self, p, button, state):
55 if not self.editors:
56 return None
57 offsets = []
58 drag = []
59 for editor in self.editors:
60 if editor.HasSelection():
61 drag.append(1)
62 off = editor.ButtonDown(p, button, state)
63 else:
64 drag.append(0)
65 off = None
66 if off is None:
67 off = Point(0, 0)
68 offsets.append(off)
69 off = offsets[self.active]
70 for i in range(len(offsets)):
71 offsets[i] = off - offsets[i]
72 self.offsets = offsets
73 self.drag = drag
74 return off
75
76 def MouseMove(self, p, state):
77 drag = self.drag
78 for i in range(len(self.editors)):
79 if drag[i]:
80 self.editors[i].MouseMove(p + self.offsets[i], state)
81
82 def ButtonUp(self, p, button, state):
83 undo = []
84 drag = self.drag
85 for i in range(len(self.editors)):
86 if drag[i]:
87 info = self.editors[i].ButtonUp(p + self.offsets[i], button,
88 state)
89 if info is not None:
90 undo.append(info)
91 return Sketch.Base.CreateListUndo(undo)
92
93 def Handles(self):
94 handles = []
95 for i in range(len(self.editors)):
96 h = self.editors[i].GetHandles()
97 for tmp in h:
98 tmp.editor = i
99 handles.extend(h)
100 return handles
101
102 def SelectHandle(self, handle, mode):
103 self.active = handle.editor
104 change = self.editors[self.active].SelectHandle(handle, mode)
105 if change == const.SelectSingle:
106 editors = self.editors[:]
107 del editors[self.active]
108 for editor in editors:
109 editor.SelectNone()
110
111 def SelectPoint(self, p, device, mode):
112 rect = device.HitRectAroundPoint(p)
113 point_selected = False
114 for i, editor in enumerate(self.editors):
115 if editor.SelectPoint(p, rect, device, mode):
116 self.active = i
117 point_selected = True
118 return point_selected
119
120 def SelectRect(self, rect, mode):
121 for editor in self.editors:
122 editor.SelectRect(rect, mode)
123
124 def DrawDragged(self, device, partially):
125 drag = self.drag
126 for i in range(len(self.editors)):
127 if drag[i]:
128 self.editors[i].DrawDragged(device, partially)
129
130 def Show(self, device, partially = 0):
131 drag = self.drag
132 for i in range(len(self.editors)):
133 if drag[i]:
134 self.editors[i].Show(device, partially)
135
136 def Hide(self, device, partially = 0):
137 drag = self.drag
138 for i in range(len(self.editors)):
139 if drag[i]:
140 self.editors[i].Hide(device, partially)
141
142 def CurrentInfoText(self):
143 if self.editors:
144 return self.editors[self.active].CurrentInfoText()
145 else:
146 return ""
147
148
149
150 class EditToolInstance(tools.ToolInstance):
151
152 title = ''"Edit"
153
154 def __init__(self, editor):
155 tools.ToolInstance.__init__(self, editor)
156 self.editor.Subscribe(SELECTION, self.selection_changed)
157 self.multiedit = MultiEditor()
158 self.get_editors()
159
160 def End(self):
161 self.editor.Unsubscribe(SELECTION, self.selection_changed)
162 tools.ToolInstance.End(self)
163
164 def selection_changed(self):
165 self.get_editors()
166
167 def get_editors(self):
168 self.multiedit.UpdateEditors(self.editor.Selection())
169
170 def ButtonPress(self, context, p, snapped, button, state, handle = None):
171 tools.ToolInstance.ButtonPress(self, context, p, snapped, button,
172 state, handle = handle)
173 object = None
174 hide_handles = 1
175 if handle is not None:
176 # The user pressed the button over a handle. Prepare to drag
177 # at the handle
178 self.multiedit.SelectHandle(handle, SelectDrag)
179 object = self.multiedit
180 else:
181 test = context.test_device()
182 test.StartOutlineMode()
183 if self.editor.SelectionHit(p, test, test_all = 0) \
184 and self.multiedit.SelectPoint(p, test, SelectDrag):
185 # The user pressed the button over an already selected object.
186 # Prepare to edit/transform the current selection
187 self.multiedit.SelectPoint(p, test, SelectDrag)
188 object = self.multiedit
189 else:
190 pick = self.editor.PickActiveObject(test, p)
191 if pick is not None and pick.is_GuideLine:
192 # edit guide line
193 object = Sketch.Editor.GuideEditor(pick)
194 test.EndOutlineMode()
195
196 # if no object has been found to be edited, start a
197 # rubberbanding selection
198 if object is None:
199 object = SelectionRectangle(p)
200 hide_handles = 0
201
202 self.begin_edit_object(context, object, snapped, button, state,
203 hide_handles = hide_handles)
204
205 def ButtonRelease(self, context, p, snapped, button, state):
206 tools.ToolInstance.ButtonRelease(self, context, p, snapped, button,
207 state)
208 object = self.end_edit_object(context, snapped, button, state)
209 if isinstance(object, SelectionRectangle):
210 self.multiedit.SelectRect(object.bounding_rect,
211 tools.selection_type(state))
212 self.editor.update_handles()
213
214 def ButtonClick(self, context, p, snapped, button, state, handle = None):
215 tools.ToolInstance.ButtonClick(self, context, p, snapped, button,
216 state, handle = handle)
217 mode = tools.selection_type(state)
218 if handle is not None:
219 self.multiedit.SelectHandle(handle, mode)
220 self.editor.update_handles()
221 else:
222 test = context.test_device()
223 test.StartOutlineMode()
224 hit = self.editor.SelectionHit(p, test, test_all = 0)
225 test.EndOutlineMode()
226 if hit:
227 self.multiedit.SelectPoint(p, test, mode)
228 self.editor.update_handles()
229 else:
230 self.editor.SelectPoint(p, test, mode)
231
232 def CallObjectEditorMethod(self, aclass, methodname, *args):
233 for objecteditor in self.multiedit.editors:
234 if isinstance(objecteditor, aclass):
235 self.document.BeginTransaction()
236 obmethod = getattr(objecteditor, methodname)
237 undo = obmethod(*args)
238 if undo is not None:
239 self.document.AddUndo(undo)
240 self.document.EndTransaction()
241 self.editor.update_handles()
242
243 def Handles(self):
244 if self.editor.HasSelection():
245 handles = self.multiedit.Handles()
246 else:
247 handles = []
248 return handles
249
250 EditTool = tools.ToolInfo("EditTool", EditToolInstance, cursor = 'CurEdit',
251 active_cursor = 1)
252
253 # PolyBezier commands
254 def check_polybezier_method(context, methodname, *args):
255 """Return true if EditTool is active, there is at least a PolyBezier
256 selected and calling methodname on PolyBezierEditor returns True.
257 """
258 can = 0
259 editor = context.editor
260 tool = editor.Tool()
261 if isinstance(tool, EditToolInstance) and context.tool == 'EditTool' and \
262 editor.HasSelection():
263 for objeditor in tool.multiedit.editors:
264 if isinstance(objeditor, PolyBezierEditor):
265 checkmethod = getattr(objeditor, methodname)
266 if checkmethod(*args):
267 can = 1
268 break
269 return can
270
271 def call_polybezier_method(context, method, *args):
272 tool = context.editor.Tool()
273 if isinstance(tool, EditToolInstance):
274 tool.CallObjectEditorMethod(PolyBezierEditor, method, *args)
275
276 AddEditorBuiltin('cont_angle', ''"Angle",
277 call_polybezier_method, ('SetContinuity', ContAngle),
278 sensitive = lambda context: check_polybezier_method(context,
279 'CanSetContinuity', ContAngle),
280 channels = (HANDLES,))
281 AddEditorBuiltin('cont_smooth', ''"Smooth",
282 call_polybezier_method, ('SetContinuity', ContSmooth),
283 sensitive = lambda context: check_polybezier_method(context,
284 'CanSetContinuity', ContSmooth),
285 channels = (HANDLES,))
286 AddEditorBuiltin('cont_symmetrical', ''"Symmetrical",
287 call_polybezier_method, ('SetContinuity', ContSymmetrical),
288 sensitive = lambda context: check_polybezier_method(context,
289 'CanSetContinuity', ContSymmetrical),
290 channels = (HANDLES,))
291 AddEditorBuiltin('segments_to_lines', ''"Segments To Lines",
292 call_polybezier_method, ('SegmentsToLines',),
293 sensitive = lambda context: check_polybezier_method(context,
294 'CanConvertSegments', Line),
295 channels = (HANDLES,))
296 AddEditorBuiltin('segments_to_curve', ''"Segments To Curves",
297 call_polybezier_method, ('SegmentsToCurve',),
298 sensitive = lambda context: check_polybezier_method(context,
299 'CanConvertSegments', Bezier),
300 channels = (HANDLES,))
301 AddEditorBuiltin('select_all_nodes', ''"Select All Nodes",
302 call_polybezier_method, ('SelectAllNodes',),
303 sensitive = lambda context: check_polybezier_method(context,
304 'CanSelectAllNodes'),
305 channels = (HANDLES,))
306 AddEditorBuiltin('delete_nodes', ''"Delete Nodes",
307 call_polybezier_method, ('DeleteNodes',),
308 sensitive = lambda context: check_polybezier_method(context,
309 'CanDeleteNodes'),
310 channels = (HANDLES,))
311 AddEditorBuiltin('insert_nodes', ''"Insert Nodes",
312 call_polybezier_method, ('InsertNodes',),
313 sensitive = lambda context: check_polybezier_method(context,
314 'CanInsertNodes'),
315 channels = (HANDLES,))
316 AddEditorBuiltin('close_nodes', ''"Close Nodes",
317 call_polybezier_method, ('CloseNodes',),
318 sensitive = lambda context: check_polybezier_method(context,
319 'CanCloseNodes'),
320 channels = (HANDLES,))
321 AddEditorBuiltin('open_nodes', ''"Cut Curve",
322 call_polybezier_method, ('OpenNodes',),
323 sensitive = lambda context: check_polybezier_method(context,
324 'CanOpenNodes'),
325 channels = (HANDLES,))

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

root@scm.wald.intevation.org
ViewVC Help
Powered by ViewVC 1.1.26