/*******************************************************************************
* Copyright 2013 Comcast Cable Communications Management, LLC
*
* 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.marshalchen.common.uimodule.freeflow.layouts;
import java.util.LinkedHashMap;
import com.marshalchen.common.uimodule.freeflow.core.FreeFlowItem;
import com.marshalchen.common.uimodule.freeflow.core.Section;
import com.marshalchen.common.uimodule.freeflow.core.SectionedAdapter;
import com.marshalchen.common.uimodule.freeflow.layouts.FreeFlowLayout.FreeFlowLayoutParams;
import com.marshalchen.common.uimodule.freeflow.layouts.HLayout.LayoutParams;
import com.marshalchen.common.uimodule.freeflow.utils.ViewUtils;
import android.graphics.Rect;
public class VLayout extends FreeFlowLayoutBase implements FreeFlowLayout {
private static final String TAG = "VLayout";
private int itemHeight = -1;
private LinkedHashMap<Object, FreeFlowItem> proxies = new LinkedHashMap<Object, FreeFlowItem>();
private int headerHeight = -1;
private int headerWidth = -1;
private int cellBufferSize = 0;
private int bufferCount = 1;
protected FreeFlowLayoutParams layoutParams;
@Override
public void setLayoutParams(FreeFlowLayoutParams params) {
if (params.equals(this.layoutParams)) {
return;
}
LayoutParams lp = (LayoutParams) params;
this.itemHeight = lp.itemHeight;
this.headerWidth = lp.headerWidth;
this.headerHeight = lp.headerHeight;
cellBufferSize = bufferCount * cellBufferSize;
}
public void prepareLayout() {
if (itemHeight < 0) {
throw new IllegalStateException("itemHeight not set");
}
proxies.clear();
int topStart = 0;
for (int i = 0; i < itemsAdapter.getNumberOfSections(); i++) {
Section s = itemsAdapter.getSection(i);
if (itemsAdapter.shouldDisplaySectionHeaders()) {
if (headerWidth < 0) {
throw new IllegalStateException("headerWidth not set");
}
if (headerHeight < 0) {
throw new IllegalStateException("headerHeight not set");
}
FreeFlowItem header = new FreeFlowItem();
Rect hframe = new Rect();
header.itemSection = i;
header.itemIndex = -1;
header.isHeader = true;
hframe.left = 0;
hframe.top = topStart;
hframe.right = headerWidth;
hframe.bottom = topStart + headerHeight;
header.frame = hframe;
header.data = s.getHeaderData();
proxies.put(header.data, header);
topStart += headerHeight;
}
for (int j = 0; j < s.getDataCount(); j++) {
FreeFlowItem descriptor = new FreeFlowItem();
Rect frame = new Rect();
descriptor.itemSection = i;
descriptor.itemIndex = j;
frame.left = 0;
frame.top = j * itemHeight + topStart;
frame.right = width;
frame.bottom = frame.top + itemHeight;
descriptor.frame = frame;
descriptor.data = s.getDataAtIndex(j);
proxies.put(descriptor.data, descriptor);
}
topStart += (s.getDataCount()) * itemHeight;
}
}
/**
* NOTE: In this instance, we subtract/add the cellBufferSize (computed when
* item height is set, defaulted to 1 cell) to add a buffer of
* cellBufferSize to each end of the viewport. <br>
*
* {@inheritDoc}
*
*/
@Override
public LinkedHashMap<Object, FreeFlowItem> getItemProxies(
int viewPortLeft, int viewPortTop) {
LinkedHashMap<Object, FreeFlowItem> desc = new LinkedHashMap<Object, FreeFlowItem>();
for (FreeFlowItem fd : proxies.values()) {
if (fd.frame.top + itemHeight > viewPortTop - cellBufferSize
&& fd.frame.top < viewPortTop + height + cellBufferSize) {
desc.put(fd.data, fd);
}
}
return desc;
}
@Override
public boolean horizontalScrollEnabled() {
return false;
}
@Override
public boolean verticalScrollEnabled() {
return true;
}
@Override
public int getContentWidth() {
return width;
}
@Override
public int getContentHeight() {
if (itemsAdapter == null || itemsAdapter.getNumberOfSections() <= 0){
return 0;
}
int sectionIndex = itemsAdapter.getNumberOfSections() - 1;
Section s = itemsAdapter.getSection(sectionIndex);
if (s.getDataCount() == 0)
return 0;
Object lastFrameData = s.getDataAtIndex(s.getDataCount() - 1);
FreeFlowItem fd = proxies.get(lastFrameData);
return (fd.frame.top + fd.frame.height());
}
@Override
public FreeFlowItem getFreeFlowItemForItem(Object data) {
return proxies.get(data);
}
@Override
public FreeFlowItem getItemAt(float x, float y) {
return ViewUtils.getItemAt(proxies, (int) x, (int) y);
}
public void setBufferCount(int bufferCount) {
this.bufferCount = bufferCount;
}
public static class LayoutParams extends FreeFlowLayoutParams {
public int itemHeight = 0;
public int headerWidth = 0;
public int headerHeight = 0;
public LayoutParams(int itemHeight) {
this.itemHeight = itemHeight;
}
public LayoutParams(int itemHeight, int headerWidth, int headerHeight) {
this.itemHeight = itemHeight;
this.headerWidth = headerWidth;
this.headerHeight = headerHeight;
}
}
}