/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.litho;
import android.graphics.Rect;
/**
* Holds information about a VisibilityOutput (that is, about a component for which a visibility
* event handler has been set). This class is justified by the fact that VisibilityOuput should
* be immutable.
*/
class VisibilityItem {
private static final int FLAG_LEFT_EDGE_VISIBLE = 1 << 1;
private static final int FLAG_TOP_EDGE_VISIBLE = 1 << 2;
private static final int FLAG_RIGHT_EDGE_VISIBLE = 1 << 3;
private static final int FLAG_BOTTOM_EDGE_VISIBLE = 1 << 4;
private static final int FLAG_FOCUSED_RANGE = 1 << 5;
private int mFlags;
private boolean mFocusedFlag;
// The invisible event and unfocused event handlers are required to make it possible to dispatch
// the corresponding event when unbind is called or when the MountState is reset.
private EventHandler<InvisibleEvent> mInvisibleHandler;
private EventHandler<UnfocusedVisibleEvent> mUnfocusedHandler;
public VisibilityItem() {
mFlags = 0;
mInvisibleHandler = null;
mUnfocusedHandler = null;
}
/**
* Sets the invisible event handler.
*/
void setInvisibleHandler(EventHandler<InvisibleEvent> invisibleHandler) {
mInvisibleHandler = invisibleHandler;
}
/**
* Returns the invisible event handler.
*/
EventHandler<InvisibleEvent> getInvisibleHandler() {
return mInvisibleHandler;
}
/**
* Sets the unfocused event handler.
*/
void setUnfocusedHandler(EventHandler<UnfocusedVisibleEvent> unfocusedHandler) {
mUnfocusedHandler = unfocusedHandler;
}
/**
* Returns the unfocused event handler.
*/
EventHandler<UnfocusedVisibleEvent> getUnfocusedHandler() {
return mUnfocusedHandler;
}
boolean isInFocusedRange() {
return mFocusedFlag;
}
void setFocusedRange(boolean flag) {
mFocusedFlag = flag;
}
/**
* Returns true if the component associated with this VisibilityItem is in the full impression
* range.
*/
boolean isInFullImpressionRange() {
final int allEdgesVisible = FLAG_LEFT_EDGE_VISIBLE
| FLAG_TOP_EDGE_VISIBLE
| FLAG_RIGHT_EDGE_VISIBLE
| FLAG_BOTTOM_EDGE_VISIBLE;
return (mFlags & allEdgesVisible) == allEdgesVisible;
}
/**
* Sets the flags corresponding to the edges of the component that are visible. Afterwards, it
* checks if the component has entered the full impression visible range and, if so, it sets the
* appropriate flag.
*/
void setVisibleEdges(Rect componentBounds, Rect componentVisibleBounds) {
if (componentBounds.top == componentVisibleBounds.top) {
mFlags |= FLAG_TOP_EDGE_VISIBLE;
}
if (componentBounds.bottom == componentVisibleBounds.bottom) {
mFlags |= FLAG_BOTTOM_EDGE_VISIBLE;
}
if (componentBounds.left == componentVisibleBounds.left) {
mFlags |= FLAG_LEFT_EDGE_VISIBLE;
}
if (componentBounds.right == componentVisibleBounds.right) {
mFlags |= FLAG_RIGHT_EDGE_VISIBLE;
}
}
void release() {
mFlags = 0;
mInvisibleHandler = null;
mUnfocusedHandler = null;
}
}