package hk.hku.cs.srli.widget;
import android.content.Context;
import android.graphics.drawable.TransitionDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
import hk.hku.cs.srli.widget.util.HoverHandler;
public class HoverDiscloseLayout extends RelativeLayout {
private HoverHandler hover;
private boolean dimmed;
public HoverDiscloseLayout(Context context) {
super(context);
init();
}
public HoverDiscloseLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public HoverDiscloseLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
hover = new HoverHandler(this, HoverHandler.HOVER_TIMEOUT * 2);
if (!HoverHandler.isHoverEnabled(getContext())) {
// disable itself
setEnabled(false);
}
setBackgroundResource(R.drawable.transition_dim);
dimmed = false;
}
@Override
protected void onFinishInflate() {
if (isEnabled()) setAllChildrenVisibility(INVISIBLE);
super.onFinishInflate();
}
@Override
public void onHoverChanged(boolean hovered) {
TransitionDrawable transition = (TransitionDrawable) getBackground();
// animate background transition
if (hovered) {
if (dimmed) {
transition.reverseTransition(250);
dimmed = false;
}
} else {
transition.startTransition(500);
dimmed = true;
}
super.onHoverChanged(hovered);
if (isEnabled()) updateChildrenVisibility();
}
@Override
public boolean onHoverEvent(MotionEvent event) {
hover.onHoverEvent(event);
// do not consume the event
return false;
}
@Override
protected boolean dispatchHoverEvent(MotionEvent event) {
boolean ret = super.dispatchHoverEvent(event);
if (isEnabled()) updateChildrenVisibility();
return ret;
}
private void updateChildrenVisibility() {
if (isHovered() || hasActiveChild()) {
setAllChildrenVisibility(VISIBLE);
} else {
setAllChildrenVisibility(INVISIBLE);
}
}
private boolean hasActiveChild() {
for(int i = 0; i < getChildCount(); ++i) {
boolean ret = false;
View child = getChildAt(i);
ret |= child.isHovered();
ret |= child.isPressed();
ret |= child.isSelected();
ret |= child.isFocused();
if (ret) return true;
}
return false;
}
private void setAllChildrenVisibility(int visibility) {
for(int i = 0; i < getChildCount(); ++i) {
// TODO: maintain original state if child is already hidden.
getChildAt(i).setVisibility(visibility);
}
}
}