/* * Copyright 2008-2009 Adam Tacy <adam.tacy AT gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ /* * Copyright 2011 Vancouver Ywebb Consulting Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package org.adamtacy.client.ui.effects.impl.browsers; import org.adamtacy.client.ui.Canvas; import org.adamtacy.client.ui.NEffectPanel; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Element; import com.google.gwt.user.client.ui.DockPanel; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; /** * Deferred Binding class allowing access to low level effect functionality for standard browsers. * * @author Adam Tacy * @version 3.0 * */ public class EffectImplementationStandard { final protected int WHERE_IS_REFLECTION = 2; /** * Clip the inner component of the Effect Panel to a specific set of * rectangle. * * @param top topmost y-coordinate of the clip rectangle. * @param right rightmost x-coordinate of the clip rectangle. * @param bottom bottom-most y-coordinate of the clip rectangle. * @param left leftmost x-coordinate of the clip rectangle. * * */ public void clip(Element e, String top, String right, String bottom, String left) { StringBuffer clipString = new StringBuffer("rect"); clipString.append("("); clipString.append(top); clipString.append(" "); clipString.append(right); clipString.append(" "); clipString.append(bottom); clipString.append(" "); clipString.append(left); clipString.append(")"); e.getStyle().setProperty("clip", clipString.toString()); // DOM.setStyleAttribute((com.google.gwt.user.client.Element) e, "clip", // clipString.toString()); // DOM.setStyleAttribute((com.google.gwt.user.client.Element) e, "clip", // "rect(" + top + " " + right + " " + bottom + " " + left + ")"); } /** * Get a reference to the image to be reflected. * * @param thePanel * @return */ public Image getReflectedImage(NEffectPanel thePanel, boolean setUp) { if (!setUp) return (Image) thePanel.getPanelWidget(); else return (Image) (((DockPanel) thePanel.getPanelWidget()).getWidget(0)); } /** * The code to reflect an element. This comment block gives a verbatim * description as we remove that from the JSNI code to keep output as short as * possible (GWT does not, as far as I am aware, remove comments from JSNI * code... // Get the canvas context var context = ct.getContext('2d'); // * save current state (i.e. identity transformation) context.save(); // move * whatever will be drawn to the bottom of the canvas context.translate(0, * imgHeight-1); // flip it in y-axis context.scale(1, -1); // draw the image * context.drawImage(img, 0, 0, imgWidth, imgHeight); // Get back to the * identity transformation context.restore(); // Now we're going to draw on * top... context.globalCompositeOperation = 'destination-out'; // Create a * gradient var gradient = context.createLinearGradient(0, 0, 0, imgHeight); * gradient.addColorStop(0, 'rgba(255, 255, 255, '+(1-opacity)+')'); var * length = (canvasHeight/imgHeight); gradient.addColorStop(length, 'rgba(255, * 255, 255, 1.0)'); gradient.addColorStop(1, 'rgba(255, 255, 255, 1.0)'); // * Set the fill stylr context.fillStyle = gradient; // And draw.... * context.fillRect(0,0,imgWidth,imgHeight); * */ protected native void reflect(Element ct, Element img, int cH, double opacity)/*-{ var imgWidth = img.width; var imgHeight = img.height; var c = ct.getContext('2d'); ct.width = imgWidth; ct.height = cH; ct.style.width = imgWidth + 'px'; ct.style.height = cH + 'px'; c.save(); c.translate(0, img.height-1); c.scale(1, -1); c.drawImage(img, 0, 0, img.width, img.height); c.restore(); c.globalCompositeOperation = 'destination-out'; var g = c.createLinearGradient(0, 0, 0, cH); g.addColorStop(0, 'rgba(255, 255, 255, '+(1-opacity)+')'); g.addColorStop(1, 'rgba(255, 255, 255, 1.0)'); c.fillStyle = g; c.fillRect(0,0,img.width,cH); }-*/; /** * Reflects an image by creating a DockPanel where the original image is place * in the top and a canvas object containing a refection of the original image * is placed below. At the moment I can't seem to reuse the original canvas so * if any action is performed requiring the reflection to be re-drawn a new * canvas object is required (compare that to the Opera version where reuse is * possible) * * @param gap */ public void reflectImage(NEffectPanel thePanel, int height, double opacity, int gap, boolean setUp) { DockPanel container; Widget w; SimplePanel gapPanel; Canvas v; w = getReflectedImage(thePanel, setUp); if (setUp) { v = new Canvas(); container = (DockPanel) thePanel.getPanelWidget(); // Remove from panel now as this may make any animations look much // smoother // If not, there is a danger on slow(er) systems that the reflection hangs // out from image until re-drawn. container.remove(WHERE_IS_REFLECTION); } else { container = new DockPanel(); v = new Canvas(); } gapPanel = new SimplePanel(); gapPanel.setWidth("100%"); gapPanel.add(new HTML(" ")); gapPanel.setHeight(gap + "px"); int imgWidth = w.getOffsetWidth(); int imgHeight = w.getOffsetHeight(); int canvasHeight = (int) ((imgHeight * height) / 100); v.setSize(imgWidth, canvasHeight); reflect(v.getElement(), w.getElement(), canvasHeight, opacity); if (setUp) { container.add(v, DockPanel.SOUTH); } else { container.add(w, DockPanel.NORTH); container.add(v, DockPanel.SOUTH); thePanel.add(container); } container.add(gapPanel, DockPanel.CENTER); } /** * Set the opacity of the component held by the EffectPanel * * @param value Opacity value. */ public void setOpacity(Element e, double value) { e.getStyle().setProperty("opacity", ""+value/100); // DOM.setStyleAttribute((com.google.gwt.user.client.Element) e, "opacity", "" // + value / 100); } public String getOpacityText(double value){ return "opacity" + value / 100 + "; "; } /** * For normal browsers, nothing more to do... * @param effectElement * @param styleComponentToChange */ public void setTransparent(Element effectElement, String styleComponentToChange) { effectElement.getStyle().setProperty(styleComponentToChange, "transparent"); // DOM.setStyleAttribute((com.google.gwt.user.client.Element) effectElement, // styleComponentToChange, "transparent"); } /** * For normal browsers, nothing more to do... * @param color */ public void setTransparentColor(String color){ return; } /** * In standard case, just set the colour * @param effectElement * @param styleComponentToChange * @param colour */ public void setColour(Element effectElement, String styleComponentToChange, String colour) { effectElement.getStyle().setProperty(styleComponentToChange, colour); // DOM.setStyleAttribute((com.google.gwt.user.client.Element) effectElement, // styleComponentToChange, colour); } /** * Gets the layout definition that IE requires to use filters. * returns empty string for any browser other than IE as it has no use. */ public String getLayoutDefinition() { GWT.log("getLayoutDefinition() is only available for IE (it is not needed for other browsers)", null); return ""; } /** * Sets the layout definition that IE requires to use filters. * Is a null operation except for within IE */ public void setLayoutDefinition(String id, String val) { GWT.log("setLayoutDefinition() is only available for IE (it is not needed for other browsers)", null); } }