134dd1e25SAndrew Rist /**************************************************************
234dd1e25SAndrew Rist  *
334dd1e25SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
434dd1e25SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
534dd1e25SAndrew Rist  * distributed with this work for additional information
634dd1e25SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
734dd1e25SAndrew Rist  * to you under the Apache License, Version 2.0 (the
834dd1e25SAndrew Rist  * "License"); you may not use this file except in compliance
934dd1e25SAndrew Rist  * with the License.  You may obtain a copy of the License at
1034dd1e25SAndrew Rist  *
1134dd1e25SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1234dd1e25SAndrew Rist  *
1334dd1e25SAndrew Rist  * Unless required by applicable law or agreed to in writing,
1434dd1e25SAndrew Rist  * software distributed under the License is distributed on an
1534dd1e25SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1634dd1e25SAndrew Rist  * KIND, either express or implied.  See the License for the
1734dd1e25SAndrew Rist  * specific language governing permissions and limitations
1834dd1e25SAndrew Rist  * under the License.
1934dd1e25SAndrew Rist  *
2034dd1e25SAndrew Rist  *************************************************************/
2134dd1e25SAndrew Rist 
2234dd1e25SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir import javax.swing.*;
25cdf0e10cSrcweir import java.awt.Dimension;
26cdf0e10cSrcweir import java.awt.*;
27cdf0e10cSrcweir import java.awt.geom.*;
28cdf0e10cSrcweir 
29cdf0e10cSrcweir import com.sun.star.accessibility.XAccessible;
30cdf0e10cSrcweir import com.sun.star.accessibility.XAccessibleContext;
31cdf0e10cSrcweir import com.sun.star.accessibility.XAccessibleComponent;
32cdf0e10cSrcweir 
33cdf0e10cSrcweir import com.sun.star.awt.Point;
34cdf0e10cSrcweir import com.sun.star.awt.Size;
35cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime;
36cdf0e10cSrcweir 
37cdf0e10cSrcweir 
38cdf0e10cSrcweir /** Display the currently focused accessible object graphically.
39cdf0e10cSrcweir */
40cdf0e10cSrcweir public class GraphicalDisplay
41cdf0e10cSrcweir     extends JPanel
42cdf0e10cSrcweir     implements IAccessibleObjectDisplay
43cdf0e10cSrcweir {
44cdf0e10cSrcweir     /** Create a new graphical widget the displays some of the geometrical
45cdf0e10cSrcweir         information availbable from accessible objects.
46cdf0e10cSrcweir     */
GraphicalDisplay()47cdf0e10cSrcweir     public GraphicalDisplay ()
48cdf0e10cSrcweir     {
49cdf0e10cSrcweir         setPreferredSize (new Dimension (300,200));
50cdf0e10cSrcweir     }
51cdf0e10cSrcweir 
52cdf0e10cSrcweir 
53cdf0e10cSrcweir     /** Paint some or all of the area of this widget with the outlines of
54cdf0e10cSrcweir         the currently focues object and its ancestors.
55cdf0e10cSrcweir      */
paintComponent(Graphics g)56cdf0e10cSrcweir     public synchronized void paintComponent (Graphics g)
57cdf0e10cSrcweir     {
58cdf0e10cSrcweir         super.paintComponent (g);
59cdf0e10cSrcweir 
60cdf0e10cSrcweir         setupTransformation ();
61cdf0e10cSrcweir 
62cdf0e10cSrcweir         // Draw the screen representation to give a hint of the location of the
63cdf0e10cSrcweir         // accessible object on the screen.
64cdf0e10cSrcweir         Dimension aScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
65cdf0e10cSrcweir         // Fill the screen rectangle.
66cdf0e10cSrcweir         g.setColor (new Color (250,240,230));
67cdf0e10cSrcweir         g.fillRect (
68cdf0e10cSrcweir             (int)(mnHOffset+0.5),
69cdf0e10cSrcweir             (int)(mnVOffset+0.5),
70cdf0e10cSrcweir             (int)(mnScale*aScreenSize.getWidth()),
71cdf0e10cSrcweir             (int)(mnScale*aScreenSize.getHeight()));
72*a893be29SPedro Giffuni         // Draw a frame around the screen rectangle to increase its visibility.
73cdf0e10cSrcweir         g.setColor (Color.BLACK);
74cdf0e10cSrcweir         g.drawRect (
75cdf0e10cSrcweir             (int)(mnHOffset+0.5),
76cdf0e10cSrcweir             (int)(mnVOffset+0.5),
77cdf0e10cSrcweir             (int)(mnScale*aScreenSize.getWidth()),
78cdf0e10cSrcweir             (int)(mnScale*aScreenSize.getHeight()));
79cdf0e10cSrcweir 
80cdf0e10cSrcweir         // Now do the actual display of the accessible object.
81cdf0e10cSrcweir         drawAccessibleObject (g, mxContext, Color.GREEN);
82cdf0e10cSrcweir     }
paintChildren(Graphics g)83cdf0e10cSrcweir     public synchronized void paintChildren (Graphics g)
84cdf0e10cSrcweir     {
85cdf0e10cSrcweir     }
paintBorder(Graphics g)86cdf0e10cSrcweir     public synchronized void paintBorder (Graphics g)
87cdf0e10cSrcweir     {
88cdf0e10cSrcweir     }
89cdf0e10cSrcweir 
90cdf0e10cSrcweir 
91cdf0e10cSrcweir 
92cdf0e10cSrcweir 
93cdf0e10cSrcweir     /** Draw a simple representation of the given accessible object in the
94cdf0e10cSrcweir         specified color.
95cdf0e10cSrcweir     */
drawAccessibleObject(Graphics g, XAccessibleContext xContext, Color aColor)96cdf0e10cSrcweir     public void drawAccessibleObject (Graphics g, XAccessibleContext xContext, Color aColor)
97cdf0e10cSrcweir     {
98cdf0e10cSrcweir         if (xContext != null)
99cdf0e10cSrcweir         {
100cdf0e10cSrcweir             // First draw our parent.
101cdf0e10cSrcweir             XAccessible xParent = xContext.getAccessibleParent();
102cdf0e10cSrcweir             if (xParent != null)
103cdf0e10cSrcweir                 drawAccessibleObject (g, xParent.getAccessibleContext(), Color.GRAY);
104cdf0e10cSrcweir 
105cdf0e10cSrcweir             // When the context supports the XAccessibleComponent interface
106cdf0e10cSrcweir             // then draw its outline.
107cdf0e10cSrcweir             XAccessibleComponent xComponent =
108cdf0e10cSrcweir                 (XAccessibleComponent)UnoRuntime.queryInterface(
109cdf0e10cSrcweir                     XAccessibleComponent.class, xContext);
110cdf0e10cSrcweir             if (xComponent != null)
111cdf0e10cSrcweir             {
112cdf0e10cSrcweir                 // Get size and location on screen and transform them to fit
113cdf0e10cSrcweir                 // everything inside this widget.
114cdf0e10cSrcweir                 Point aLocation = xComponent.getLocationOnScreen();
115cdf0e10cSrcweir                 Size aSize = xComponent.getSize();
116cdf0e10cSrcweir                 g.setColor (aColor);
117cdf0e10cSrcweir                 g.drawRect (
118cdf0e10cSrcweir                     (int)(mnHOffset + mnScale*aLocation.X+0.5),
119cdf0e10cSrcweir                     (int)(mnVOffset + mnScale*aLocation.Y+0.5),
120cdf0e10cSrcweir                     (int)(mnScale*aSize.Width),
121cdf0e10cSrcweir                     (int)(mnScale*aSize.Height));
122cdf0e10cSrcweir             }
123cdf0e10cSrcweir         }
124cdf0e10cSrcweir     }
125cdf0e10cSrcweir 
126cdf0e10cSrcweir 
setAccessibleObject(XAccessibleContext xContext)127cdf0e10cSrcweir     public synchronized void setAccessibleObject (XAccessibleContext xContext)
128cdf0e10cSrcweir     {
129cdf0e10cSrcweir         mxContext = xContext;
130cdf0e10cSrcweir         repaint ();
131cdf0e10cSrcweir     }
132cdf0e10cSrcweir 
updateAccessibleObject(XAccessibleContext xContext)133cdf0e10cSrcweir     public synchronized void updateAccessibleObject (XAccessibleContext xContext)
134cdf0e10cSrcweir     {
135cdf0e10cSrcweir         repaint ();
136cdf0e10cSrcweir     }
137cdf0e10cSrcweir 
138cdf0e10cSrcweir 
139cdf0e10cSrcweir     /** Set up the transformation so that the graphical display can show a
140cdf0e10cSrcweir         centered representation of the whole screen.
141cdf0e10cSrcweir     */
setupTransformation()142cdf0e10cSrcweir     private void setupTransformation ()
143cdf0e10cSrcweir     {
144cdf0e10cSrcweir         Dimension aScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
145cdf0e10cSrcweir         Dimension aWidgetSize = getSize();
146cdf0e10cSrcweir         if ((aScreenSize.getWidth() > 0) && (aScreenSize.getHeight() > 0))
147cdf0e10cSrcweir         {
148cdf0e10cSrcweir             // Calculate the scales that would map the screen onto the
149cdf0e10cSrcweir             // widget in both of the coordinate axes and select the smaller
150cdf0e10cSrcweir             // of the two: it maps the screen onto the widget in both axes
151cdf0e10cSrcweir             // at the same time.
152cdf0e10cSrcweir             double nHScale = (aWidgetSize.getWidth() - 10) / aScreenSize.getWidth();
153cdf0e10cSrcweir             double nVScale = (aWidgetSize.getHeight() - 10) / aScreenSize.getHeight();
154cdf0e10cSrcweir             if (nHScale < nVScale)
155cdf0e10cSrcweir                 mnScale = nHScale;
156cdf0e10cSrcweir             else
157cdf0e10cSrcweir                 mnScale = nVScale;
158cdf0e10cSrcweir 
159cdf0e10cSrcweir             // Calculate offsets that center the scaled screen inside the widget.
160cdf0e10cSrcweir             mnHOffset = (aWidgetSize.getWidth() - mnScale*aScreenSize.getWidth()) / 2.0;
161cdf0e10cSrcweir             mnVOffset = (aWidgetSize.getHeight() - mnScale*aScreenSize.getHeight()) / 2.0;
162cdf0e10cSrcweir         }
163cdf0e10cSrcweir         else
164cdf0e10cSrcweir         {
165cdf0e10cSrcweir             // In case of a degenerate (not yet initialized?) screen size
166cdf0e10cSrcweir             // use some meaningless default values.
167cdf0e10cSrcweir             mnScale = 1;
168cdf0e10cSrcweir             mnHOffset = 0;
169cdf0e10cSrcweir             mnVOffset = 0;
170cdf0e10cSrcweir         }
171cdf0e10cSrcweir     }
172cdf0e10cSrcweir 
173cdf0e10cSrcweir 
174cdf0e10cSrcweir     private XAccessibleContext mxContext;
175cdf0e10cSrcweir     private double mnScale;
176cdf0e10cSrcweir     private double mnHOffset;
177cdf0e10cSrcweir     private double mnVOffset;
178cdf0e10cSrcweir }
179