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