Package org.waveprotocol.wave.client.wavepanel.impl.focus

Source Code of org.waveprotocol.wave.client.wavepanel.impl.focus.FocusFramePresenter$FocusOrder

/**
* Copyright 2010 Google Inc.
*
*  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.waveprotocol.wave.client.wavepanel.impl.focus;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;

import org.waveprotocol.wave.client.common.util.KeyCombo;
import org.waveprotocol.wave.client.scroll.SmartScroller;
import org.waveprotocol.wave.client.wavepanel.impl.WavePanelImpl;
import org.waveprotocol.wave.client.wavepanel.view.BlipView;
import org.waveprotocol.wave.client.wavepanel.view.FocusFrameView;
import org.waveprotocol.wave.model.util.CopyOnWriteSet;
import org.waveprotocol.wave.model.util.ValueUtils;
import org.waveprotocol.wave.model.wave.SourcesEvents;

/**
* Presents the focus frame, and exposes an API for controlling it.
*
*/
public final class FocusFramePresenter
    implements SourcesEvents<FocusFramePresenter.Listener>, WavePanelImpl.LifecycleListener {

  public interface Listener {
    void onFocusMoved(BlipView oldUi, BlipView newUi);
  }

  public interface FocusOrder {
    BlipView getNext(BlipView current);

    BlipView getPrevious(BlipView current);
  }

  public interface FrameKeyHandler {
    boolean onKeySignal(KeyCombo key, BlipView context);
  }

  /** Focus frame UI. */
  private final FocusFrameView view;

  /** Thing that knows how to move around views. */
  private final ViewTraverser traverser;

  /** Listeners. */
  private final CopyOnWriteSet<Listener> listeners = CopyOnWriteSet.create();

  /** Scroller. */
  private final SmartScroller<? super BlipView> scroller;

  /** Order generator, optionally installed. */
  private FocusOrder order;

  /** Blip that currently has the focus frame. May be {@code null}. */
  private BlipView blip;

  /**
   * Creates a focus-frame presenter.
   */
  @VisibleForTesting
  FocusFramePresenter(
      FocusFrameView view, SmartScroller<? super BlipView> scroller, ViewTraverser traverser) {
    this.view = view;
    this.scroller = scroller;
    this.traverser = traverser;
  }

  //
  // Wave panel lifecycle.
  //

  @Override
  public void onInit() {
  }

  @Override
  public void onReset() {
    blip = null;
  }

  //
  // Focus movement.
  //

  /**
   * Puts the focus frame on a blip.
   */
  public void focus(BlipView blip) {
    Preconditions.checkState(scroller != null);
    Preconditions.checkArgument(blip != null);
    focus(blip, true);
  }

  /**
   * Puts the focus frame on a blip, without forcing it into view.
   */
  public void focusWithoutScroll(BlipView blip) {
    Preconditions.checkState(scroller != null);
    Preconditions.checkArgument(blip != null);
    focus(blip, false);
  }

  /**
   * Moves the focus frame to the previous blip in the vertical ordering, if
   * there is one. If there is no previous blip, this method does nothing.
   */
  public void moveUp() {
    BlipView prev = blip != null ? traverser.getPrevious(blip) : null;
    if (prev != null) {
      focus(prev, true);
    }
  }

  /**
   * Moves the focus frame to the next blip in the vertical ordering, if there
   * is one. If there is no next blip, this method does nothing.
   */
  public void moveDown() {
    BlipView next = blip != null ? traverser.getNext(blip) : null;
    if (next != null) {
      focus(next, true);
    }
  }

  /**
   * Sets the blip that has the focus frame. If {@code blip} is null, the focus
   * frame is removed.
   */
  private void focus(BlipView blip, boolean scroll) {
    if (!ValueUtils.equal(this.blip, blip)) {
      BlipView oldUi = this.blip;
      BlipView newUi = blip;

      // Scroll first, before layout gets invalidated.
      if (newUi != null && scroll) {
        scroller.moveTo(newUi);
      }

      detachChrome();
      this.blip = blip;
      attachChrome();

      fireOnFocusMoved(oldUi, newUi);
    }
  }

  private void detachChrome() {
    if (this.blip != null) {
      this.blip.getMeta().removeFocusChrome(view);
    }
  }

  private void attachChrome() {
    if (this.blip != null) {
      this.blip.getMeta().placeFocusFrame(view);
    }
  }

  //
  // Events.
  //

  @Override
  public void addListener(Listener listener) {
    listeners.add(listener);
  }

  @Override
  public void removeListener(Listener listener) {
    listeners.remove(listener);
  }

  private void fireOnFocusMoved(BlipView oldUi, BlipView newUi) {
    for (Listener listener : listeners) {
      listener.onFocusMoved(oldUi, newUi);
    }
  }

  //
  // Focus ordering / processing.
  //

  /**
   * Moves to the next blip as defined by an attached
   * {@link #setOrder(FocusOrder) ordering}, if there is one.
   */
  public void focusNext() {
    // Real condition is that blip != null implies scroller != null.
    Preconditions.checkState(blip == null || scroller != null);
    if (blip != null && order != null) {
      BlipView next = order.getNext(blip);
      if (next != null) {
        focus(next);
      }
      else {
        focusPrevious();
      }
    }
  }

  /**
   * Moves to the previous blip as defined by an attached
   * {@link #setOrder(FocusOrder) ordering}, if there is one.
   */
  public void focusPrevious() {
    // Real condition is that blip != null implies scroller != null.
    Preconditions.checkState(blip == null || scroller != null);
    if (blip != null && order != null) {
      BlipView next = order.getPrevious(blip);
      if (next != null) {
        focus(next);
      }
    }
  }

  /**
   * Specifies the orderer to use when moving to the next and previous
   * interesting blips.
   */
  public void setOrder(FocusOrder order) {
    this.order = order;
  }

  /** @return the view that is currently focused. */
  public BlipView getFocusedBlip() {
    return blip;
  }
}
TOP

Related Classes of org.waveprotocol.wave.client.wavepanel.impl.focus.FocusFramePresenter$FocusOrder

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.
d', 'pageview');