1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 import java.awt.*; 23 import javax.swing.*; 24 import javax.swing.tree.*; 25 import java.awt.geom.Rectangle2D; 26 27 import com.sun.star.beans.XPropertyChangeListener; 28 import com.sun.star.beans.PropertyChangeEvent; 29 30 import com.sun.star.accessibility.XAccessible; 31 import com.sun.star.accessibility.XAccessibleContext; 32 import com.sun.star.accessibility.XAccessibleComponent; 33 import com.sun.star.accessibility.XAccessibleExtendedComponent; 34 import com.sun.star.accessibility.XAccessibleText; 35 import com.sun.star.accessibility.XAccessibleStateSet; 36 import com.sun.star.accessibility.AccessibleStateType; 37 38 class CanvasShape 39 { 40 public final Color maHighlightColor = Color.red; 41 public final Color maSelectionColor = Color.green; 42 public final Color maFocusColor = Color.blue; 43 44 // public AccessibleObject (XAccessibleContext xContext, TreePath aPath) CanvasShape(AccTreeNode aNode)45 public CanvasShape (AccTreeNode aNode) 46 { 47 maNode = aNode; 48 mxContext = aNode.getContext(); 49 msName = "name unknown"; 50 msDescription = "description unknown"; 51 maShape = new Rectangle2D.Double (-10,-10,10,10); 52 maPosition = new Point (-10,-10); 53 maSize = new Dimension (10,10); 54 maFgColor = java.awt.Color.black; 55 maBgColor = Color.blue; 56 mnRole = -1; 57 mbHighlighted = false; 58 mbSelected = false; 59 mbFocused = false; 60 mxComponent = aNode.getComponent(); 61 62 update (); 63 } 64 65 66 67 /** Update the data obtained from the xAccessible. 68 */ update()69 public void update () 70 { 71 if (mxContext != null) 72 { 73 msName = mxContext.getAccessibleName(); 74 msDescription = mxContext.getAccessibleDescription(); 75 mnRole = mxContext.getAccessibleRole(); 76 77 // Extract the selected and focused flag. 78 XAccessibleStateSet xStateSet = mxContext.getAccessibleStateSet (); 79 if (xStateSet != null) 80 { 81 mbSelected = xStateSet.contains (AccessibleStateType.SELECTED); 82 mbFocused = xStateSet.contains (AccessibleStateType.FOCUSED); 83 } 84 } 85 86 updateGeometry (); 87 if (mxComponent != null) 88 { 89 // Note: alpha values in office 0..255 have to be mapped to 90 // 255..0 in Java 91 Color aCol = new Color (mxComponent.getForeground(), true); 92 maFgColor = new Color (aCol.getRed (), 93 aCol.getGreen (), 94 aCol.getBlue (), 95 0xff - aCol.getAlpha ()); 96 aCol = new Color (mxComponent.getBackground(), true); 97 maBgColor = new Color (aCol.getRed (), 98 aCol.getGreen (), 99 aCol.getBlue (), 100 0xff - aCol.getAlpha ()); 101 } 102 } 103 updateGeometry()104 public void updateGeometry () 105 { 106 if (mxComponent != null) 107 { 108 com.sun.star.awt.Point aLocationOnScreen = mxComponent.getLocationOnScreen(); 109 com.sun.star.awt.Size aSizeOnScreen = mxComponent.getSize(); 110 maPosition = new Point ( 111 aLocationOnScreen.X, 112 aLocationOnScreen.Y); 113 maSize = new Dimension ( 114 aSizeOnScreen.Width, 115 aSizeOnScreen.Height); 116 } 117 } 118 119 120 /** Paint the object into the specified canvas. It is transformed 121 according to the specified offset and scale. 122 */ paint(Graphics2D g, double nXOffset, double nYOffset, double nScaleFactor, boolean bShowDescription, boolean bShowName, boolean bShowText)123 public void paint (Graphics2D g, 124 double nXOffset, double nYOffset, double nScaleFactor, 125 boolean bShowDescription, boolean bShowName, boolean bShowText) 126 { 127 try{ 128 // Transform the object's position and size according to the 129 // specified offset and scale. 130 Point aLocation = new Point(); 131 maShape = new Rectangle2D.Double ( 132 maPosition.x * nScaleFactor + nXOffset, 133 maPosition.y * nScaleFactor + nYOffset, 134 maSize.width * nScaleFactor, 135 maSize.height * nScaleFactor); 136 137 // Fill the object's bounding box with its background color if it 138 // has no children. 139 if (mxContext.getAccessibleChildCount() == 0) 140 { 141 g.setColor (maBgColor); 142 g.fill (maShape); 143 } 144 145 // Remove alpha channel from color before drawing the frame. 146 Color color = maFgColor; 147 if (maFgColor.getAlpha()<128) 148 color = new Color (maFgColor.getRed(), maFgColor.getGreen(), maFgColor.getBlue()); 149 g.setColor (color); 150 g.draw (maShape); 151 152 if (mbFocused) 153 { 154 g.setColor (maFocusColor); 155 for (int x=0; x<=2; x++) 156 for (int y=0; y<=2; y++) 157 g.fill ( 158 new Rectangle2D.Double ( 159 maShape.x + x/2.0 * maShape.width-3, 160 maShape.y + y/2.0 * maShape.height-3, 161 6, 162 6)); 163 } 164 if (mbSelected) 165 { 166 g.setColor (maSelectionColor); 167 for (int x=0; x<=2; x++) 168 for (int y=0; y<=2; y++) 169 g.draw ( 170 new Rectangle2D.Double ( 171 maShape.x + x/2.0 * maShape.width-2, 172 maShape.y + y/2.0 * maShape.height-2, 173 4, 174 4)); 175 } 176 177 // Write the object's text OR name and description. 178 g.setColor (maFgColor); 179 if (bShowName) 180 paintName (g); 181 if (bShowDescription) 182 paintDescription (g); 183 if (bShowText) 184 paintText (g); 185 } 186 catch (Exception e) 187 { // don't care 188 } 189 } 190 paint_highlight(Graphics2D g, double nXOffset, double nYOffset, double nScaleFactor)191 public void paint_highlight (Graphics2D g, 192 double nXOffset, double nYOffset, double nScaleFactor) 193 { 194 if (mbHighlighted) 195 g.setColor (maHighlightColor); 196 else 197 g.setColor (maFgColor); 198 g.draw (maShape); 199 } 200 201 202 203 paintName(Graphics2D g)204 private void paintName (Graphics2D g) 205 { 206 g.drawString ("Name: " + msName, 207 (float)maShape.x+5, 208 (float)maShape.y+15); 209 } 210 211 212 paintDescription(Graphics2D g)213 private void paintDescription (Graphics2D g) 214 { 215 g.drawString ("Description: " + msDescription, 216 (float)maShape.x+5, 217 (float)maShape.y+35); 218 } 219 220 221 222 paintText(Graphics2D g)223 private void paintText (Graphics2D g) 224 { 225 XAccessibleText xText = null; 226 // get XAccessibleText 227 xText = maNode.getText(); 228 229 // Draw every character in the text string. 230 if (xText != null) 231 { 232 String sText = xText.getText(); 233 try 234 { 235 for(int i = 0; i < sText.length(); i++) 236 { 237 com.sun.star.awt.Rectangle aRect = 238 xText.getCharacterBounds(i); 239 240 double x = maShape.x + aRect.X; 241 double y = maShape.y + aRect.Y + aRect.Height; 242 243 g.drawString(sText.substring(i, i+1), (float)x, (float)y); 244 } 245 } 246 catch (com.sun.star.lang.IndexOutOfBoundsException e) 247 {} 248 } 249 } 250 251 252 253 254 /** Callback for disposing events. 255 */ disposing(com.sun.star.lang.EventObject e)256 public void disposing (com.sun.star.lang.EventObject e) 257 { 258 System.out.println ("Disposing"); 259 } 260 261 262 263 264 /** Compute whether the specified point lies inside the object's 265 bounding box. 266 */ contains(int x, int y)267 public boolean contains (int x, int y) 268 { 269 return (maShape.contains (x,y)); 270 } 271 highlight()272 public void highlight () 273 { 274 mbHighlighted = true; 275 } 276 unhighlight()277 public void unhighlight () 278 { 279 mbHighlighted = false; 280 } 281 isHighlighted()282 public boolean isHighlighted () 283 { 284 return mbHighlighted; 285 } 286 getBBox()287 public Rectangle getBBox () 288 { 289 return new Rectangle (maPosition, maSize); 290 } 291 getOrigin()292 public Point getOrigin () 293 { 294 return maPosition; 295 } 296 getPath()297 public TreePath getPath () 298 { 299 return new TreePath (maNode.createPath()); 300 } 301 getRole()302 public int getRole () 303 { 304 return mnRole; 305 } 306 getContext()307 public XAccessibleContext getContext () 308 { 309 return mxContext; 310 } 311 getComponent()312 public XAccessibleComponent getComponent () 313 { 314 return mxComponent; 315 } 316 toString()317 public String toString () 318 { 319 return ">"+msName+", "+msDescription+" +"+maPosition.x+"+"+maPosition.y 320 +"x"+maSize.width+"x"+maSize.height+"<"; 321 } 322 323 private AccTreeNode 324 maNode; 325 private XAccessibleContext 326 mxContext; 327 private XAccessibleComponent 328 mxComponent; 329 private String 330 msDescription, 331 msName; 332 private Rectangle2D.Double 333 maShape; 334 private Point 335 maPosition; 336 private Dimension 337 maTransformedSize, 338 maSize; 339 private Color 340 maFgColor, 341 maBgColor; 342 private boolean 343 // Highlighting objects is an internal concept. Corresponds to selection in the tree view. 344 mbHighlighted, 345 // Set when the accessible object is selected. 346 mbSelected, 347 // Set when the accessible object is focused. 348 mbFocused; 349 private int 350 mnRole; 351 } 352