Package com.googlecode.mgwt.ui.client.widget.list.celllist

Source Code of com.googlecode.mgwt.ui.client.widget.list.celllist.CellList$EntryTemplate

/*
* Copyright 2010 Daniel Kurka
*
* 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 com.googlecode.mgwt.ui.client.widget.list.celllist;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.EventTarget;
import com.google.gwt.dom.client.Node;
import com.google.gwt.dom.client.Touch;
import com.google.gwt.event.dom.client.TouchCancelEvent;
import com.google.gwt.event.dom.client.TouchEndEvent;
import com.google.gwt.event.dom.client.TouchMoveEvent;
import com.google.gwt.event.dom.client.TouchStartEvent;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.uibinder.client.UiFactory;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Widget;

import com.googlecode.mgwt.dom.client.event.tap.Tap;
import com.googlecode.mgwt.dom.client.event.touch.TouchHandler;
import com.googlecode.mgwt.dom.client.recognizer.EventPropagator;
import com.googlecode.mgwt.ui.client.widget.touch.TouchWidgetImpl;

import java.util.List;

/**
*
* A widget that renders its children as a list
*
* You can control the markup of the children by using the Cell interface, therefore you can render
* any kind of arbitrary markup
*
* <h2>Styling</h2> The DOM will look like this:
*
* <pre>
* &lt;ul class="mgwt-List">
*  &lt;li class="mgwt-List-first">&lt;!-- your markup -->&lt;/li>
*  &lt;li class="">&lt;!-- your markup -->&lt;/li>
*  ...
*  &lt;li class="mgwt-List-last">&lt;!-- your markup -->&lt;/li>
* &lt;/ul>
* </pre>
*
* These styles will be applied to the main ul element:
*
* <ul>
* <li>.mgwt-List-round- if the list should be rendered with rounded corners</li>
* </ul>
*
* These styles will be applied to one or more of the li elements:
* <ul>
* <li>.mgwt-List-selected - if the li got selected</li>
* <li>.mgwt-List-group - if the element should be rendered as selectable (is has more content)</li>
* </ul>
*
* @author Daniel Kurka
* @param <T> the type of the model to render
*/
public class CellList<T> extends Widget implements HasCellSelectedHandler {


  public interface EntryTemplate {
    SafeHtml li(int idx, String classes, SafeHtml cellContents);
  }

  protected static final EventPropagator EVENT_PROPAGATOR = GWT.create(EventPropagator.class);


  private class InternalTouchHandler implements TouchHandler {

    private boolean moved;
    private int index;
    private Element node;
    private int x;
    private int y;
    private boolean started;
    private Element originalElement;

    @Override
    public void onTouchCancel(TouchCancelEvent event) {

    }

    @Override
    public void onTouchMove(TouchMoveEvent event) {
      Touch touch = event.getTouches().get(0);
      if (Math.abs(touch.getPageX() - x) > Tap.RADIUS
          || Math.abs(touch.getPageY() - y) > Tap.RADIUS) {
        moved = true;
        // deselect
        if (node != null) {
          node.removeClassName(CellList.this.appearance.css().selected());
          stopTimer();
        }

      }

    }

    @Override
    public void onTouchEnd(TouchEndEvent event) {
      if (node != null) {
        node.removeClassName(CellList.this.appearance.css().selected());
        stopTimer();
      }
      if (started && !moved && index != -1) {
        fireSelectionAtIndex(index, originalElement);
      }
      node = null;
      started = false;

    }

    @Override
    public void onTouchStart(TouchStartEvent event) {
      started = true;

      x = event.getTouches().get(0).getPageX();
      y = event.getTouches().get(0).getPageY();

      if (node != null) {
        node.removeClassName(CellList.this.appearance.css().selected());
      }
      moved = false;
      index = -1;
      // Get the event target.
      EventTarget eventTarget = event.getNativeEvent().getEventTarget();
      if (eventTarget == null) {
        return;
      }

      // no textnode or element node
      if (!Node.is(eventTarget) && !Element.is(eventTarget)) {
        return;
      }

      event.preventDefault();

      // text node use the parent..
      if (Node.is(eventTarget) && !Element.is(eventTarget)) {
        Node target = Node.as(eventTarget);
        eventTarget = target.getParentElement().cast();
      }

      // no element
      if (!Element.is(eventTarget)) {
        return;
      }
      Element target = eventTarget.cast();

      originalElement = target;

      // Find cell
      String idxString = "";
      while ((target != null) && ((idxString = target.getAttribute("__idx")).length() == 0)) {

        target = target.getParentElement();
      }
      if (idxString.length() > 0) {
        try {
          index = Integer.parseInt(idxString);
          node = target;
          startTimer(node);
        } catch (Exception e) {
        }
      }

    }
  }

