| /* |
| * Copyright (C) 2008 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.systemui.statusbar; |
| |
| import android.content.Context; |
| import android.content.res.Configuration; |
| import android.graphics.Canvas; |
| import android.graphics.Rect; |
| import android.os.SystemClock; |
| import android.util.AttributeSet; |
| import android.view.MotionEvent; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.view.ViewParent; |
| import android.widget.FrameLayout; |
| |
| import com.android.systemui.R; |
| |
| public class StatusBarView extends FrameLayout { |
| private static final String TAG = "StatusBarView"; |
| |
| static final int DIM_ANIM_TIME = 400; |
| |
| PhoneStatusBarService mService; |
| boolean mTracking; |
| int mStartX, mStartY; |
| ViewGroup mNotificationIcons; |
| ViewGroup mStatusIcons; |
| View mDate; |
| FixedSizeDrawable mBackground; |
| |
| boolean mNightMode = false; |
| int mStartAlpha = 0, mEndAlpha = 0; |
| long mEndTime = 0; |
| |
| Rect mButtonBounds = new Rect(); |
| boolean mCapturingEvents = true; |
| |
| public StatusBarView(Context context, AttributeSet attrs) { |
| super(context, attrs); |
| } |
| |
| @Override |
| protected void onFinishInflate() { |
| super.onFinishInflate(); |
| mNotificationIcons = (ViewGroup)findViewById(R.id.notificationIcons); |
| mStatusIcons = (ViewGroup)findViewById(R.id.statusIcons); |
| mDate = findViewById(R.id.date); |
| |
| mBackground = new FixedSizeDrawable(mDate.getBackground()); |
| mBackground.setFixedBounds(0, 0, 0, 0); |
| mDate.setBackgroundDrawable(mBackground); |
| } |
| |
| @Override |
| protected void onAttachedToWindow() { |
| super.onAttachedToWindow(); |
| mService.onBarViewAttached(); |
| } |
| |
| @Override |
| protected void onConfigurationChanged(Configuration newConfig) { |
| super.onConfigurationChanged(newConfig); |
| boolean nightMode = (newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK) |
| == Configuration.UI_MODE_NIGHT_YES; |
| if (mNightMode != nightMode) { |
| mNightMode = nightMode; |
| mStartAlpha = getCurAlpha(); |
| mEndAlpha = mNightMode ? 0x80 : 0x00; |
| mEndTime = SystemClock.uptimeMillis() + DIM_ANIM_TIME; |
| invalidate(); |
| } |
| } |
| |
| int getCurAlpha() { |
| long time = SystemClock.uptimeMillis(); |
| if (time > mEndTime) { |
| return mEndAlpha; |
| } |
| return mEndAlpha |
| - (int)(((mEndAlpha-mStartAlpha) * (mEndTime-time) / DIM_ANIM_TIME)); |
| } |
| |
| @Override |
| protected void onSizeChanged(int w, int h, int oldw, int oldh) { |
| super.onSizeChanged(w, h, oldw, oldh); |
| mService.updateExpandedViewPos(PhoneStatusBarService.EXPANDED_LEAVE_ALONE); |
| } |
| |
| @Override |
| protected void onLayout(boolean changed, int l, int t, int r, int b) { |
| super.onLayout(changed, l, t, r, b); |
| |
| // put the date date view quantized to the icons |
| int oldDateRight = mDate.getRight(); |
| int newDateRight; |
| |
| newDateRight = getDateSize(mNotificationIcons, oldDateRight, |
| getViewOffset(mNotificationIcons)); |
| if (newDateRight < 0) { |
| int offset = getViewOffset(mStatusIcons); |
| if (oldDateRight < offset) { |
| newDateRight = oldDateRight; |
| } else { |
| newDateRight = getDateSize(mStatusIcons, oldDateRight, offset); |
| if (newDateRight < 0) { |
| newDateRight = r; |
| } |
| } |
| } |
| int max = r - getPaddingRight(); |
| if (newDateRight > max) { |
| newDateRight = max; |
| } |
| |
| mDate.layout(mDate.getLeft(), mDate.getTop(), newDateRight, mDate.getBottom()); |
| mBackground.setFixedBounds(-mDate.getLeft(), -mDate.getTop(), (r-l), (b-t)); |
| } |
| |
| @Override |
| protected void dispatchDraw(Canvas canvas) { |
| super.dispatchDraw(canvas); |
| int alpha = getCurAlpha(); |
| if (alpha != 0) { |
| canvas.drawARGB(alpha, 0, 0, 0); |
| } |
| if (alpha != mEndAlpha) { |
| invalidate(); |
| } |
| } |
| |
| /** |
| * Gets the left position of v in this view. Throws if v is not |
| * a child of this. |
| */ |
| private int getViewOffset(View v) { |
| int offset = 0; |
| while (v != this) { |
| offset += v.getLeft(); |
| ViewParent p = v.getParent(); |
| if (v instanceof View) { |
| v = (View)p; |
| } else { |
| throw new RuntimeException(v + " is not a child of " + this); |
| } |
| } |
| return offset; |
| } |
| |
| private int getDateSize(ViewGroup g, int w, int offset) { |
| final int N = g.getChildCount(); |
| for (int i=0; i<N; i++) { |
| View v = g.getChildAt(i); |
| int l = v.getLeft() + offset; |
| int r = v.getRight() + offset; |
| if (w >= l && w <= r) { |
| return r; |
| } |
| } |
| return -1; |
| } |
| |
| /** |
| * Ensure that, if there is no target under us to receive the touch, |
| * that we process it ourself. This makes sure that onInterceptTouchEvent() |
| * is always called for the entire gesture. |
| */ |
| @Override |
| public boolean onTouchEvent(MotionEvent event) { |
| if (!mCapturingEvents) { |
| return false; |
| } |
| if (event.getAction() != MotionEvent.ACTION_DOWN) { |
| mService.interceptTouchEvent(event); |
| } |
| return true; |
| } |
| |
| @Override |
| public boolean onInterceptTouchEvent(MotionEvent event) { |
| if (event.getAction() == MotionEvent.ACTION_DOWN) { |
| if (mButtonBounds.contains((int)event.getX(), (int)event.getY())) { |
| mCapturingEvents = false; |
| return false; |
| } |
| } |
| mCapturingEvents = true; |
| return mService.interceptTouchEvent(event) |
| ? true : super.onInterceptTouchEvent(event); |
| } |
| } |
| |