/* GNU LESSER GENERAL PUBLIC LICENSE Copyright (C) 2006 The Lobo Project This library 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 2.1 of the License, or (at your option) any later version. This library 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 this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Contact info: lobochief@users.sourceforge.net */ package org.lobobrowser.html.renderer; 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 javax.swing.SwingUtilities; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.lobobrowser.html.domimpl.HTMLBaseInputElement; import org.lobobrowser.html.domimpl.HTMLElementImpl; import org.lobobrowser.html.domimpl.ImageEvent; import org.lobobrowser.html.domimpl.ImageListener; import org.lobobrowser.html.style.HtmlValues; import org.lobobrowser.ua.ImageResponse; import org.lobobrowser.ua.ImageResponse.State; import org.lobobrowser.util.gui.WrapperLayout; import cz.vutbr.web.css.CSSProperty.VerticalAlign; class InputImageControl extends BaseInputControl implements ImageListener { private static final long serialVersionUID = -2242175570423778798L; // private JButton button; private boolean mouseBeingPressed; public InputImageControl(final HTMLBaseInputElement modelNode) { super(modelNode); this.setLayout(WrapperLayout.getInstance()); // JButton button = new LocalButton(); // this.button = button; // button.setMargin(RBlockViewport.ZERO_INSETS); // button.setBorder(null); // this.add(button); modelNode.addImageListener(this); this.addMouseListener(new MouseAdapter() { @Override public void mousePressed(final MouseEvent e) { mouseBeingPressed = true; repaint(); } // public void mouseExited(MouseEvent e) { // mouseBeingPressed = false; // repaint(); // } @Override public void mouseReleased(final MouseEvent e) { mouseBeingPressed = false; repaint(); HtmlController.getInstance().onPressed(modelNode, e, e.getX(), e.getY()); } }); } private Dimension preferredSize; private int declaredWidth; private int declaredHeight; private ImageResponse imageResponse; @Override public void reset(final int availWidth, final int availHeight) { super.reset(availWidth, availHeight); final HTMLElementImpl element = this.controlElement; final int dw = HtmlValues.getOldSyntaxPixelSize(element.getAttribute("width"), availWidth, -1); final int dh = HtmlValues.getOldSyntaxPixelSize(element.getAttribute("height"), availHeight, -1); this.declaredWidth = dw; this.declaredHeight = dh; this.preferredSize = this.createPreferredSize(dw, dh); } @Override public VerticalAlign getVAlign() { final HTMLElementImpl element = this.controlElement; return element.getRenderState().getVerticalAlign(); } @Override public void paintComponent(final Graphics g) { super.paintComponent(g); final Dimension size = this.getSize(); final Insets insets = this.getInsets(); synchronized (this) { } final ImageResponse imageResponse = this.imageResponse; if (imageResponse.state == State.loaded) { g.drawImage(imageResponse.img, insets.left, insets.top, size.width - insets.left - insets.right, size.height - insets.top - insets.bottom, this); } else { // TODO: alt } if (this.mouseBeingPressed) { final Color over = new Color(255, 100, 100, 64); final Color oldColor = g.getColor(); try { g.setColor(over); g.fillRect(0, 0, size.width, size.height); } finally { g.setColor(oldColor); } } } @Override public Dimension getPreferredSize() { final Dimension ps = this.preferredSize; return ps == null ? new Dimension(0, 0) : ps; } public Dimension createPreferredSize(int dw, int dh) { final ImageResponse imgResponse = this.imageResponse; if (!imgResponse.isDecoded()) { return new Dimension(dw == -1 ? 0 : dw, dh == -1 ? 0 : dh); } assert (imgResponse.img != null); final @NonNull Image img = imgResponse.img; if (dw == -1) { dw = HtmlValues.scaleToDevicePixels(img.getWidth(this)); } if (dh == -1) { dh = HtmlValues.scaleToDevicePixels(img.getHeight(this)); } return new Dimension(dw, dh); } private final boolean checkPreferredSizeChange() { final Dimension newPs = this.createPreferredSize(this.declaredWidth, this.declaredHeight); final 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(final Image img, final int infoflags, final int x, final int y, final int w, final int h) { if (((infoflags & ImageObserver.ALLBITS) != 0) || ((infoflags & ImageObserver.FRAMEBITS) != 0)) { SwingUtilities.invokeLater(() -> { if (!checkPreferredSizeChange()) { repaint(); } else { ruicontrol.preferredSizeInvalidated(); } }); } return true; } /* * (non-Javadoc) * * @see java.awt.Component#imageUpdate(java.awt.Image, int, int, int, int, * int) */ public void imageUpdate(final Image img, final int w, final int h) { SwingUtilities.invokeLater(() -> { if (!checkPreferredSizeChange()) { repaint(); } else { ruicontrol.preferredSizeInvalidated(); } }); } @Override public boolean paintSelection(final Graphics g, final boolean inSelection, final RenderableSpot startPoint, final RenderableSpot endPoint) { return inSelection; } public void imageLoaded(final ImageEvent event) { // Implementation of ImageListener. Invoked in a request thread most likely. final ImageResponse imageResponseLocal = event.imageResponse; // ImageIcon imageIcon = new ImageIcon(image); // this.button.setIcon(imageIcon); this.imageResponse = imageResponseLocal; if (imageResponseLocal.isDecoded()) { assert (imageResponseLocal.img != null); @Nullable Image image = imageResponseLocal.img; final int width = image.getWidth(this); final int height = image.getHeight(this); this.imageUpdate(image, width, height); } } public void imageAborted() { // do nothing } public void resetInput() { // NOP } @Override public boolean isReadyToPaint() { return imageResponse.isReadyToPaint(); } // private static class LocalButton extends JButton { // public void revalidate() { // // ignore // } // // public void repaint() { // // ignore // } // } }