  private static final CellListAppearance DEFAULT_APPEARANCE = GWT.create(CellListAppearance.class);

  private static final TouchWidgetImpl impl = GWT.create(TouchWidgetImpl.class);

  protected final Cell<T> cell;

  protected Timer timer;

  @UiField
  protected Element container;
  private CellListAppearance appearance;

  protected EntryTemplate entryTemplate;

  /**
   * Construct a CellList
   *
   * @param cell the cell to use
   */
  public CellList(Cell<T> cell) {
    this(cell, DEFAULT_APPEARANCE);
  }

  /**
   * Construct a celllist with a given cell and css
   *
   * @param cell the cell to use
   * @param css the css to use
   */
  public CellList(Cell<T> cell, CellListAppearance appearance) {

    this.cell = cell;
    this.appearance = appearance;

    setElement(this.appearance.uiBinder().createAndBindUi(this));
    entryTemplate = this.appearance.getEntryTemplate();

    InternalTouchHandler touchHandler = new InternalTouchHandler();
    impl.addTouchHandler(this, touchHandler);
  }

  public HandlerRegistration addCellSelectedHandler(CellSelectedHandler cellSelectedHandler) {
    return addHandler(cellSelectedHandler, CellSelectedEvent.getType());
  }

  /**
   * Render a List of models in this cell list
   *
   * @param models the list of models to render
   */
  public void render(List<T> models) {

    SafeHtmlBuilder sb = new SafeHtmlBuilder();

    for (int i = 0; i < models.size(); i++) {

      T model = models.get(i);

      SafeHtmlBuilder cellBuilder = new SafeHtmlBuilder();

      String clazz = "";
      if (cell.canBeSelected(model)) {
        clazz = this.appearance.css().canbeSelected() + " ";
      }

      if (i == 0) {
        clazz += this.appearance.css().first() + " ";
      }

      if (models.size() - 1 == i) {
        clazz += this.appearance.css().last() + " ";
      }

      cell.render(cellBuilder, model);

      sb.append(entryTemplate.li(i, clazz, cellBuilder.toSafeHtml()));
    }

    final String html = sb.toSafeHtml().asString();

    getElement().setInnerHTML(html);

    if (models.size() > 0) {
      String innerHTML = getElement().getInnerHTML();
      if ("".equals(innerHTML.trim())) {
        fixBug(html);
      }
    }

  }

  /**
   * Set a selected element in the celllist
   *
   * @param index the index of the element
   * @param selected true to select the element, false to deselect
   */
  public void setSelectedIndex(int index, boolean selected) {
    Node node = getElement().getChild(index);
    Element li = Element.as(node);
    if (selected) {
      li.addClassName(this.appearance.css().selected());
    } else {
      li.removeClassName(this.appearance.css().selected());
    }
  }

  protected void fixBug(final String html) {
    new Timer() {

      @Override
      public void run() {
        getElement().setInnerHTML(html);
        String innerHTML = getElement().getInnerHTML();
        if ("".equals(innerHTML.trim())) {
          fixBug(html);

        }

      }
    }.schedule(100);
  }

  protected void fireSelectionAtIndex(int index, Element element) {
    EVENT_PROPAGATOR.fireEvent(this, new CellSelectedEvent(index, element));
  }

  @UiFactory
  protected CellListAppearance getAppearance() {
    return appearance;
  }

  protected void startTimer(final Element node) {
    if (timer != null) {
      timer.cancel();
      timer = null;
    }

    timer = new Timer() {

      @Override
      public void run() {
        node.addClassName(CellList.this.appearance.css().selected());
      }
    };
    timer.schedule(150);
  }

  protected void stopTimer() {
    if (timer != null) {
      timer.cancel();
      timer = null;
    }
  }
}
TOP

Related Classes of com.googlecode.mgwt.ui.client.widget.list.celllist.CellList$EntryTemplate

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.