root/gaphas/tags/gaphas-0.3.2/README.txt

Revision 1855, 9.3 kB (checked in by arj..@yirdis.nl, 1 year ago)

clarified readme text

  • Property svn:keywords set to Revision HeadURL
Line 
1 Gaphor's Canvas
2 ===============
3
4 This module contains a new canvas implementation for Gaphor.
5
6 The basic idea is:
7
8 - Items (canvas items) can be added to a Canvas.
9 - The canvas maintains the tree structure (parent-child relationships between
10   items).
11 - A constraint solver is used to maintain item constraints and inter-item
12   constraints.
13 - The item (and user) should not be bothered with things like bounding-box
14   calculations.
15 - Very modular: e.g. handle support could be swapped in and swapped out.
16 - Rendering using Cairo.
17
18  Gaphas is released under the terms of the GNU Library General Public License
19  (LGPL). See the COPYING file for details.
20
21 .. contents::
22
23 How it Works
24 ============
25
26 The Canvas class (from canvas.py) acts as a container for Item's (from item.py).
27 The item's parent/child relationships are maintained here (not in the Item!).
28
29 An Item can have a set of Handle's (also from item.py) which can be used to
30 manipulate the item (although this is not necessary). Each item has it's own
31 coordinate system (a (0, 0) point). Item.matrix is the transformation
32 relative to the parent item of the Item, as defined in the Canvas.
33
34 The Canvas also contains a constraint Solver (from solver.py) that can be used
35 to solve mathematical dependencies between items (such as Handles that should
36 be aligned). The constraint solver is also a handy tool to keep constraint
37 in the item true (e.g. make sure a box maintains it's rectangular shape).
38
39 View (from view.py) is used to visualize a canvas. On a View, a Tool
40 (from tool.py) can be applied, which will handle user input (button presses,
41 key presses, etc.). Painters (from painter.py) are used to do the actual
42 drawing. This way it should be easy do draw to other media than the screen,
43 such as a printer or PDF document.
44
45 Updating item state
46 -------------------
47 If an items needs updating, it sets out an update request on the Canvas
48 (Canvas.request_update()). The canvas performs an update by calling:
49
50 1. Item.pre_update(context) for each item marked for update
51 2. Updating Canvas-to-Item matrices, for fast transformation of coordinates
52    from the canvas' to the items' coordinate system.
53    The c2i matrix is stored on the Item as Item._matrix_c2i.
54 3. Solve constraints.
55 4. Normalize items by setting the coordinates of the first handle to (0, 0).
56 5. Updating Canavs-to-Item matrices for items that have been changed by
57    normalizarion, just to be on the save side.
58 6. Item.post_update(context) for each item marked for update, including items
59    that have been marked during constraint solving.
60
61 The idea is to do as much updating as possible in the {pre|post}_update()
62 methods, since they are called when the application is not handling user input.
63
64 The context contains:
65
66 :cairo: a CairoContext, this can be used to calculate the dimensions of text
67         for example
68
69 NOTE: updating is done from the canvas, items should not update sub-items.
70
71 After an update, the Item should be ready to be drawn.
72
73 Constraint solving
74 ------------------
75 A word about the constraint solver seems in place. It is one of the big
76 features of this library after all. The Solver is able to solve constraints.
77 Constraints can be applied to items (e.g. the Element item uses constraints to
78 maintain it's recangular shape) and constraints can be created *between* items
79 (for example a line that connects to a box).
80
81 Constaints that apply to one item are pretty straight forward, as all variables
82 live in the same coordinate system (of the item). The variables (in most cases
83 a Handle's x and y coordinate) can simply be put in a constraint.
84
85 When two items are connected to each other and constraints are created, a
86 problem shows up: variables live in separate coordinate systems. To overcome
87 this problem a Projection (from solver.py) has been defined. With a Projection
88 instance, a variable can be "projected" on another coordinate system. In this
89 case, where two items are connecting to each other, the Canvas' coordinate
90 system is used.
91
92
93 Drawing
94 -------
95 Drawing is done by the View. All items marked for redraw (e.i. the items
96 that had been updated) will be drawn in the order in which they reside in the
97 Canvas (first root item, then it's children; second root item, etc.)
98
99 There used to be a draw_children() method in the view context. This method
100 has been rendered obsolete (mainly to speed up drawing).
101 The view context passed to the Items draw() method has the following properties:
102
103 :view:     the view we're drawing to
104 :cairo:    the CairoContext to draw to
105 :selected: True if the item is actually selected in the view
106 :focused:  True if the item has the focus
107 :hovered:  True if the mouse pointer if over the item. Only the top-most item
108            is marked as hovered.
109 :dropzone: The item is marked as drop zone. This happens then an item is
110            dragged over the item and (if dropped) will become a child of
111            this item.
112 :draw_all: True if everything drawable on the item should be drawn (e.g. when
113            calculating the bounding boxes).
114
115 The View automatically calculates the bounding box for the item, based on the
116 items drawn in the draw(context) function (this is only done when really
117 necessary, e.g. after an update of the item). The bounding box is in viewport
118 coordinates.
119
120 The actual drawing is done by Painters (painter.py). A series of Painters have
121 been defined: one for handles, one for items, etc.
122
123 Tools
124 -----
125 Behavior is added to the canvas(-view) by tools.
126
127 Tools can be chained together in order to provide more complex behavior.
128
129 To make it easy a DefaultTool has been defined: a ToolChain instance with the
130 tools added that are listed in the following sections.
131
132 ToolChain
133     The ToolChain does not do anything by itself. It delegates to a set of
134     tools and keeps track of which tool has grabbed the focus. This happens
135     most of the time when the uses presses a mouse button. The tool requests a
136     grab() and all upcoming events (e.g. motion or button release events) are
137     directly sent to the focused tool.
138
139 HoverTool
140     A small and simple tool that does nothing more than making the item under
141     the mouse button the "hovered item". When such an item is drawn, its
142     context.hovered_item flag will be set to True.
143
144 HandleTool
145     The HandleTool is used to deal with handles. Handles can be dragged around.
146     Clicking on a handle automatically makes the underlaying item the focused
147     item.
148
149 ItemTool
150     The item tool takes care of selecting items and dragging items around.
151
152 TextEditTool
153     This is a demo-tool, featuring a text-edit popup.
154
155 RubberbandTool
156     The last toolin line is the rubberband tool. It's invoked when the mouse
157     button is pressed on a section of the view where no items or handles are
158     present. It allows the user to select items using a selection box
159     (rubberband).
160
161
162 Interaction
163 -----------
164 Interaction with the canvas view (visual component) is handled by tools.
165 Although the default tools do a fair amount of work, in most cases you'll
166 see that especially the way items connect with each other is not the way
167 you want it. That's okay. HandleTool provides some hooks (connect, disconnect
168 and glue) to implement custom connection behavior (in fact, the default
169 implementation doesn't do any connecting at all!).
170
171 One of the problems you'll face is what to do when an item is removed from the
172 canvas and there are other items (lines) connected to. This problem can be
173 overcome by providing a disconnect handler to the handle instance ones it is
174 connected. A callable object (e.g. function) can be assigned to the handle. It
175 is called at the moment the item it's connected to is removed from the canvas.
176
177
178 Undo
179 ====
180
181 Gaphas has a simple build-in system for registering changes in it's classes and
182 notifying the application. This code resides in state.py.
183
184 There is also a "reverter" framework in place. This "framework" is notified
185 when objects change their state and will figure out the reverse operation that
186 has to be applied in order to undo the operation.
187
188 See state.txt and undo.txt for details and usage examples.
189
190
191 Files
192 =====
193
194 Canvas independent classes:
195
196 tree.py:
197     Central tree structure (no more CanvasGroupable)
198 solver.py:
199     A constraint solver (infinite domain, based on diacanvas2's solver)
200 constraint.py:
201     Constraint implementation.
202 geometry.py:
203     Matrix, Rectangle calculations.
204 quadtree.py:
205     A QuadTree spacial index. Used in the View to pick items quickly.
206
207 Canvas classes:
208
209 item.py:
210     Canvas item and handle
211 canvas.py:
212     Canvas class
213 view.py:
214     Canvas view (renderer) class
215 tool.py:
216     Base class for Tools (which handle events on the view).
217
218 Other:
219
220 examples.py:
221     Simple example classes.
222
223 Guidelines
224 ==========
225 Following the `Python coding guidelines`_ indentation should be 4 spaces
226 (no tabs), function and method names should be ``lowercase_with_underscore()``,
227 and files should contain a ``__version__`` property, like this::
228
229   __version__ = "$Revision$"
230   # $HeadURL$
231
232 It should be placed after the module docstring.
233
234 This inhibits that for each .py file, the svn:keywords property should be set
235 to ``Revision HeadURL``. This can be done manually::
236
237   $ svn propset svn:keywords "Revision HeadURL" myfile.py
238
239 or by configuring your ~/.subversion/config file to use auto-props::
240
241   [miscellany]
242   # ...
243   enable-auto-props = yes
244
245   [auto-props]
246   # ...
247   *.py = svn:keywords=Revision HeadURL
248
249
250 .. _Python coding guidelines: http://www.python.org/dev/peps/pep-0008/
Note: See TracBrowser for help on using the browser.