/** * 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.block; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; import org.waveprotocol.wave.client.common.util.MeasurerInstance; import org.waveprotocol.wave.client.paging.Block; import org.waveprotocol.wave.client.wavepanel.block.BlockStructure.Node; import org.waveprotocol.wave.model.util.CollectionUtils; import org.waveprotocol.wave.model.util.StringMap; /** * Exposes a view structure as pageable blocks. * */ public final class PageableBlockStructure { /** * Wraps a structural node in order to provide behaviour. * This is temporary until the pager is flyweighted. */ private class NodeImpl implements Block { private final Node source; private Element dom; public NodeImpl(Node source) { this.source = source; } @Override public NodeImpl getParent() { return adapt(source.getParent()); } @Override public NodeImpl getFirstChild() { return adapt(source.getFirstChild()); } @Override public NodeImpl getLastChild() { return adapt(source.getLastChild()); } @Override public NodeImpl getNextSibling() { return adapt(source.getNextSibling()); } @Override public NodeImpl getPreviousSibling() { return adapt(source.getPreviousSibling()); } // // Paging nature. // private Element getElement() { if (dom == null) { String domId = source.getId(); dom = Document.get().getElementById(domId); if (dom == null) { throw new RuntimeException("Block is missing: " + domId); } } return dom; } @Override public double getStart() { return MeasurerInstance.get().top(getRoot().getElement(), getElement()); } @Override public double getEnd() { return MeasurerInstance.get().bottom(getRoot().getElement(), getElement()); } @Override public void pageIn() { handler.pageIn(source); } @Override public void pageOut() { handler.pageOut(source); } @Override public double getChildrenOrigin() { return 0; } } public interface PageHandler { void pageIn(Node block); void pageOut(Node block); } private final StringMap<NodeImpl> nodes = CollectionUtils.createStringMap(); private final BlockStructure view; private final PageHandler handler; private PageableBlockStructure(PageHandler handler, BlockStructure view) { this.handler = handler; this.view = view; } public static PageableBlockStructure create(PageHandler handler, BlockStructure view) { return new PageableBlockStructure(handler, view); } private NodeImpl adapt(Node source) { if (source == null) { return null; } String id = source.getId(); NodeImpl block = nodes.get(id); if (block == null) { block = new NodeImpl(source); nodes.put(id, block); } return block; } public NodeImpl getRoot() { return adapt(view.getRoot()); } public NodeImpl getNode(String id) { return adapt(view.getNode(id)); } }