Hi Thomas.
Here's a patch which makes handling GenericBridges more uniform.
GenericBridge.handleElement is called from the GVTBuilder instead of
from individual bridges' buildGraphicsNode method. The check for
avoiding setting a tool tip for the root SVG element is done in
JSVGCanvas.CanvasUserAgent.handleElement.
The patch also fixes a bug with tool tip handling where in a document
like this:
<svg>
<g>
<title>G title</title>
<rect>
<title>Rect title</title>
</rect>
<circle/>
</g>
</svg>
where the g's tool tip would override the rect's because
ToolTipModifiers are created for both title elements, and the one for
the g happens to be called later.
Cameron
--
Cameron McCormack
| Web: http://mcc.id.au/
| ICQ: 26955922
diff -ru xml-batik/sources/org/apache/batik/bridge/AbstractGraphicsNodeBridge.java
xml-batik.test/sources/org/apache/batik/bridge/AbstractGraphicsNodeBridge.java
--- xml-batik/sources/org/apache/batik/bridge/AbstractGraphicsNodeBridge.java
2003-10-06 10:56:00.000000000 +1000
+++ xml-batik.test/sources/org/apache/batik/bridge/AbstractGraphicsNodeBridge.java
2004-01-13 12:14:53.000000000 +1100
@@ -166,9 +166,6 @@
node.setPointerEventType(CSSUtilities.convertPointerEvents(e));
initializeDynamicSupport(ctx, e, node);
-
- // Handle children elements such as <title>
- SVGUtilities.bridgeChildren(ctx, e);
}
/**
diff -ru xml-batik/sources/org/apache/batik/bridge/GVTBuilder.java
xml-batik.test/sources/org/apache/batik/bridge/GVTBuilder.java
--- xml-batik/sources/org/apache/batik/bridge/GVTBuilder.java 2003-08-08
21:38:50.000000000 +1000
+++ xml-batik.test/sources/org/apache/batik/bridge/GVTBuilder.java 2004-01-13
16:33:53.000000000 +1100
@@ -143,7 +143,11 @@
public GraphicsNode build(BridgeContext ctx, Element e) {
// get the appropriate bridge according to the specified element
Bridge bridge = ctx.getBridge(e);
- if (bridge == null || !(bridge instanceof GraphicsNodeBridge)) {
+ if (bridge instanceof GenericBridge) {
+ // If it is a GenericBridge just handle it and return.
+ ((GenericBridge) bridge).handleElement(ctx, e);
+ return null;
+ } else if (bridge == null || !(bridge instanceof GraphicsNodeBridge)) {
return null;
}
// create the associated graphics node
@@ -156,6 +160,8 @@
if (gn != null) {
if (gnBridge.isComposite()) {
buildComposite(ctx, e, (CompositeGraphicsNode)gn);
+ } else {
+ handleGenericBridges(ctx, e);
}
gnBridge.buildGraphicsNode(ctx, e, gn);
}
@@ -207,7 +213,11 @@
}
// get the appropriate bridge according to the specified element
Bridge bridge = ctx.getBridge(e);
- if (bridge == null || !(bridge instanceof GraphicsNodeBridge)) {
+ if (bridge instanceof GenericBridge) {
+ // If it is a GenericBridge just handle it and return.
+ ((GenericBridge) bridge).handleElement(ctx, e);
+ return;
+ } else if (bridge == null || !(bridge instanceof GraphicsNodeBridge)) {
return;
}
// check the display property
@@ -224,6 +234,9 @@
// check if the element has children to build
if (gnBridge.isComposite()) {
buildComposite(ctx, e, (CompositeGraphicsNode)gn);
+ } else {
+ // if not then still handle the GenericBridges
+ handleGenericBridges(ctx, e);
}
gnBridge.buildGraphicsNode(ctx, e, gn);
}
@@ -241,5 +254,22 @@
throw ex;
}
}
-}
+ /**
+ * Handles any GenericBridge elements which are children of the
+ * specified element.
+ * @param ctx the bridge context
+ * @param e the element whose child elements should be handled
+ */
+ protected void handleGenericBridges(BridgeContext ctx, Element e) {
+ for (Node n = e.getFirstChild(); n != null; n = n.getNextSibling()) {
+ if (n instanceof Element) {
+ Element e2 = (Element) n;
+ Bridge b = ctx.getBridge(e2);
+ if (b instanceof GenericBridge) {
+ ((GenericBridge) b).handleElement(ctx, e2);
+ }
+ }
+ }
+ }
+}
diff -ru xml-batik/sources/org/apache/batik/bridge/SVGSVGElementBridge.java
xml-batik.test/sources/org/apache/batik/bridge/SVGSVGElementBridge.java
--- xml-batik/sources/org/apache/batik/bridge/SVGSVGElementBridge.java 2003-11-06
09:21:09.000000000 +1100
+++ xml-batik.test/sources/org/apache/batik/bridge/SVGSVGElementBridge.java
2004-01-13 12:15:09.000000000 +1100
@@ -254,9 +254,6 @@
initializeDynamicSupport(ctx, e, node);
- // Handle children elements such as <title>
- //SVGUtilities.bridgeChildren(ctx, e);
- //super.buildGraphicsNode(ctx, e, node);
ctx.closeViewport(e);
}
diff -ru xml-batik/sources/org/apache/batik/bridge/SVGTextElementBridge.java
xml-batik.test/sources/org/apache/batik/bridge/SVGTextElementBridge.java
--- xml-batik/sources/org/apache/batik/bridge/SVGTextElementBridge.java 2003-09-08
08:25:28.000000000 +1000
+++ xml-batik.test/sources/org/apache/batik/bridge/SVGTextElementBridge.java
2004-01-13 12:15:27.000000000 +1100
@@ -251,9 +251,6 @@
node.setPointerEventType(CSSUtilities.convertPointerEvents(e));
initializeDynamicSupport(ctx, e, node);
-
- // Handle children elements such as <title>
- SVGUtilities.bridgeChildren(ctx, e);
}
/**
diff -ru xml-batik/sources/org/apache/batik/bridge/SVGUtilities.java
xml-batik.test/sources/org/apache/batik/bridge/SVGUtilities.java
--- xml-batik/sources/org/apache/batik/bridge/SVGUtilities.java 2003-08-10
02:58:37.000000000 +1000
+++ xml-batik.test/sources/org/apache/batik/bridge/SVGUtilities.java 2004-01-13
12:15:46.000000000 +1100
@@ -1140,31 +1140,4 @@
return new Rectangle2D.Double();
}
}
-
- /**
- * Scans the children of the input <tt>e</tt> element and
- * invokes any registered bridge found for the children.
- *
- * @param ctx active BridgeContext
- * @param e element to be scanned
- */
- public static void bridgeChildren(BridgeContext ctx,
- Element elt){
- for (Node n = elt.getFirstChild();
- n != null;
- n = n.getNextSibling()) {
-
- if ((n.getNodeType() != Node.ELEMENT_NODE)) {
- continue;
- }
-
- Element e = (Element)n;
- Bridge bridge = ctx.getBridge(e);
- if (bridge == null || !(bridge instanceof GenericBridge)) {
- continue;
- }
-
- ((GenericBridge)bridge).handleElement(ctx, e);
- }
- }
}
diff -ru xml-batik/sources/org/apache/batik/swing/JSVGCanvas.java
xml-batik.test/sources/org/apache/batik/swing/JSVGCanvas.java
--- xml-batik/sources/org/apache/batik/swing/JSVGCanvas.java 2004-01-13
16:24:04.000000000 +1100
+++ xml-batik.test/sources/org/apache/batik/swing/JSVGCanvas.java 2004-01-13
17:25:49.000000000 +1100
@@ -785,6 +785,16 @@
= "JSVGCanvas.CanvasUserAgent.ToolTip.titleAndDesc";
/**
+ * The time of the last tool tip event.
+ */
+ protected long lastToolTipEventTimeStamp;
+
+ /**
+ * The target for which the last tool tip event was fired.
+ */
+ protected EventTarget lastToolTipEventTarget;
+
+ /**
* The handleElement method builds a tool tip from the
* content of a <title> element, a <desc>
* element or both. <br/>
@@ -811,6 +821,12 @@
if (!SVGConstants.SVG_NAMESPACE_URI.equals(elt.getNamespaceURI()))
return;
+ // Don't handle tool tips for the root SVG element.
+ if (elt.getParentNode() ==
+ elt.getOwnerDocument().getDocumentElement()) {
+ return;
+ }
+
if (elt.getLocalName().equals(SVGConstants.SVG_TITLE_TAG)) {
// If there is a <desc> peer, do nothing as the tooltip will
// be handled when handleElement is invoked for the <desc>
@@ -941,12 +957,12 @@
// On mouseover, set the tooltip to the title value
target.addEventListener(SVGConstants.SVG_EVENT_MOUSEOVER,
- new ToolTipModifier(toolTip),
+ new ToolTipModifier(toolTip, this),
false);
// On mouseout, remove the tooltip
target.addEventListener(SVGConstants.SVG_EVENT_MOUSEOUT,
- new ToolTipModifier(null),
+ new ToolTipModifier(null, this),
false);
if (locationListener == null) {
@@ -985,6 +1001,23 @@
dialog.show(); // Safe to be called from any thread
}
}
+
+ /**
+ * Sets the time and element of the last tool tip event handled.
+ */
+ public void setLastToolTipEvent(long t, EventTarget et) {
+ lastToolTipEventTimeStamp = t;
+ lastToolTipEventTarget = et;
+ }
+
+ /**
+ * Checks if the specified event time and element are the same
+ * as the last tool tip event.
+ */
+ public boolean matchLastToolTipEvent(long t, EventTarget et) {
+ return lastToolTipEventTimeStamp == t
+ && lastToolTipEventTarget == et;
+ }
}
// ----------------------------------------------------------------------
@@ -1029,14 +1062,32 @@
protected String toolTip;
/**
+ * The CanvasUserAgent used to track the last tool tip event.
+ */
+ protected CanvasUserAgent canvasUserAgent;
+
+ /**
* @param toolTip value to which the JSVGCanvas should be
* set when the event occurs.
+ * @param cua the CanvasUserAgent which will be used to track
+ * the last tool tip event.
*/
- public ToolTipModifier(String toolTip){
+ public ToolTipModifier(String toolTip, CanvasUserAgent cua) {
this.toolTip = toolTip;
+ canvasUserAgent = cua;
}
public void handleEvent(Event evt){
+ // Don't set the tool tip if another ToolTipModifier
+ // has already handled this event (as it will have been
+ // a higher priority tool tip).
+ if (canvasUserAgent.matchLastToolTipEvent(evt.getTimeStamp(),
+ evt.getTarget())) {
+ return;
+ }
+ canvasUserAgent.setLastToolTipEvent(evt.getTimeStamp(),
+ evt.getTarget());
+
EventQueue.invokeLater(new Runnable() {
public void run() {
setToolTipText(toolTip);
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]