PanelBar.java revision 1e8feef1faca7d2f14bf459691dbe724c8cf5c88
1package com.android.systemui.statusbar.phone;
2
3import java.util.ArrayList;
4
5import android.content.Context;
6import android.util.AttributeSet;
7import android.util.Slog;
8import android.view.MotionEvent;
9import android.widget.FrameLayout;
10
11public class PanelBar extends FrameLayout {
12    public static final boolean DEBUG = false;
13    public static final String TAG = PanelView.class.getSimpleName();
14    public static final void LOG(String fmt, Object... args) {
15        if (!DEBUG) return;
16        Slog.v(TAG, String.format(fmt, args));
17    }
18
19    private PanelHolder mPanelHolder;
20    private ArrayList<PanelView> mPanels = new ArrayList<PanelView>();
21    protected PanelView mTouchingPanel;
22    private static final int STATE_CLOSED = 0;
23    private static final int STATE_TRANSITIONING = 1;
24    private static final int STATE_OPEN = 2;
25    private int mState = STATE_CLOSED;
26    private boolean mTracking;
27
28    private void go(int state) {
29        LOG("go state: %d -> %d", mState, state);
30        mState = state;
31    }
32
33    public PanelBar(Context context, AttributeSet attrs) {
34        super(context, attrs);
35    }
36
37    @Override
38    protected void onFinishInflate() {
39        super.onFinishInflate();
40    }
41
42    public void addPanel(PanelView pv) {
43        mPanels.add(pv);
44        pv.setBar(this);
45    }
46
47    public void setPanelHolder(PanelHolder ph) {
48        if (ph == null) {
49            Slog.e(TAG, "setPanelHolder: null PanelHolder", new Throwable());
50            return;
51        }
52        ph.setBar(this);
53        mPanelHolder = ph;
54        final int N = ph.getChildCount();
55        for (int i=0; i<N; i++) {
56            final PanelView v = (PanelView) ph.getChildAt(i);
57            if (v != null) {
58                addPanel(v);
59            }
60        }
61    }
62
63    public float getBarHeight() {
64        return getMeasuredHeight();
65    }
66
67    public PanelView selectPanelForTouchX(float x) {
68        final int N = mPanels.size();
69        return mPanels.get((int)(N * x / getMeasuredWidth()));
70    }
71
72    public boolean isEnabled() {
73        return true;
74    }
75
76    @Override
77    public boolean onTouchEvent(MotionEvent event) {
78        // Allow subclasses to implement enable/disable semantics
79        if (!isEnabled()) return false;
80
81        // figure out which panel needs to be talked to here
82        if (event.getAction() == MotionEvent.ACTION_DOWN) {
83            mTouchingPanel = selectPanelForTouchX(event.getX());
84            mPanelHolder.setSelectedPanel(mTouchingPanel);
85            LOG("PanelBar.onTouch: state=%d ACTION_DOWN: panel %s", mState, mTouchingPanel.getName());
86            if (mState == STATE_CLOSED || mState == STATE_OPEN) {
87                go(STATE_TRANSITIONING);
88                onPanelPeeked();
89            }
90        }
91        final boolean result = mTouchingPanel.getHandle().dispatchTouchEvent(event);
92        return result;
93    }
94
95    public void panelExpansionChanged(PanelView panel, float frac) {
96        boolean fullyClosed = true;
97        PanelView fullyOpenedPanel = null;
98        LOG("panelExpansionChanged: start state=%d panel=%s", mState, panel.getName());
99        for (PanelView pv : mPanels) {
100            // adjust any other panels that may be partially visible
101            if (pv.getExpandedHeight() > 0f) {
102                fullyClosed = false;
103                final float thisFrac = pv.getExpandedFraction();
104                LOG("panelExpansionChanged:  -> %s: f=%.1f", pv.getName(), thisFrac);
105                if (panel == pv) {
106                    if (thisFrac == 1f) fullyOpenedPanel = panel;
107                } else {
108                    pv.setExpandedFraction(1f-frac);
109                }
110            }
111        }
112        if (fullyOpenedPanel != null && !mTracking) {
113            go(STATE_OPEN);
114            onPanelFullyOpened(fullyOpenedPanel);
115        } else if (fullyClosed && !mTracking) {
116            go(STATE_CLOSED);
117            onAllPanelsCollapsed();
118        }
119
120        LOG("panelExpansionChanged: end state=%d [%s%s ]", mState,
121                (fullyOpenedPanel!=null)?" fullyOpened":"", fullyClosed?" fullyClosed":"");
122    }
123
124    public void collapseAllPanels(boolean animate) {
125        for (PanelView pv : mPanels) {
126            if (animate && pv == mTouchingPanel) {
127                mTouchingPanel.collapse();
128            } else {
129                pv.setExpandedFraction(0); // just in case
130            }
131        }
132    }
133
134    public void onPanelPeeked() {
135        LOG("onPanelPeeked");
136    }
137
138    public void onAllPanelsCollapsed() {
139        LOG("onAllPanelsCollapsed");
140    }
141
142    public void onPanelFullyOpened(PanelView openPanel) {
143        LOG("onPanelFullyOpened");
144    }
145
146    public void onTrackingStarted(PanelView panel) {
147        mTracking = true;
148        if (panel != mTouchingPanel) {
149            LOG("shouldn't happen: onTrackingStarted(%s) != mTouchingPanel(%s)",
150                    panel, mTouchingPanel);
151        }
152    }
153
154    public void onTrackingStopped(PanelView panel) {
155        mTracking = false;
156        panelExpansionChanged(panel, panel.getExpandedFraction());
157    }
158}
159