/*
* Copyright (c) 2012 Socialize Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.socialize.ui.slider;
import android.content.Context;
import android.view.View;
import android.view.animation.Animation;
import com.socialize.android.ioc.IBeanFactory;
import com.socialize.log.SocializeLogger;
import com.socialize.ui.actionbar.ActionBarView;
import com.socialize.util.DisplayUtils;
import com.socialize.view.BaseView;
import java.util.Map;
import java.util.TreeMap;
/**
* @author Jason Polites
*
*/
public class ActionBarSliderView extends BaseView {
public enum DisplayState {CLOSE, MAXIMIZE, PEEK};
private DisplayUtils displayUtils;
private IBeanFactory<SliderAnimationSet> sliderAnimationSetFactory;
private IBeanFactory<ActionBarSliderContent> actionBarSliderContentFactory;
private IBeanFactory<ActionBarSliderHandle> actionBarSliderHandleFactory;
private Map<String, SliderAnimationSet> animations;
private SliderAnimationSet currentAnimationSet;
private SocializeLogger logger;
private int[] parentViewlocation;
private ActionBarSliderHandle handle;
private ActionBarSliderContent content;
private DisplayState displayState = DisplayState.CLOSE;
private int handleHeight = 30;
private int actionBarTop;
private int actionBarHeight;
private int deviceHeight;
private int peekHeight;
private boolean moving = false;
private ActionBarSliderItem currentItem;
public OnActionBarSliderMoveListener onActionBarSliderMoveListener;
public ActionBarSliderView(Context context) {
super(context);
}
public ActionBarSliderView(Context context, int[] parentLocation, int peekHeight) {
super(context);
this.parentViewlocation = parentLocation;
this.peekHeight = peekHeight;
}
public void init() {
deviceHeight = displayUtils.getDisplayHeight();
actionBarHeight = displayUtils.getDIP(ActionBarView.ACTION_BAR_HEIGHT);
animations = new TreeMap<String, SliderAnimationSet>();
if(peekHeight > 0) {
actionBarTop = peekHeight;
}
else {
if(parentViewlocation != null) {
actionBarTop = parentViewlocation[1];
}
else {
actionBarTop = deviceHeight - actionBarHeight;
}
}
LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
params.setMargins(0,0,0,0);
setLayoutParams(params);
setOrientation(VERTICAL);
handleHeight = displayUtils.getDIP(handleHeight);
content = actionBarSliderContentFactory.getBean(this, deviceHeight-handleHeight);
handle = actionBarSliderHandleFactory.getBean(this, handleHeight);
addView(handle);
addView(content);
}
public void clearContent() {
if(currentItem != null) {
currentItem.onClear(this);
}
}
public void updateContent() {
if(currentItem != null) {
currentItem.onUpdate(this);
}
}
public boolean showLastItem() {
if(currentItem != null) {
showSliderItem(currentItem);
return true;
}
return false;
}
public synchronized void loadItem(ActionBarSliderItem item) {
if(logger != null && logger.isDebugEnabled()) {
logger.debug("Loading slider item for " + item.getId());
}
if(currentItem != item) {
currentItem = item;
content.removeAllViews();
content.addView(item.getView());
handle.setTitle(item.getTitle());
handle.setIconImage(item.getIconImage());
currentAnimationSet = animations.get(item.getId());
if(currentAnimationSet == null) {
currentAnimationSet = sliderAnimationSetFactory.getBean();
currentAnimationSet.init(item, this);
animations.put(item.getId(), currentAnimationSet);
}
currentItem.onCreate(this);
}
}
public void showSliderItem(ActionBarSliderItem item) {
if(logger != null && logger.isDebugEnabled()) {
logger.debug("Showing slider item for " + item.getId());
}
if(content != null) {
if(item != null) {
DisplayState state = item.getStartPosition();
if(item != currentItem) {
if(logger != null && logger.isDebugEnabled()) {
logger.debug("Don't have item [" +
item.getId() +
"], current state is " + displayState);
}
close();
loadItem(item);
switch (state) {
case PEEK:
peek();
break;
case MAXIMIZE:
maximize();
break;
}
}
else {
if(logger != null && logger.isDebugEnabled()) {
logger.debug("Already have item [" +
item.getId() +
"], current state is " + displayState);
}
if(!displayState.equals(state)) {
switch (state) {
case PEEK:
peek();
break;
case MAXIMIZE:
maximize();
break;
}
}
}
}
}
}
public void addContentItem(View child) {
if(content != null) {
content.addView(child);
}
}
public void setHandleText(String text) {
handle.setTitle(text);
}
public void maximize() {
if(logger != null && logger.isDebugEnabled()) {
logger.debug("maximize called in state " + displayState);
}
switch (displayState) {
case CLOSE:
startAnimationForState(currentAnimationSet.getMaximizeFromClose(), DisplayState.MAXIMIZE);
break;
case PEEK:
startAnimationForState(currentAnimationSet.getMaximizeFromPeek(), DisplayState.MAXIMIZE);
break;
}
}
protected void startAnimationForState(Animation animation, DisplayState state) {
// Animation doesn't always seem to work.. force an invalidate
setVisibility(View.VISIBLE);
clearAnimation();
displayState = state;
if(logger != null && logger.isDebugEnabled()) {
logger.debug("starting animation for state " + state);
}
startAnimation(animation);
}
public void peek() {
if(logger != null && logger.isDebugEnabled()) {
logger.debug("peek called in state " + displayState);
}
switch (displayState) {
case CLOSE:
startAnimationForState(currentAnimationSet.getPeekFromClose(), DisplayState.PEEK);
break;
case MAXIMIZE:
startAnimationForState(currentAnimationSet.getPeekFromMaximize(), DisplayState.PEEK);
break;
}
}
public void close() {
if(logger != null && logger.isDebugEnabled()) {
logger.debug("close called in state " + displayState);
}
switch (displayState) {
case MAXIMIZE:
startAnimationForState(currentAnimationSet.getCloseFromMaximized(), DisplayState.CLOSE);
break;
case PEEK:
startAnimationForState(currentAnimationSet.getCloseFromPeek(), DisplayState.CLOSE);
break;
}
displayState = DisplayState.CLOSE;
}
public void onClose() {
if(currentItem != null) {
currentItem.onClose(this);
}
if(onActionBarSliderMoveListener != null) {
onActionBarSliderMoveListener.onClose(this);
}
}
public void onOpen() {
if(currentItem != null) {
currentItem.onOpen(this);
}
if(onActionBarSliderMoveListener != null) {
onActionBarSliderMoveListener.onOpen(this);
}
}
public void slide() {
if(logger != null && logger.isDebugEnabled()) {
logger.debug("slide called in state " + displayState);
}
if(!moving) {
moving = true;
switch(displayState) {
case CLOSE:
peek();
break;
case PEEK:
maximize();
break;
case MAXIMIZE:
if(currentItem.isPeekOnClose()) {
peek();
}
else {
close();
}
break;
}
}
}
public void setDisplayUtils(DisplayUtils deviceUtils) {
this.displayUtils = deviceUtils;
}
public void setLogger(SocializeLogger logger) {
this.logger = logger;
}
public int[] getParentViewlocation() {
return parentViewlocation;
}
public void setParentViewlocation(int[] parentViewlocation) {
this.parentViewlocation = parentViewlocation;
}
public void setSliderAnimationSetFactory(IBeanFactory<SliderAnimationSet> sliderAnimationSetFactory) {
this.sliderAnimationSetFactory = sliderAnimationSetFactory;
}
public void setActionBarSliderContentFactory(IBeanFactory<ActionBarSliderContent> actionBarSliderContentFactory) {
this.actionBarSliderContentFactory = actionBarSliderContentFactory;
}
public void setActionBarSliderHandleFactory(IBeanFactory<ActionBarSliderHandle> actionBarSliderHandleFactory) {
this.actionBarSliderHandleFactory = actionBarSliderHandleFactory;
}
protected boolean isMoving() {
return moving;
}
protected void setMoving(boolean moving) {
this.moving = moving;
}
protected ActionBarSliderHandle getHandle() {
return handle;
}
protected ActionBarSliderContent getContent() {
return content;
}
public DisplayState getDisplayState() {
return displayState;
}
protected int getHandleHeight() {
return handleHeight;
}
protected int getActionBarTop() {
return actionBarTop;
}
protected int getActionBarHeight() {
return actionBarHeight;
}
protected int getDeviceHeight() {
return deviceHeight;
}
}