1
2
3
4
5
6
7
8
9
10
11
12 package sk.uniba.euromath.editor;
13 import javax.xml.transform.Source;
14 import javax.xml.transform.dom.DOMSource;
15
16 import org.eclipse.draw2d.Graphics;
17 import org.eclipse.draw2d.IFigure;
18 import org.eclipse.draw2d.geometry.Dimension;
19 import org.eclipse.draw2d.geometry.Point;
20
21 import sk.baka.ikslibs.ObjectSource;
22 import sk.baka.ikslibs.modify.DOMChangeCollector;
23 import sk.baka.ikslibs.modify.IChangeCollector;
24 import sk.baka.ikslibs.splitted.SplittedDocHolder;
25 import sk.uniba.euromath.editor.figures.IEMFigure;
26 import sk.uniba.euromath.gene.RendererContext;
27 /***
28 * <p>
29 * Renderer produces graphical representation of given data. Displays nodes from
30 * one namespace only. For each nametree present in transformed document a
31 * separate instance of renderer is constructed.
32 * </p>
33 * <p>
34 * First the {@link #init(Source, RendererContext)} method is called to
35 * initialize the renderer. After the initialization the renderer must be able
36 * to provide drawing size, figures, and must be able to paint itself on a
37 * <code>Graphics</code> instance. {@link #reinit(IChangeCollector)} may be
38 * called at any time to inform renderer of partial data change.
39 * </p>
40 * <p>
41 * Renderer can support only two kinds of sources: the
42 * {@link javax.xml.transform.dom.DOMSource DOMSource} and
43 * {@link ObjectSource ObjectSource}:
44 * </p>
45 * <ul>
46 * <li>They can be easily accessed multiple times without modification</li>
47 * <li>Changes can be managed easily</li>
48 * </ul>
49 * <p>
50 * Instance of renderer is always used by a single thread - it should not be
51 * synchronized, resulting in faster execution.
52 * </p>
53 * @author Tomáš Studva, Martin Vysny
54 */
55 public interface IRenderer {
56 /***
57 * <p>
58 * Initializes the renderer. Called as the first method (only the
59 * {@link #offerObject()} and {@link #getInfo()} methods may be called
60 * before this method). Renderer should prepare {@link IFigure} instances
61 * for future rendering.
62 * </p>
63 * <p>
64 * If an element from another namespace occurs ({@link SplittedDocHolder#PI_GENEREF_TARGET generef}
65 * processing instruction in case of {@link DOMSource} - you can retrieve id
66 * using {@link SplittedDocHolder#getRef(org.w3c.dom.Node)} function, or a
67 * custom object type in case of <code>ObjectSource</code>), the
68 * following steps are to be taken:
69 * </p>
70 * <ol>
71 * <li>Renderer must query the context instance using this ID. It then
72 * receives the child renderer's canvas size.</li>
73 * <li>Renderer must leave place for each child renderer canvas somewhere
74 * on its canvas, during the rendering process. It is not recommended to
75 * paint anything into that area - it gets covered by a
76 * <code>Composite</code> widget.</li>
77 * <li>After the init ends, the renderer can be queried at any time for the
78 * child renderer placement using the {@link #getPlacement(String)} method.</li>
79 * </ol>
80 * @param transformedDoc fragment of document, <code>DOMSource</code> or
81 * <code>ObjectSource</code> instance. This nametree is to be rendered by
82 * the renderer. Renderer is encouraged to throw any exception including
83 * <code>ClassCastException</code> if it encounters illegal objects, to
84 * detect invalid objects quickly and cleanly.
85 * @param context the context instance, allows you to ask for child
86 * renderers output, etc.
87 * @throws EditorException if initialization fails.
88 */
89 public void init(Source transformedDoc, RendererContext context)
90 throws EditorException;
91 /***
92 * Returns point, relative to renderer's canvas, where canvas of child
93 * renderer will be positioned.
94 * @param id the child nametree's ID.
95 * @return point, may be <code>null</code> if the child renderer's canvas
96 * is not visible (not placed anywhere).
97 */
98 public Point getPlacement(final String id);
99 /***
100 * <p>
101 * Reinitialize the renderer when a partial change of the rendered document
102 * occurs. Renderer should discard IFigures no longer needed, and prepare
103 * new IFigures. This <code>changed</code> object is given to an editor
104 * when this method finishes, to allow the editor to query for new figures.
105 * </p>
106 * @param changes defines changed elements. Has appropriate type for
107 * <code>transformedDoc</code> parameter, i.e. {@link DOMChangeCollector}
108 * for {@link javax.xml.transform.dom.DOMSource} etc. Contains source with
109 * all changes already applied.
110 * @throws EditorException if error occurs.
111 */
112 public void reinit(IChangeCollector changes) throws EditorException;
113 /***
114 * Retrieves size of area where the rendering occurs.
115 * @return dimension in pixels, never <code>null</code>.
116 * @throws EditorException if error occurs.
117 */
118 public Dimension getCanvasSize() throws EditorException;
119 /***
120 * Retrieves figure that displays given data object. The figure may contain
121 * child figures when required.
122 * @param o the data object, may be any object instance when transformed
123 * document is in form of <code>ObjectSource</code>, or a
124 * {@link org.w3c.dom.Node} instance otherwise.
125 * @return root of view
126 */
127 public IEMFigure getFigure(Object o);
128 /***
129 * Retrieves the root figure, where all figures will be placed.
130 * @return root of rendered view.
131 */
132 public IEMFigure getRootFigure();
133 /***
134 * <p>
135 * Paint rendered view to <code>Graphics</code>. Use the context object
136 * to let the children renderers to paint.
137 * </p>
138 * @param g paint onto this graphics instance.
139 * @throws EditorException if error occurs.
140 */
141 public void render(final Graphics g) throws EditorException;
142 /***
143 * <p>
144 * When the renderer accepts the ObjectSource but wants to provide an object
145 * as a result (for example it wants the document producer to draw something
146 * in a certain instance of Graphics), then return non-null value. If this
147 * functionality is not needed then just return <code>null</code> - if the
148 * document producer requires some object then it can create any object as
149 * long as it is instance of class that this exporter expects.
150 * </p>
151 * <p>
152 * The consumer (the one that receives the object, i.e. this) is responsible
153 * for freeing the object if necessary (at the end of the export method),
154 * even if this function returned <code>null</code>.
155 * </p>
156 * <p>
157 * If you want producer (the one that creates the object) to create custom
158 * instances then provide a factory object. This trick is used with
159 * <code>http://www.uniba.sk/euromath/holder/java.awt.Graphics</code>
160 * holder - a factory is returned that is able to produce
161 * <code>java.awt.Graphics</code> instances.
162 * </p>
163 * <p>
164 * This method can be called anytime, and is usually called before
165 * {@link #init(Source, RendererContext)}.
166 * </p>
167 * @return the object instance, or <code>null</code>.
168 */
169 public Object offerObject();
170 /***
171 * Returns instance of {@link RendererInfo} able to create this renderer.
172 * @return the info object for this renderer.
173 */
174 public RendererInfo getInfo();
175 /***
176 * Constructs new instance of preprocessor.
177 * @return new instance of preprocessor. If <code>null</code> then no
178 * preprocessor is needed and will be ignored.
179 */
180 public IInputPreprocessor createPreprocessor();
181 }