PanelBar.java revision 919adac28bd6a9888c3bbd53a1736f260bc76bbf
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            boolean enabled = panel.isEnabled();
87            LOG("PanelBar.onTouch: state=%d ACTION_DOWN: panel %s %s", mState, panel,
88                    (enabled ? "" : " (disabled)"));
89            if (!enabled)
90                return false;
91            startOpeningPanel(panel);
92        }
93        final boolean result = mTouchingPanel.getHandle().dispatchTouchEvent(event);
94        return result;
95    }
96
97    // called from PanelView when self-expanding, too
98    public void startOpeningPanel(PanelView panel) {
99        LOG("startOpeningPanel: " + panel);
100        mTouchingPanel = panel;
101        mPanelHolder.setSelectedPanel(mTouchingPanel);
102    }
103
104    public void panelExpansionChanged(PanelView panel, float frac) {
105        boolean fullyClosed = true;
106        PanelView fullyOpenedPanel = null;
107        LOG("panelExpansionChanged: start state=%d panel=%s", mState, panel.getName());
108        for (PanelView pv : mPanels) {
109            final boolean visible = pv.getVisibility() == View.VISIBLE;
110            // adjust any other panels that may be partially visible
111            if (pv.getExpandedHeight() > 0f) {
112                if (mState == STATE_CLOSED) {
113                    go(STATE_OPENING);
114                    onPanelPeeked();
115                }
116                fullyClosed = false;
117                final float thisFrac = pv.getExpandedFraction();
118                LOG("panelExpansionChanged:  -> %s: f=%.1f", pv.getName(), thisFrac);
119                if (panel == pv) {
120                    if (thisFrac == 1f) fullyOpenedPanel = panel;
121                } else {
122                    pv.setExpandedFraction(1f-frac);
123                }
124            }
125            if (pv.getExpandedHeight() > 0f) {
126                if (!visible) pv.setVisibility(View.VISIBLE);
127            } else {
128                if (visible) pv.setVisibility(View.GONE);
129            }
130        }
131        if (fullyOpenedPanel != null && !mTracking) {
132            go(STATE_OPEN);
133            onPanelFullyOpened(fullyOpenedPanel);
134        } else if (fullyClosed && !mTracking && mState != STATE_CLOSED) {
135            go(STATE_CLOSED);
136            onAllPanelsCollapsed();
137        }
138
139        LOG("panelExpansionChanged: end state=%d [%s%s ]", mState,
140                (fullyOpenedPanel!=null)?" fullyOpened":"", fullyClosed?" fullyClosed":"");
141    }
142
143    public void collapseAllPanels(boolean animate) {
144        boolean waiting = false;
145        for (PanelView pv : mPanels) {
146            if (animate && !pv.isFullyCollapsed()) {
147                pv.collapse();
148                waiting = true;
149            } else {
150                pv.setExpandedFraction(0); // just in case
151            }
152            pv.setVisibility(View.GONE);
153        }
154        if (!waiting) {
155            // it's possible that nothing animated, so we replicate the termination
156            // conditions of panelExpansionChanged here
157            go(STATE_CLOSED);
158            onAllPanelsCollapsed();
159        }
160    }
161
162    public void onPanelPeeked() {
163        LOG("onPanelPeeked");
164    }
165
166    public void onAllPanelsCollapsed() {
167        LOG("onAllPanelsCollapsed");
168    }
169
170    public void onPanelFullyOpened(PanelView openPanel) {
171        LOG("onPanelFullyOpened");
172    }
173
174    public void onTrackingStarted(PanelView panel) {
175        mTracking = true;
176        if (panel != mTouchingPanel) {
177            LOG("shouldn't happen: onTrackingStarted(%s) != mTouchingPanel(%s)",
178                    panel, mTouchingPanel);
179        }
180    }
181
182    public void onTrackingStopped(PanelView panel) {
183        mTracking = false;
184        panelExpansionChanged(panel, panel.getExpandedFraction());
185    }
186}
187