/** * InlineReplacedBoxView.java * (c) Peter Bielik and Radek Burget, 2011-2012 * * SwingBox is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SwingBox is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with SwingBox. If not, see <http://www.gnu.org/licenses/>. * */ package org.fit.cssbox.swingbox.view; import java.awt.Color; import java.awt.Container; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.Shape; import java.util.Map; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.Element; import javax.swing.text.Highlighter; import javax.swing.text.JTextComponent; import javax.swing.text.LayeredHighlighter; import javax.swing.text.Position; import javax.swing.text.Position.Bias; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.View; import org.fit.cssbox.layout.InlineReplacedBox; import org.fit.cssbox.layout.ReplacedContent; import org.fit.cssbox.layout.ReplacedImage; import org.fit.cssbox.swingbox.util.Constants; /** * @author Peter Bielik * @version 1.0 * @since 1.0 - 15.3.2011 */ public class InlineReplacedBoxView extends InlineBoxView { // get some default system font.. private static final Font DEFAULT_FONT = new Font(null, Font.PLAIN, 13); private Container container; private ReplacedContent content; private ReplacedImage repImage; private String alt = ""; private String title = ""; public InlineReplacedBoxView(Element elem) { super(elem); content = ((InlineReplacedBox) box).getContentObj(); if (content instanceof ReplacedImage) { repImage = (ReplacedImage) content; } else { repImage = null; } loadElementAttributes(); } private void loadElementAttributes() { alt = box.getElement().getAttribute("alt"); title = box.getElement().getAttribute("title"); } /** * {@inheritDoc} */ @Override public void paint(Graphics graphics, Shape allocation) { Graphics2D g = (Graphics2D) graphics; Rectangle alloc = toRect(allocation); if (isVisible() /*&& intersection(alloc, box.getAbsoluteBounds(), tmpRect)*/) { paintHighlights(g, alloc); box.getVisualContext().updateGraphics(g); box.drawBackground(g); if (content != null) { content.draw(g, box.getContentWidth(), box.getContentHeight()); if (repImage != null && repImage.getImage() == null) { if (!"".equals(alt)) { // so we have replaced image, which has no image data... // :) g.setFont(DEFAULT_FONT); g.setColor(Color.BLACK); //tmpRect = box.getAbsoluteContentBounds(); // alternative picture representation (screen readers) // TODO hint : java accessibility !!! //g.drawString(alt, tmpRect.x + 2, tmpRect.y // + (int) (tmpRect.height * 0.7)); } else { drawCross(g); } } } else { drawCross(g); } } } private void drawCross(Graphics2D g) { /*tmpRect = box.getAbsoluteContentBounds(); g.setColor(Color.BLACK); g.drawLine(tmpRect.x, tmpRect.y, tmpRect.x + tmpRect.width - 1, tmpRect.y + tmpRect.height - 1); g.drawLine(tmpRect.x + tmpRect.width - 1, tmpRect.y, tmpRect.x, tmpRect.y + tmpRect.height - 1);*/ } @Override public String getToolTipText(float x, float y, Shape allocation) { Map<String, String> elementAttributes = anchor.getProperties(); String val = ""; String tmp; // image title if (title != null && !"".equals(title)) val = val + "<b>" + title + "</b><br>"; // anchor title tmp = elementAttributes.get(Constants.ELEMENT_A_ATTRIBUTE_TITLE); if (tmp != null && !"".equals(tmp)) val = val + "<i>" + tmp + "</i><br>"; // anchor href tmp = elementAttributes.get(Constants.ELEMENT_A_ATTRIBUTE_HREF); if (tmp != null && !"".equals(tmp)) val = val + tmp; return "".equals(val) ? null : "<html>" + val + "</html>"; } @Override public boolean isVisible() { return box.isDisplayed() && box.isVisible(); } @Override public void setParent(View parent) { super.setParent(parent); if (parent != null) { container = getContainer(); if (repImage != null) repImage.setContainer(container);// getContainer()); } else { repImage = null; content = null; container = null; } } @Override protected View getViewAtPoint(int x, int y, Rectangle alloc) { Rectangle rec = box.getAbsoluteBounds(); if (rec.contains(x, y)) { return this; } return null; } @Override protected void setPropertiesFromAttributes(AttributeSet attr) { super.setPropertiesFromAttributes(attr); if (attr != null) { // setContent((ReplacedContent) // attr.getAttribute(Constants.ATTRIBUTE_REPLACED_CONTENT)); } } protected SimpleAttributeSet createAttributes() { // called from getAttributes() SimpleAttributeSet res = super.createAttributes(); res.addAttribute(Constants.ATTRIBUTE_REPLACED_CONTENT, content); return res; } @Override public int viewToModel(float x, float y, Shape a, Bias[] bias) { // Rectangle alloc = a instanceof Rectangle ? (Rectangle)a : // a.getBounds(); // if (x < alloc.x + alloc.width) { // bias[0] = Position.Bias.Forward; // return getStartOffset(); // LTR // } // bias[0] = Position.Bias.Backward; // return getEndOffset(); //RTL Rectangle alloc = a instanceof Rectangle ? (Rectangle) a : a .getBounds(); if (x < alloc.x + (alloc.width / 2)) { bias[0] = Position.Bias.Forward; return getStartOffset(); } bias[0] = Position.Bias.Backward; return getEndOffset(); } @Override public Shape modelToView(int pos, Shape a, Bias b) throws BadLocationException { int p0 = getStartOffset(); int p1 = getEndOffset(); if ((pos >= p0) && (pos <= p1)) { Rectangle r = a instanceof Rectangle ? (Rectangle) a : a .getBounds(); if (pos == p1) { r.x += r.width; } r.width = 0; return r; } // return null; // //return box.getAbsoluteBounds(); throw new BadLocationException(pos + " not in range " + p0 + "," + p1, pos); } private void paintHighlights(Graphics g, Shape shape) { if (container instanceof JTextComponent) { JTextComponent tc = (JTextComponent) container; Highlighter h = tc.getHighlighter(); if (h instanceof LayeredHighlighter) { ((LayeredHighlighter) h).paintLayeredHighlights(g, getStartOffset(), getEndOffset(), shape, tc, this); } } } }