merged tag ooo/DEV300_m102
[LibreOffice.git] / toolkit / test / accessibility / Canvas.java
bloba1d8fb0f7d08b755f0afb0bb7796c6de395508eb
1 import java.util.*;
2 import java.awt.*;
3 import java.awt.event.*;
4 import javax.swing.*;
5 import javax.swing.tree.*;
6 import javax.swing.event.TreeSelectionListener;
7 import javax.swing.event.TreeSelectionEvent;
8 import java.awt.geom.Rectangle2D;
10 import com.sun.star.accessibility.XAccessible;
11 import com.sun.star.accessibility.XAccessibleContext;
12 import com.sun.star.accessibility.XAccessibleComponent;
14 /** This canvas displays accessible objects graphically. Each accessible
15 object with graphical representation is represented by an
16 CanvasShape object and has to be added by the
17 <member>addAccessible</member> member function.
19 <p>The canvas listens to selection events of the associated JTree and
20 highlights the first selected node of that tree.</p>
22 class Canvas
23 extends JPanel
24 implements MouseListener, MouseMotionListener, TreeSelectionListener//, Scrollable
26 // This constant can be passed to SetZoomMode to always show the whole screen.
27 public static final int WHOLE_SCREEN = -1;
29 public Canvas ()
31 super (true);
32 maObjects = new java.util.HashMap ();
33 maNodes = new Vector ();
34 maObjectList = new Vector ();
35 maContexts = new Vector ();
36 addMouseListener (this);
37 addMouseMotionListener (this);
38 maBoundingBox = new Rectangle (0,0,100,100);
39 maTree = null;
40 mnHOffset = 0;
41 mnVOffset = 0;
42 mnScale = 1;
43 setShowText(false);
44 setShowDescriptions (true);
45 setShowNames (true);
46 setAntialiasing (true);
47 maLastWidgetSize = new Dimension (0,0);
50 /** Tell the canvas which tree view to use to highlight accessible
51 objects.
53 public void setTree (JTree aTree)
55 if (maTree != null)
56 maTree.removeTreeSelectionListener (this);
57 maTree = aTree;
58 if (maTree != null)
59 maTree.addTreeSelectionListener (this);
65 public void addNode (AccTreeNode aNode)
67 if (maNodes.indexOf (aNode) == -1)
69 maNodes.add (aNode);
71 CanvasShape aObject = (CanvasShape) maObjects.get (aNode);
72 if (aObject == null)
74 aObject = new CanvasShape (aNode);
75 // Update bounding box that includes all objects.
76 if (maObjects.size() == 0)
77 maBoundingBox = aObject.getBBox();
78 else
79 maBoundingBox = maBoundingBox.union (aObject.getBBox());
81 maObjects.put (aNode, aObject);
82 maObjectList.add (aObject);
85 repaint ();
89 public void removeNode (AccTreeNode aNode)
91 int i = maNodes.indexOf (aNode);
92 if( i != -1 )
94 Object aObject = maObjects.get(aNode);
95 maObjectList.remove (aObject);
96 maObjects.remove (aObject);
97 maNodes.remove (aNode);
98 repaint ();
102 public void updateNode (AccTreeNode aNode)
104 int i = maNodes.indexOf (aNode);
105 if (i != -1)
107 CanvasShape aObject = (CanvasShape)maObjects.get(aNode);
108 if (aObject != null)
109 aObject.update();
113 public void updateNodeGeometry (AccTreeNode aNode)
115 CanvasShape aObject = (CanvasShape)maObjects.get(aNode);
116 if (aObject != null)
117 aObject.updateGeometry();
120 public void clear ()
122 while (maNodes.size() > 0)
123 removeNode ((AccTreeNode)maNodes.elementAt(0));
125 maNodes.clear();
126 maObjects.clear();
127 maObjectList.clear();
130 public boolean getShowDescriptions ()
132 return Options.GetBoolean ("ShowDescriptions");
135 public void setShowDescriptions (boolean bNewValue)
137 Options.SetBoolean ("ShowDescriptions", bNewValue);
138 repaint ();
141 public boolean getShowNames ()
143 return Options.GetBoolean ("ShowNames");
146 public void setShowNames (boolean bNewValue)
148 Options.SetBoolean ("ShowNames", bNewValue);
149 repaint ();
152 public boolean getAntialiasing ()
154 return Options.GetBoolean ("Antialiasing");
157 public void setAntialiasing (boolean bNewValue)
159 Options.SetBoolean ("Antialiasing", bNewValue);
160 repaint ();
163 public boolean getShowText ()
165 return Options.GetBoolean ("ShowText");
168 public void setShowText (boolean bNewValue)
170 Options.SetBoolean ("ShowText", bNewValue);
171 repaint ();
174 public void setZoomMode (int nZoomMode)
176 Options.SetInteger ("ZoomMode", nZoomMode);
177 repaint ();
180 public int getZoomMode ()
182 return Options.GetInteger ("ZoomMode", WHOLE_SCREEN);
186 public void paintComponent (Graphics g)
188 synchronized (g)
190 super.paintComponent (g);
192 Graphics2D g2 = (Graphics2D)g;
193 if (getAntialiasing())
194 g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING,
195 RenderingHints.VALUE_ANTIALIAS_ON);
196 else
197 g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING,
198 RenderingHints.VALUE_ANTIALIAS_OFF);
200 setupTransformation ();
202 // Draw the screen representation to give a hint of the location of the
203 // accessible object on the screen.
204 Dimension aScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
205 Rectangle2D.Double aScreen = new Rectangle2D.Double (
206 mnHOffset,
207 mnVOffset,
208 mnScale*aScreenSize.getWidth(),
209 mnScale*aScreenSize.getHeight());
210 // Fill the screen rectangle and draw a frame arround it to increase its visibility.
211 g2.setColor (new Color (250,240,230));
212 g2.fill (aScreen);
213 g2.setColor (Color.BLACK);
214 g2.draw (aScreen);
216 synchronized (maObjectList)
218 int nCount = maObjectList.size();
219 boolean bShowDescriptions = getShowDescriptions();
220 boolean bShowNames = getShowNames();
221 boolean bShowText = getShowText();
222 for (int i=0; i<nCount; i++)
224 CanvasShape aCanvasShape = (CanvasShape)maObjectList.elementAt(i);
225 aCanvasShape.paint (
227 mnHOffset, mnVOffset, mnScale,
228 bShowDescriptions, bShowNames, bShowText);
232 // Paint highlighted frame around active object as the last thing.
233 if (maActiveObject != null)
234 maActiveObject.paint_highlight (
236 mnHOffset, mnVOffset, mnScale);
243 /** Set up the transformation so that the graphical display can show a
244 centered representation of the whole screen.
246 private void setupTransformation ()
248 // Turn off scrollbars when showing the whole screen. Otherwise show them when needed.
249 JViewport aViewport = (JViewport)getParent();
250 JScrollPane aScrollPane = (JScrollPane)aViewport.getParent();
251 int nZoomMode = getZoomMode();
252 if (nZoomMode == WHOLE_SCREEN)
254 if (aScrollPane.getHorizontalScrollBarPolicy()
255 != JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)
256 aScrollPane.setHorizontalScrollBarPolicy (JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
257 if (aScrollPane.getVerticalScrollBarPolicy()
258 != JScrollPane.VERTICAL_SCROLLBAR_NEVER)
259 aScrollPane.setVerticalScrollBarPolicy (JScrollPane.VERTICAL_SCROLLBAR_NEVER);
261 else
263 if (aScrollPane.getHorizontalScrollBarPolicy()
264 != JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED)
265 aScrollPane.setHorizontalScrollBarPolicy (JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
266 if (aScrollPane.getVerticalScrollBarPolicy()
267 != JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
268 aScrollPane.setVerticalScrollBarPolicy (JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
271 Dimension aScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
272 Dimension aWidgetSize = aViewport.getSize();
274 if ((aScreenSize.getWidth() > 0) && (aScreenSize.getHeight() > 0))
276 if (nZoomMode == WHOLE_SCREEN)
278 // Calculate the scales that would map the screen onto the
279 // widget in both of the coordinate axes and select the
280 // smaller
281 // of the two: it maps the screen onto the widget in both
282 // axes at the same time.
283 double nHScale = (aWidgetSize.getWidth() - 10) / aScreenSize.getWidth();
284 double nVScale = (aWidgetSize.getHeight() - 10) / aScreenSize.getHeight();
285 if (nHScale < nVScale)
286 mnScale = nHScale;
287 else
288 mnScale = nVScale;
290 else
292 mnScale = nZoomMode / 100.0;
295 // Calculate offsets that center the scaled screen inside the widget.
296 mnHOffset = (aWidgetSize.getWidth() - mnScale*aScreenSize.getWidth()) / 2.0;
297 mnVOffset = (aWidgetSize.getHeight() - mnScale*aScreenSize.getHeight()) / 2.0;
298 if (mnHOffset < 0)
299 mnHOffset = 0;
300 if (mnVOffset < 0)
301 mnVOffset = 0;
303 setPreferredSize (new Dimension (
304 (int)(2*mnHOffset + mnScale * aScreenSize.getWidth()),
305 (int)(2*mnVOffset + mnScale * aScreenSize.getHeight())));
306 revalidate ();
308 else
310 // In case of a degenerate (not yet initialized?) screen size
311 // use some meaningless default values.
312 mnScale = 1;
313 mnHOffset = 0;
314 mnVOffset = 0;
317 maLastWidgetSize = aWidgetSize;
322 /** Call getAccessibleAt to determine accessible object under mouse.
324 public void mouseClicked (MouseEvent e)
328 public void mousePressed (MouseEvent e)
330 CanvasShape aObjectUnderMouse = FindCanvasShapeUnderMouse (e);
331 highlightObject (aObjectUnderMouse);
332 if ((e.getModifiers() & InputEvent.CTRL_MASK) != 0)
334 maTree.expandPath (aObjectUnderMouse.getPath());
338 public void mouseReleased (MouseEvent e)
342 public void mouseEntered (MouseEvent e)
346 public void mouseExited (MouseEvent e)
348 // Deselect currently active object.
349 if (maActiveObject != null)
351 maActiveObject.unhighlight ();
352 maActiveObject = null;
353 repaint ();
357 public void mouseDragged (MouseEvent e)
361 public void mouseMoved (MouseEvent e)
363 if ((e.getModifiers() & InputEvent.SHIFT_MASK) != 0)
364 highlightObject (FindCanvasShapeUnderMouse (e));
367 protected CanvasShape FindCanvasShapeUnderMouse (MouseEvent e)
369 int nObjects = maObjects.size();
370 CanvasShape aObjectUnderMouse = null;
371 int nCount = maObjectList.size();
372 for (int i=nCount-1; i>=0; --i)
374 CanvasShape aObject = (CanvasShape)maObjectList.elementAt(i);
375 if (aObject != null)
376 if (aObject.contains (e.getX(),e.getY()))
378 aObjectUnderMouse = aObject;
379 break;
382 return aObjectUnderMouse;
385 protected boolean highlightObject (CanvasShape aNewActiveObject)
387 if (aNewActiveObject != maActiveObject)
389 if (maActiveObject != null)
390 maActiveObject.unhighlight();
392 maActiveObject = aNewActiveObject;
393 if (maActiveObject != null)
395 if (maTree != null)
397 maTree.scrollPathToVisible (maActiveObject.getPath());
398 maTree.setSelectionPath (maActiveObject.getPath());
399 maTree.repaint ();
401 maActiveObject.highlight ();
402 repaint ();
404 return true;
406 else
407 return false;
410 /** Called when the selection of the tree changes. Highlight the
411 corresponding graphical representation of the first selected object.
413 public void valueChanged (javax.swing.event.TreeSelectionEvent event)
415 TreePath aPath = event.getPath();
416 Object aObject = aPath.getLastPathComponent();
417 if (aObject instanceof AccTreeNode)
419 CanvasShape aCanvasShape = (CanvasShape)maObjects.get ((AccTreeNode)aObject);
420 if (highlightObject (aCanvasShape))
421 repaint();
425 private int
426 mnXAnchor,
427 mnYAnchor,
428 maResizeFlag;
429 private double
430 mnHOffset,
431 mnVOffset,
432 mnScale;
433 private CanvasShape
434 maActiveObject;
435 private java.util.HashMap
436 maObjects;
437 private Vector
438 maObjectList,
439 maContexts,
440 maNodes;
441 private Rectangle
442 maBoundingBox;
443 private JTree
444 maTree;
445 // The size of the widget at the last call of setupTransformation()
446 private Dimension
447 maLastWidgetSize;