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