/* GNU GENERAL LICENSE Copyright (C) 2006 The Lobo Project. Copyright (C) 2014 - 2017 Lobo Evolution This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either verion 3 of the License, or (at your option) any later version. This program 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 General License for more details. You should have received a copy of the GNU General Public along with this program. If not, see <http://www.gnu.org/licenses/>. Contact info: lobochief@users.sourceforge.net; ivan.difrancesco@yahoo.it */ package org.lobobrowser.html.control; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Image; import java.awt.Insets; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.ImageObserver; import java.net.MalformedURLException; import java.net.URL; import javax.swing.SwingUtilities; import org.apache.batik.transcoder.TranscoderException; import org.lobobrowser.html.HtmlAttributeProperties; import org.lobobrowser.html.dombl.ImageEvent; import org.lobobrowser.html.dombl.ImageListener; import org.lobobrowser.html.dombl.SVGRasterizer; import org.lobobrowser.html.domimpl.HTMLBaseInputElement; import org.lobobrowser.html.domimpl.HTMLElementImpl; import org.lobobrowser.html.renderer.HtmlController; import org.lobobrowser.html.renderer.RElement; import org.lobobrowser.html.renderer.RenderableSpot; import org.lobobrowser.html.style.HtmlValues; import org.lobobrowser.util.gui.WrapperLayout; /** * The Class InputImageControl. */ public class InputImageControl extends BaseInputControl implements ImageListener { /** The Constant serialVersionUID. */ private static final long serialVersionUID = 1L; /** The valign. */ private int valign = RElement.VALIGN_BASELINE; /** The preferred size. */ private Dimension preferredSize; /** The declared width. */ private int declaredWidth; /** The declared height. */ private int declaredHeight; /** The image. */ private Image image; /** The mouse being pressed. */ private boolean mouseBeingPressed; /** The alt. */ private String alt; /** * Instantiates a new input image control. * * @param modelNode * the model node */ public InputImageControl(final HTMLBaseInputElement modelNode) { super(modelNode); this.setLayout(WrapperLayout.getInstance()); alt = modelNode.getAlt(); modelNode.addImageListener(this); this.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { mouseBeingPressed = true; repaint(); } @Override public void mouseReleased(MouseEvent e) { mouseBeingPressed = false; repaint(); HtmlController.getInstance().onPressed(modelNode, e, e.getX(), e.getY()); } }); if (modelNode.getSrc().contains("svg")) { try { URL u = new URL(modelNode.getSrc()); SVGRasterizer r = new SVGRasterizer(u); image = r.bufferedImageToImage(); } catch (MalformedURLException | TranscoderException e1) { e1.printStackTrace(); } } } /* * (non-Javadoc) * * @see javax.swing.JComponent#paintComponent(java.awt.Graphics) */ @Override public void paintComponent(Graphics g) { super.paintComponent(g); Dimension size = this.getSize(); Insets insets = this.getInsets(); Image image = this.image; if (image != null) { g.drawImage(image, insets.left, insets.top, size.width - insets.left - insets.right, size.height - insets.top - insets.bottom, this); } else { g.drawString(alt, 10, 10); } if (this.mouseBeingPressed) { Color over = new Color(255, 100, 100, 64); if (over != null) { Color oldColor = g.getColor(); try { g.setColor(over); g.fillRect(0, 0, size.width, size.height); } finally { g.setColor(oldColor); } } } } /* * (non-Javadoc) * * @see org.lobobrowser.html.control.BaseInputControl#reset(int, int) */ @Override public void reset(int availWidth, int availHeight) { super.reset(availWidth, availHeight); HTMLElementImpl element = this.controlElement; String width = element.getAttribute(HtmlAttributeProperties.WIDTH); String height = element.getAttribute(HtmlAttributeProperties.HEIGHT); int dw = HtmlValues.getPixelSize(width, null,-1,availWidth); int dh = HtmlValues.getPixelSize(height, null,-1,availHeight); this.declaredWidth = dw; this.declaredHeight = dh; this.preferredSize = this.createPreferredSize(dw, dh); int valign; String alignText = element.getAttribute(HtmlAttributeProperties.ALIGN); if (alignText == null) { valign = RElement.VALIGN_BASELINE; } else { alignText = alignText.toLowerCase().trim(); if ("middle".equals(alignText)) { valign = RElement.VALIGN_MIDDLE; } else if ("absmiddle".equals(alignText)) { valign = RElement.VALIGN_ABSMIDDLE; } else if ("top".equals(alignText)) { valign = RElement.VALIGN_TOP; } else if ("bottom".equals(alignText)) { valign = RElement.VALIGN_BOTTOM; } else if ("baseline".equals(alignText)) { valign = RElement.VALIGN_BASELINE; } else if ("absbottom".equals(alignText)) { valign = RElement.VALIGN_ABSBOTTOM; } else { valign = RElement.VALIGN_BASELINE; } } this.valign = valign; } /* * (non-Javadoc) * * @see javax.swing.JComponent#getPreferredSize() */ @Override public Dimension getPreferredSize() { Dimension ps = this.preferredSize; return ps == null ? new Dimension(0, 0) : ps; } /** * Creates the preferred size. * * @param dw * the dw * @param dh * the dh * @return the dimension */ public Dimension createPreferredSize(int dw, int dh) { Image img = this.image; if (dw == -1) { dw = img == null ? -1 : img.getWidth(this); if (dw == -1) { dw = 0; } } if (dh == -1) { dh = img == null ? -1 : img.getHeight(this); if (dh == -1) { dh = 0; } } return new Dimension(dw, dh); } /** * Check preferred size change. * * @return true, if successful */ private final boolean checkPreferredSizeChange() { Dimension newPs = this.createPreferredSize(this.declaredWidth, this.declaredHeight); Dimension ps = this.preferredSize; if (ps == null) { return true; } if ((ps.width != newPs.width) || (ps.height != newPs.height)) { this.preferredSize = newPs; return true; } else { return false; } } /* * (non-Javadoc) * * @see java.awt.Component#imageUpdate(java.awt.Image, int, int, int, int, * int) */ @Override public boolean imageUpdate(Image img, int infoflags, int x, int y, final int w, final int h) { if (((infoflags & ImageObserver.ALLBITS) != 0) || ((infoflags & ImageObserver.FRAMEBITS) != 0)) { if (SwingUtilities.isEventDispatchThread()) { if (!checkPreferredSizeChange()) { repaint(); } else { if (ruicontrol != null) { ruicontrol.preferredSizeInvalidated(); } } } else { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { if (!checkPreferredSizeChange()) { repaint(); } else { if (ruicontrol != null) { ruicontrol.preferredSizeInvalidated(); } } } }); } } return true; } /* * (non-Javadoc) * * @see java.awt.Component#imageUpdate(java.awt.Image, int, int, int, int, * int) */ /** * Image update. * * @param img * the img * @param w * the w * @param h * the h */ public void imageUpdate(Image img, final int w, final int h) { if (SwingUtilities.isEventDispatchThread()) { if (!checkPreferredSizeChange()) { repaint(); } else { if (ruicontrol != null) { ruicontrol.preferredSizeInvalidated(); } } } else { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { if (!checkPreferredSizeChange()) { repaint(); } else { if (ruicontrol != null) { ruicontrol.preferredSizeInvalidated(); } } } }); } } /* * (non-Javadoc) * * @see * org.lobobrowser.html.control.BaseInputControl#paintSelection(java.awt. * Graphics , boolean, org.lobobrowser.html.renderer.RenderableSpot, * org.lobobrowser.html.renderer.RenderableSpot) */ @Override public boolean paintSelection(Graphics g, boolean inSelection, RenderableSpot startPoint, RenderableSpot endPoint) { return inSelection; } /* * (non-Javadoc) * * @see * org.lobobrowser.html.dombl.ImageListener#imageLoaded(org.lobobrowser.html * .dombl.ImageEvent) */ @Override public void imageLoaded(ImageEvent event) { // Implementation of ImageListener. Invoked in a request thread most // likely. Image image = event.image; // ImageIcon imageIcon = new ImageIcon(image); // this.button.setIcon(imageIcon); this.image = image; int width = image.getWidth(this); int height = image.getHeight(this); if ((width != -1) && (height != -1)) { this.imageUpdate(image, width, height); } } /* * (non-Javadoc) * * @see org.lobobrowser.html.dombl.InputContext#resetInput() */ @Override public void resetInput() { // NOP } /* * (non-Javadoc) * * @see org.lobobrowser.html.control.BaseInputControl#getVAlign() */ @Override public int getVAlign() { return this.valign; } }