mobile/android/base/toolbar/ToolbarProgressView.java

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /*
     2  * Copyright (C) 2010 The Android Open Source Project
     3  *
     4  * Licensed under the Apache License, Version 2.0 (the "License");
     5  * you may not use this file except in compliance with the License.
     6  * You may obtain a copy of the License at
     7  *
     8  *      http://www.apache.org/licenses/LICENSE-2.0
     9  *
    10  * Unless required by applicable law or agreed to in writing, software
    11  * distributed under the License is distributed on an "AS IS" BASIS,
    12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  * See the License for the specific language governing permissions and
    14  * limitations under the License.
    15  */
    17 package org.mozilla.gecko.toolbar;
    19 import android.content.Context;
    20 import android.graphics.Canvas;
    21 import android.graphics.Rect;
    22 import android.graphics.drawable.Drawable;
    23 import android.os.Build;
    24 import android.os.Handler;
    25 import android.os.Message;
    26 import android.util.AttributeSet;
    27 import android.widget.ImageView;
    28 import android.view.View;
    29 import android.view.animation.Animation;
    31 /**
    32  * Progress view used for page loads.
    33  *
    34  * Because we're given limited information about the page load progress, the
    35  * bar also includes incremental animation between each step to improve
    36  * perceived performance.
    37  */
    38 public class ToolbarProgressView extends ImageView {
    39     private static final int MAX_PROGRESS = 10000;
    40     private static final int MSG_UPDATE = 0;
    41     private static final int MSG_HIDE = 1;
    42     private static final int STEPS = 10;
    43     private static final int DELAY = 40;
    45     private static final boolean PRE_HONEYCOMB = Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB;
    47     private int mTargetProgress;
    48     private int mIncrement;
    49     private Rect mBounds;
    50     private Handler mHandler;
    51     private int mCurrentProgress;
    53     public ToolbarProgressView(Context context, AttributeSet attrs, int defStyle) {
    54         super(context, attrs, defStyle);
    55         init(context);
    56     }
    58     public ToolbarProgressView(Context context, AttributeSet attrs) {
    59         super(context, attrs);
    60         init(context);
    61     }
    63     public ToolbarProgressView(Context context) {
    64         super(context);
    65         init(context);
    66     }
    68     private void init(Context ctx) {
    69         mBounds = new Rect(0,0,0,0);
    70         mTargetProgress = 0;
    72         mHandler = new Handler() {
    73             @Override
    74             public void handleMessage(Message msg) {
    75                 switch (msg.what) {
    76                     case MSG_UPDATE:
    77                         mCurrentProgress = Math.min(mTargetProgress, mCurrentProgress + mIncrement);
    79                         updateBounds();
    81                         if (mCurrentProgress < mTargetProgress) {
    82                             final int delay = (mTargetProgress < MAX_PROGRESS) ? DELAY : DELAY / 4;
    83                             sendMessageDelayed(mHandler.obtainMessage(msg.what), delay);
    84                         } else if (mCurrentProgress == MAX_PROGRESS) {
    85                             sendMessageDelayed(mHandler.obtainMessage(MSG_HIDE), DELAY);
    86                         }
    87                         break;
    89                     case MSG_HIDE:
    90                         setVisibility(View.GONE);
    91                         break;
    92                 }
    93             }
    95         };
    96     }
    98     @Override
    99     public void setVisibility(int visibility) {
   100         // On GB/Froyo, setting the visibility to GONE/HIDDEN alone does not
   101         // work with translations. Calling clearAnimation acts as a workaround.
   102         if (PRE_HONEYCOMB && visibility != VISIBLE) {
   103             clearAnimation();
   104         }
   106         super.setVisibility(visibility);
   107     }
   109     @Override
   110     public void setAnimation(Animation animation) {
   111         // On GB/Froyo, setting the animation after hiding the view causes it
   112         // to reappear. As a workaround, disallow setAnimation from being
   113         // called if the view is not shown.
   114         if (PRE_HONEYCOMB && isShown()) {
   115             super.setAnimation(animation);
   116         }
   117     }
   119     @Override
   120     public void onLayout(boolean f, int l, int t, int r, int b) {
   121         mBounds.left = 0;
   122         mBounds.right = (r - l) * mCurrentProgress / MAX_PROGRESS;
   123         mBounds.top = 0;
   124         mBounds.bottom = b - t;
   125     }
   127     @Override
   128     public void onDraw(Canvas canvas) {
   129         final Drawable d = getDrawable();
   130         d.setBounds(mBounds);
   131         d.draw(canvas);
   132     }
   134     /**
   135      * Immediately sets the progress bar to the given progress percentage.
   136      *
   137      * @param progress Percentage (0-100) to which progress bar should be set
   138      */
   139     void setProgress(int progressPercentage) {
   140         mCurrentProgress = mTargetProgress = getAbsoluteProgress(progressPercentage);
   141         updateBounds();
   143         clearMessages();
   144     }
   146     /**
   147      * Animates the progress bar from the current progress value to the given
   148      * progress percentage.
   149      *
   150      * @param progress Percentage (0-100) to which progress bar should be animated
   151      */
   152     void animateProgress(int progressPercentage) {
   153         final int absoluteProgress = getAbsoluteProgress(progressPercentage);
   154         if (absoluteProgress <= mTargetProgress) {
   155             // After we manually click stop, we can still receive page load
   156             // events (e.g., DOMContentLoaded). Updating for other updates
   157             // after a STOP event can freeze the progress bar, so guard against
   158             // that here.
   159             return;
   160         }
   162         mTargetProgress = absoluteProgress;
   163         mIncrement = (mTargetProgress - mCurrentProgress) / STEPS;
   165         clearMessages();
   166         mHandler.sendEmptyMessage(MSG_UPDATE);
   167     }
   169     private void clearMessages() {
   170         mHandler.removeMessages(MSG_UPDATE);
   171         mHandler.removeMessages(MSG_HIDE);
   172     }
   174     private int getAbsoluteProgress(int progressPercentage) {
   175         if (progressPercentage < 0) {
   176             return 0;
   177         }
   179         if (progressPercentage > 100) {
   180             return 100;
   181         }
   183         return progressPercentage * MAX_PROGRESS / 100;
   184     }
   186     private void updateBounds() {
   187         mBounds.right = getWidth() * mCurrentProgress / MAX_PROGRESS;
   188         invalidate();
   189     }
   190 }

mercurial