/*******************************************************************************
* 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 java.util.Map;
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.VGridLayout.LayoutParams;
import com.marshalchen.common.uimodule.freeflow.utils.ViewUtils;
import android.graphics.Rect;
public class HGridLayout extends FreeFlowLayoutBase implements FreeFlowLayout {
private static final String TAG = "HGridLayout";
private int itemHeight = -1;
private int itemWidth = -1;
private Map<Object, FreeFlowItem> proxies = new LinkedHashMap<Object, FreeFlowItem>();
private int headerWidth = -1;
private int headerHeight = -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.itemWidth = lp.itemWidth;
this.itemHeight = lp.itemHeight;
this.headerWidth = lp.headerWidth;
this.headerHeight = lp.headerHeight;
cellBufferSize = bufferCount * cellBufferSize;
}
public void prepareLayout() {
proxies.clear();
int rows = height / itemHeight;
int leftStart = 0;
for (int i = 0; i < itemsAdapter.getNumberOfSections(); i++) {
Section s = itemsAdapter.getSection(i);
if (itemsAdapter.shouldDisplaySectionHeaders()) {
FreeFlowItem header = new FreeFlowItem();
Rect hframe = new Rect();
header.itemSection = i;
header.itemIndex = -1;
header.isHeader = true;
hframe.left = leftStart;
hframe.top = 0;
hframe.right = leftStart + headerWidth;
hframe.bottom = headerHeight;
header.frame = hframe;
header.data = s.getHeaderData();
proxies.put(header.data, header);
leftStart += headerWidth;
}
for (int j = 0; j < s.getDataCount(); j++) {
FreeFlowItem descriptor = new FreeFlowItem();
Rect frame = new Rect();
descriptor.itemSection = i;
descriptor.itemIndex = j;
frame.left = (j / rows) * itemWidth + leftStart;
frame.top = (j % rows) * itemHeight;
frame.right = frame.left + itemWidth;
frame.bottom = frame.top + itemHeight;
descriptor.frame = frame;
descriptor.data = s.getDataAtIndex(j);
proxies.put(descriptor.data, descriptor);
}
int mod = 0;
if (s.getDataCount() % rows != 0)
mod = 1;
leftStart += ((s.getDataCount() / rows) + mod) * itemWidth;
}
}
/**
* NOTE: In this instance, we subtract/add the cellBufferSize (computed when
* item width 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.left + itemWidth > viewPortLeft - cellBufferSize
&& fd.frame.left < viewPortLeft + width + cellBufferSize) {
desc.put(fd.data, fd);
}
}
return desc;
}
@Override
public FreeFlowItem getItemAt(float x, float y){
return ViewUtils.getItemAt(proxies, (int)x, (int)y);
}
@Override
public boolean horizontalScrollEnabled() {
return true;
}
@Override
public boolean verticalScrollEnabled() {
return false;
}
@Override
public int getContentWidth() {
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.left + fd.frame.width());
}
@Override
public int getContentHeight() {
if (itemsAdapter == null)
return 0;
return height;
}
@Override
public FreeFlowItem getFreeFlowItemForItem(Object data) {
return proxies.get(data);
}
public void setBufferCount(int bufferCount) {
this.bufferCount = bufferCount;
}
public static class LayoutParams extends FreeFlowLayoutParams{
public int itemWidth = 0;
public int itemHeight = 0;
public int headerWidth = 0;
public int headerHeight = 0;
public LayoutParams(int itemWidth, int itemHeight){
this.itemWidth = itemWidth;
this.itemHeight = itemHeight;
}
public LayoutParams(int itemWidth, int itemHeight, int headerWidth, int headerHeight){
this.itemWidth = itemWidth;
this.itemHeight = itemHeight;
this.headerWidth = headerWidth;
this.headerHeight = headerHeight;
}
}
}