root/gaphas/tags/release-0.1.2/README.txt

Revision 1161, 7.1 kB (checked in by arjanmol, 2 years ago)

Fixed bug in canvas add/remove undo, fixed typos in docs and added more tests. Version bump to 0.1.2.

  • Property svn:keywords set to Revision HeadURL
Line 
1 Gaphor Canvas
2 =============
3
4 This module contains a new canvas implementation for Gaphor.
5
6 The basic idea is:
7
8  - Items (canvas items) should be used as "adapter" for model elements.
9    (not a real adapter since they are statefull).
10  - The canvas determines the tree structure (which items are children
11    of some other item is maintained by the canvas itself).
12  - of course the constraint solver is present.
13  - more modular: e.g. handle support could be swapped in and swapped out.
14  - rendering using Cairo.
15
16
17 To do
18 =====
19
20 This is it as far as stage 1 is concerned. I have implemented:
21  v a render cycle.
22  v zoom and move functionality (canvas2world).
23  v scroll-bars work.
24  v a set of tools and a ToolChain (to chain them together).
25  v rubberband selection
26
27 Stage 2:
28  v check the code with pylint for strange things.
29  v line item
30  v placement tool
31  v connection protocol
32  v make update cycle independent from render (expose) event.
33     This is something we might do if the response is getting bad.
34  ? rotating and shearing for Element items.
35     Do we need this?
36
37 Stage 3:
38  v make double and triple click work.
39  v text edit tool (gtk.Edit in popup window?)
40
41 Stage n:
42  - Drop-zone tool
43      the idea is that for example you have a Package and when you drag
44      a Class into it it automatically makes the Package its owning element.
45  v undo management
46
47
48 How it Works
49 ============
50
51 The Canvas class (from canvas.py) acts as a container for Item's (from item.py).
52 The item's parent/child relationships are maintained here (not in the Item!).
53
54 An Item can have a set of Handle's (also from item.py) which can be used to
55 manipulate the item (although this is not necessary). Each item has it's own
56 coordinate system (a (0, 0) point). Item.matrix is the transformation
57 relative to the parent item of the Item, as defined in the Canvas.
58
59 The Canvas also contains a constraint Solver (from solver.py) that can be used
60 to solve mathematical dependencies between items (such as Handles that should
61 be aligned).
62
63 View (from view.py) is used to visualize a canvas. On a View, a Tool
64 (from tool.py) can be assigned, which will handle user input (button presses,
65 key presses, etc.). Painters (from painter.py) are used to do the actual
66 drawing. This way it should be easy do draw to other media than the screen,
67 such as a printer or PDF document.
68
69 Updating item state
70 -------------------
71 If an items needs updating, it sets out an update request on the Canvas
72 (Canvas.request_update for a full update or Canvas.request_matrix_update() if
73 only the transformation matrix has changed). The canvas performs an update by
74 calling:
75
76  1. Item.pre_update(context)
77  2. updating World-to-Item matrices, for fast transformation of coordinates
78     from the world to the items' coordinate system.
79     The w2i matrix is stored on the Item as Item._matrix_w2i.
80  3. solve constraints
81  4. updating World-to-Item matrices again, just to be on the save side.
82  5. Item.update(context)
83
84 The idea is to do as much updating as possible in the (pre_)update() methods,
85 since they are called when the application is not handling user input.
86
87 The context contains:
88
89  parent:   parent item of the item, or None
90  children: child items of this item (do not need to force updates for those)
91  cairo:    a CairoContext, this can be used to calculate the dimensions of text
92            for example
93
94 NOTE: updating is done from the canvas, items should not update sub-items.
95
96 After an update, the Item should be ready top be drawn.
97
98 Drawing
99 -------
100 Drawing is done by the View. It calls the draw(context) method for each *root*
101 item in the canvas. Items should instruct the engine to draw sub-item (children)
102 by calling context.draw_children().
103
104 In addition to draw_children(), the context has the following properties:
105
106  view:     the view we're drawing to
107  cairo:    the CairoContext to draw to
108  parent:   parent item of the item, or None
109  children: child items of this item (do not need to force updates for those)
110  selected: True if the item is actually selected in the view
111  focused:  True if the item has the focus
112  hovered:  True if the mouse pointer if over the item. Only the top-most item
113            is marked as hovered.
114  draw_all: True if everything drawable on the item should be drawn (e.g. when
115            calculating the bounding boxes).
116
117 The View automatically calculates the bounding box for the item, based on the
118 items drawn in the draw(context) function (this is only done once after each
119 Item.update()). The bounding box is stored on the item as Item._view_bounds
120 as a geometry.Rectangle object. The bounding box is in viewport coordinates.
121
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 DefaultTool
130 HandleTool
131 ChainTool (connect behavior of tools)
132
133
134 Interaction
135 -----------
136 Interaction with the canvas view (visual component) is handled by tools.
137 Although the default tools do a fair amount of work, in most cases you'll
138 see that especially the way items connect with each other is not the way
139 you want it. That's okay. HandleTool provides some hooks (connect, disconnect and glue) to implement custom connection behavior (in fact, the default implementation doesn't do any connecting at all!).
140
141 One of the problems you'll face is what to do when an item is removed from the
142 canvas and there are other items (lines) connected to. This problem can be
143 solved by providing a disconnect handler to the handle instance ones it is
144 connected. A callable object (e.g. function) can be assigned to the handle. It
145 is called at the moment the item it's connected to is removed from the canvas.
146
147
148 Undo
149 ====
150
151 Gaphas has a simple build-in system for registering changes in it's classes and
152 notifying the application. This code resides in state.py.
153
154 There is also a "reverter" framework in place. This "framework" is notified
155 when objects change their state and will figure out the reverse operation that
156 has to be applied in order to undo the operation.
157
158 See state.txt and undo.txt for details and usage examples.
159
160
161 Files
162 =====
163
164 Canvas independent classes:
165
166 tree.py:
167         Central tree structure (no more CanvasGroupable)
168 solver.py:
169         A constraint solver (infinite domain, based on diacanvas2's solver)
170 constraint.py:
171         Constraint implementation.
172 geometry.py:
173         Matrix, Rectangle calculations.
174
175 Canvas classes:
176
177 item.py:
178         Canvas item and handle
179 canvas.py:
180         Canvas class
181 view.py:
182         Canvas view (renderer) class
183 tool.py:
184         Base class for Tools (which handle events on the view).
185
186 Other:
187
188 examples.py:
189         Simple example classes.
190
191 Guidelines
192 ----------
193 Following the Python coding guidelines
194 <http://www.python.org/dev/peps/pep-0008/> indentation should be 4 spaces
195 (no tabs), function and method names should be lowercase_with_underscore(),
196 and files should contain a __version__ property, like this:
197
198   __version__ = "$Revision$"
199   # $HeadURL$
200
201 It should be placed after the module docstring.
202
203 This inhibits that for each .py file, the svn:keywords property should be set
204 to "Revision HeadURL". This can be done manually:
205
206   $ svn propset svn:keywords "Revision HeadURL" myfile.py
207
208 or by configuring your ~/.subversion/config file to use auto-props:
209
210   [miscellany]
211   # ...
212   enable-auto-props = yes
213
214   [auto-props]
215   # ...
216   *.py = svn:keywords=Revision HeadURL
217
218
Note: See TracBrowser for help on using the browser.