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