Package org.apache.wicket.markup.html.link

Source Code of org.apache.wicket.markup.html.link.ClientSideImageMap$UsemapModel

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.wicket.markup.html.link;

import java.awt.Shape;
import java.awt.geom.PathIterator;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.behavior.Behavior;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;

/**
* A client-side image map implementation which allows you to "attach" the map to any existing
* {@link Image} component.
*
* @since 1.5
*/
public class ClientSideImageMap extends Panel
{
  private static final long serialVersionUID = 1L;
  private static final String CIRCLE = "circle";
  private static final String POLYGON = "polygon";
  private static final String RECTANGLE = "rect";

  private RepeatingView areas;

  /**
   * Constructs a client-side image map which is "attached" to the given {@link Image} component.
   *
   * @param id
   *            the component id
   * @param image
   *            the image component
   */
  public ClientSideImageMap(String id, Image image)
  {
    super(id);
    setOutputMarkupId(true);
    add(AttributeModifier.replace("name", new PropertyModel<String>(this, "markupId")));
    image.add(AttributeModifier.replace("usemap", new UsemapModel()));

    areas = new RepeatingView("area");
    add(areas);
  }

  private String circleCoordinates(int x, int y, int radius)
  {
    return x + "," + y + "," + radius;
  }

  private String polygonCoordinates(int... coordinates)
  {
    final StringBuilder buffer = new StringBuilder();
    for (int i = 0; i < coordinates.length; i++)
    {
      buffer.append(coordinates[i]);

      if (i < (coordinates.length - 1))
      {
        buffer.append(',');
      }
    }
    return buffer.toString();
  }

  private String rectangleCoordinates(int x1, int y1, int x2, int y2)
  {
    return x1 + "," + y1 + "," + x2 + "," + y2;
  }

  private String shapeCoordinates(Shape shape)
  {
    final StringBuilder sb = new StringBuilder();
    final PathIterator pi = shape.getPathIterator(null, 1.0);
    final float[] coords = new float[6];
    final float[] lastMove = new float[2];
    while (!pi.isDone())
    {
      switch (pi.currentSegment(coords))
      {
        case PathIterator.SEG_MOVETO :
          if (sb.length() != 0)
          {
            sb.append(',');
          }
          sb.append(Math.round(coords[0]));
          sb.append(',');
          sb.append(Math.round(coords[1]));
          lastMove[0] = coords[0];
          lastMove[1] = coords[1];
          break;
        case PathIterator.SEG_LINETO :
          if (sb.length() != 0)
          {
            sb.append(',');
          }
          sb.append(Math.round(coords[0]));
          sb.append(',');
          sb.append(Math.round(coords[1]));
          break;
        case PathIterator.SEG_CLOSE :
          if (sb.length() != 0)
          {
            sb.append(',');
          }
          sb.append(Math.round(lastMove[0]));
          sb.append(',');
          sb.append(Math.round(lastMove[1]));
          break;
      }
      pi.next();
    }
    return sb.toString();
  }

  @Override
  protected void onComponentTag(ComponentTag tag)
  {
    // Must be attached to an map tag
    checkComponentTag(tag, "map");

    super.onComponentTag(tag);
  }

  /**
   * Generates a unique id string. This makes it easy to add items to be rendered w/out having to
   * worry about generating unique id strings in your code.
   *
   * @return unique child id
   */
  public String newChildId()
  {
    return areas.newChildId();
  }

  /**
   * Adds a circle-shaped area centered at (x,y) with radius r.
   *
   * @param link
   *            the link
   * @param x
   *            x coordinate of the center of the circle
   * @param y
   *            y coordinate of center
   * @param radius
   *            the radius
   * @return this
   */
  public ClientSideImageMap addCircleArea(AbstractLink link, int x, int y, int radius)
  {
    areas.add(link);

    link.add(new Area(circleCoordinates(x, y, radius), CIRCLE));

    return this;
  }

  /**
   * Adds a polygon-shaped area defined by coordinates.
   *
   * @param link
   *            the link
   * @param coordinates
   *            the coordinates for the polygon
   * @return This
   */
  public ClientSideImageMap addPolygonArea(AbstractLink link, int... coordinates)
  {
    areas.add(link);

    link.add(new Area(polygonCoordinates(coordinates), POLYGON));

    return this;
  }

  /**
   * Adds a rectangular-shaped area.
   *
   * @param link
   *            the link
   * @param x1
   *            top left x
   * @param y1
   *            top left y
   * @param x2
   *            bottom right x
   * @param y2
   *            bottom right y
   * @return this
   */
  public ClientSideImageMap addRectangleArea(AbstractLink link, int x1, int y1, int x2, int y2)
  {
    areas.add(link);
    link.add(new Area(rectangleCoordinates(x1, y1, x2, y2), RECTANGLE));
    return this;
  }

  /**
   * Adds an area defined by a shape object.
   *
   * @param link
   *            the link
   * @param shape
   *            the shape
   * @return this
   */
  public ClientSideImageMap addShapeArea(AbstractLink link, Shape shape)
  {
    areas.add(link);
    link.add(new Area(shapeCoordinates(shape), POLYGON));
    return this;
  }

  /**
   * Encapsulates the concept of an <area> within a <map>.
   */
  private static class Area extends Behavior
  {
    private static final long serialVersionUID = 1L;

    private final String coordinates;
    private final String type;

    protected Area(final String coordinates, final String type)
    {
      this.coordinates = coordinates;
      this.type = type;
    }

    @Override
    public void onComponentTag(Component component, ComponentTag tag)
    {
      tag.put("shape", type);
      tag.put("coords", coordinates);
    }
  }

  private class UsemapModel extends Model<String>
  {
    private static final long serialVersionUID = 1L;

    @Override
    public String getObject()
    {
      return "#" + getMarkupId();
    }
  }
}
TOP

Related Classes of org.apache.wicket.markup.html.link.ClientSideImageMap$UsemapModel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.