8d8e6c84e5
which is internal API, unused (as far as I can tell) by external users. This state is purely a bitset (as implemented by utl::AccessibleStateSetHelper) so we can just return it as a 64-bit value. This shaves significant time off the performance profiles of code that loads very complex shapes, because this state is frequently used, and we no longer need to allocate a return value on the heap for every call. Change-Id: Icf1b3bd367c256646ae9015f9127025f59459c2c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136786 Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
286 lines
8.8 KiB
Java
286 lines
8.8 KiB
Java
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
import java.awt.*;
|
|
import javax.swing.tree.*;
|
|
import java.awt.geom.Rectangle2D;
|
|
|
|
import com.sun.star.accessibility.XAccessibleContext;
|
|
import com.sun.star.accessibility.XAccessibleComponent;
|
|
import com.sun.star.accessibility.XAccessibleText;
|
|
import com.sun.star.accessibility.AccessibleStateType;
|
|
|
|
class CanvasShape
|
|
{
|
|
private final Color maHighlightColor = Color.red;
|
|
private final Color maSelectionColor = Color.green;
|
|
private final Color maFocusColor = Color.blue;
|
|
|
|
public CanvasShape (AccTreeNode aNode)
|
|
{
|
|
maNode = aNode;
|
|
mxContext = aNode.getContext();
|
|
msName = "name unknown";
|
|
msDescription = "description unknown";
|
|
maShape = new Rectangle2D.Double (-10,-10,10,10);
|
|
maPosition = new Point (-10,-10);
|
|
maSize = new Dimension (10,10);
|
|
maFgColor = java.awt.Color.black;
|
|
maBgColor = Color.blue;
|
|
mbHighlighted = false;
|
|
mbSelected = false;
|
|
mbFocused = false;
|
|
mxComponent = aNode.getComponent();
|
|
|
|
update ();
|
|
}
|
|
|
|
|
|
|
|
/** Update the data obtained from the xAccessible.
|
|
*/
|
|
public void update ()
|
|
{
|
|
if (mxContext != null)
|
|
{
|
|
msName = mxContext.getAccessibleName();
|
|
msDescription = mxContext.getAccessibleDescription();
|
|
|
|
// Extract the selected and focused flag.
|
|
long nStateSet = mxContext.getAccessibleStateSet ();
|
|
mbSelected = (nStateSet & AccessibleStateType.SELECTED) != 0;
|
|
mbFocused = (nStateSet & AccessibleStateType.FOCUSED) != 0;
|
|
}
|
|
|
|
updateGeometry ();
|
|
if (mxComponent != null)
|
|
{
|
|
// Note: alpha values in office 0..255 have to be mapped to
|
|
// 255..0 in Java
|
|
Color aCol = new Color (mxComponent.getForeground(), true);
|
|
maFgColor = new Color (aCol.getRed (),
|
|
aCol.getGreen (),
|
|
aCol.getBlue (),
|
|
0xff - aCol.getAlpha ());
|
|
aCol = new Color (mxComponent.getBackground(), true);
|
|
maBgColor = new Color (aCol.getRed (),
|
|
aCol.getGreen (),
|
|
aCol.getBlue (),
|
|
0xff - aCol.getAlpha ());
|
|
}
|
|
}
|
|
|
|
public void updateGeometry ()
|
|
{
|
|
if (mxComponent != null)
|
|
{
|
|
com.sun.star.awt.Point aLocationOnScreen = mxComponent.getLocationOnScreen();
|
|
com.sun.star.awt.Size aSizeOnScreen = mxComponent.getSize();
|
|
maPosition = new Point (
|
|
aLocationOnScreen.X,
|
|
aLocationOnScreen.Y);
|
|
maSize = new Dimension (
|
|
aSizeOnScreen.Width,
|
|
aSizeOnScreen.Height);
|
|
}
|
|
}
|
|
|
|
|
|
/** Paint the object into the specified canvas. It is transformed
|
|
according to the specified offset and scale.
|
|
*/
|
|
public void paint (Graphics2D g,
|
|
double nXOffset, double nYOffset, double nScaleFactor,
|
|
boolean bShowDescription, boolean bShowName, boolean bShowText)
|
|
{
|
|
try{
|
|
// Transform the object's position and size according to the
|
|
// specified offset and scale.
|
|
maShape = new Rectangle2D.Double (
|
|
maPosition.x * nScaleFactor + nXOffset,
|
|
maPosition.y * nScaleFactor + nYOffset,
|
|
maSize.width * nScaleFactor,
|
|
maSize.height * nScaleFactor);
|
|
|
|
// Fill the object's bounding box with its background color if it
|
|
// has no children.
|
|
if (mxContext.getAccessibleChildCount() == 0)
|
|
{
|
|
g.setColor (maBgColor);
|
|
g.fill (maShape);
|
|
}
|
|
|
|
// Remove alpha channel from color before drawing the frame.
|
|
Color color = maFgColor;
|
|
if (maFgColor.getAlpha()<128)
|
|
color = new Color (maFgColor.getRed(), maFgColor.getGreen(), maFgColor.getBlue());
|
|
g.setColor (color);
|
|
g.draw (maShape);
|
|
|
|
if (mbFocused)
|
|
{
|
|
g.setColor (maFocusColor);
|
|
for (int x=0; x<=2; x++)
|
|
for (int y=0; y<=2; y++)
|
|
g.fill (
|
|
new Rectangle2D.Double (
|
|
maShape.x + x/2.0 * maShape.width-3,
|
|
maShape.y + y/2.0 * maShape.height-3,
|
|
6,
|
|
6));
|
|
}
|
|
if (mbSelected)
|
|
{
|
|
g.setColor (maSelectionColor);
|
|
for (int x=0; x<=2; x++)
|
|
for (int y=0; y<=2; y++)
|
|
g.draw (
|
|
new Rectangle2D.Double (
|
|
maShape.x + x/2.0 * maShape.width-2,
|
|
maShape.y + y/2.0 * maShape.height-2,
|
|
4,
|
|
4));
|
|
}
|
|
|
|
// Write the object's text OR name and description.
|
|
g.setColor (maFgColor);
|
|
if (bShowName)
|
|
paintName (g);
|
|
if (bShowDescription)
|
|
paintDescription (g);
|
|
if (bShowText)
|
|
paintText (g);
|
|
}
|
|
catch (Exception e)
|
|
{ // don't care
|
|
}
|
|
}
|
|
|
|
public void paint_highlight (Graphics2D g)
|
|
{
|
|
if (mbHighlighted)
|
|
g.setColor (maHighlightColor);
|
|
else
|
|
g.setColor (maFgColor);
|
|
g.draw (maShape);
|
|
}
|
|
|
|
|
|
|
|
|
|
private void paintName (Graphics2D g)
|
|
{
|
|
g.drawString ("Name: " + msName,
|
|
(float)maShape.x+5,
|
|
(float)maShape.y+15);
|
|
}
|
|
|
|
|
|
|
|
private void paintDescription (Graphics2D g)
|
|
{
|
|
g.drawString ("Description: " + msDescription,
|
|
(float)maShape.x+5,
|
|
(float)maShape.y+35);
|
|
}
|
|
|
|
|
|
|
|
|
|
private void paintText (Graphics2D g)
|
|
{
|
|
XAccessibleText xText = null;
|
|
// get XAccessibleText
|
|
xText = maNode.getText();
|
|
|
|
// Draw every character in the text string.
|
|
if (xText != null)
|
|
{
|
|
String sText = xText.getText();
|
|
try
|
|
{
|
|
for(int i = 0; i < sText.length(); i++)
|
|
{
|
|
com.sun.star.awt.Rectangle aRect =
|
|
xText.getCharacterBounds(i);
|
|
|
|
double x = maShape.x + aRect.X;
|
|
double y = maShape.y + aRect.Y + aRect.Height;
|
|
|
|
g.drawString(sText.substring(i, i+1), (float)x, (float)y);
|
|
}
|
|
}
|
|
catch (com.sun.star.lang.IndexOutOfBoundsException e)
|
|
{}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Compute whether the specified point lies inside the object's
|
|
bounding box.
|
|
*/
|
|
public boolean contains (int x, int y)
|
|
{
|
|
return maShape.contains (x,y);
|
|
}
|
|
|
|
public void highlight ()
|
|
{
|
|
mbHighlighted = true;
|
|
}
|
|
|
|
public void unhighlight ()
|
|
{
|
|
mbHighlighted = false;
|
|
}
|
|
|
|
public Rectangle getBBox ()
|
|
{
|
|
return new Rectangle (maPosition, maSize);
|
|
}
|
|
|
|
public TreePath getPath ()
|
|
{
|
|
return new TreePath (maNode.createPath());
|
|
}
|
|
|
|
@Override
|
|
public String toString ()
|
|
{
|
|
return ">"+msName+", "+msDescription+" +"+maPosition.x+"+"+maPosition.y
|
|
+"x"+maSize.width+"x"+maSize.height+"<";
|
|
}
|
|
|
|
private final AccTreeNode maNode;
|
|
private final XAccessibleContext mxContext;
|
|
private final XAccessibleComponent mxComponent;
|
|
private String msDescription, msName;
|
|
private Rectangle2D.Double maShape;
|
|
private Point maPosition;
|
|
private Dimension maSize;
|
|
private Color maFgColor, maBgColor;
|
|
private boolean
|
|
// Highlighting objects is an internal concept. Corresponds to selection in the tree view.
|
|
mbHighlighted,
|
|
// Set when the accessible object is selected.
|
|
mbSelected,
|
|
// Set when the accessible object is focused.
|
|
mbFocused;
|
|
}
|