/**
* BlockReplacedBoxView.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.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.BlockReplacedBox;
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 - 14.4.2011
*/
public class BlockReplacedBoxView extends BlockBoxView
{
// this is a block version of InlineReplacedBoxView
// get some default system font..
// hint: default font as constant in Constants
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 = "";
/**
* Instantiates a new block replaced box view.
*
* @param elem
* the element
*/
public BlockReplacedBoxView(Element elem)
{
// bonus : spravit klikaciu mapu :)
super(elem);
content = ((BlockReplacedBox) box).getContentObj();
if (content instanceof ReplacedImage)
{
repImage = (ReplacedImage) content;
}
else
{
repImage = null;
}
loadElementAttributes();
}
private void loadElementAttributes()
{
/*
* http://www.w3schools.com/TAGS/tag_img.asp html attributy : alt -
* alternativny popisok, zobrazit ak nie je dostupny image title -
* popup/tooltip text
*/
// getElement().getAttribute("src");
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)
{
String val = "";
String tmp;
Map<String, String> elementAttributes = anchor.getProperties();
if (title != null && !"".equals(title))
val = val + "<b>" + title + "</b><br>";
tmp = elementAttributes.get(Constants.ELEMENT_A_ATTRIBUTE_TITLE);
if (tmp != null && !"".equals(tmp))
val = val + "<i>" + tmp + "</i><br>";
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;
}
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);
}
}
}
}