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) 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 */ 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 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 */ 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 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 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 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 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 */ 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 */ 267 public boolean contains (int x, int y) 268 { 269 return (maShape.contains (x,y)); 270 } 271 272 public void highlight () 273 { 274 mbHighlighted = true; 275 } 276 277 public void unhighlight () 278 { 279 mbHighlighted = false; 280 } 281 282 public boolean isHighlighted () 283 { 284 return mbHighlighted; 285 } 286 287 public Rectangle getBBox () 288 { 289 return new Rectangle (maPosition, maSize); 290 } 291 292 public Point getOrigin () 293 { 294 return maPosition; 295 } 296 297 public TreePath getPath () 298 { 299 return new TreePath (maNode.createPath()); 300 } 301 302 public int getRole () 303 { 304 return mnRole; 305 } 306 307 public XAccessibleContext getContext () 308 { 309 return mxContext; 310 } 311 312 public XAccessibleComponent getComponent () 313 { 314 return mxComponent; 315 } 316 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