diff options
| author | Owen Lin <owenlin@google.com> | 2011-09-14 00:51:39 -0700 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-09-14 00:51:39 -0700 |
| commit | 3ff75bc0cc30d621a4c213364efcd62c1f8c5180 (patch) | |
| tree | 3b0e737f6bef9b54a8a89354d5c00138037cc53e | |
| parent | 2b40d7c0857117f6276886b9c67bca596886d88c (diff) | |
| parent | 8e565703e8d482421714383a8ad40a67929ce2da (diff) | |
| download | android_packages_apps_Gallery2-3ff75bc0cc30d621a4c213364efcd62c1f8c5180.tar.gz android_packages_apps_Gallery2-3ff75bc0cc30d621a4c213364efcd62c1f8c5180.tar.bz2 android_packages_apps_Gallery2-3ff75bc0cc30d621a4c213364efcd62c1f8c5180.zip | |
Merge "Use different UIs for phone's portrait mode in manage offline page."
| -rw-r--r-- | res/drawable-hdpi/ic_manage_pin_small.png | bin | 0 -> 962 bytes | |||
| -rw-r--r-- | res/drawable-mdpi/ic_manage_pin_small.png | bin | 0 -> 615 bytes | |||
| -rw-r--r-- | res/layout-w480dp/manage_offline_bar.xml | 57 | ||||
| -rw-r--r-- | res/layout/main.xml | 21 | ||||
| -rw-r--r-- | res/layout/manage_offline_bar.xml | 62 | ||||
| -rw-r--r-- | src/com/android/gallery3d/app/AbstractGalleryActivity.java | 7 | ||||
| -rw-r--r-- | src/com/android/gallery3d/app/ActivityState.java | 4 | ||||
| -rw-r--r-- | src/com/android/gallery3d/app/ManageCachePage.java | 188 | ||||
| -rw-r--r-- | src/com/android/gallery3d/app/StateManager.java | 7 | ||||
| -rw-r--r-- | src/com/android/gallery3d/ui/CacheBarView.java | 270 | ||||
| -rw-r--r-- | src/com/android/gallery3d/ui/CacheStorageUsageInfo.java | 89 | ||||
| -rw-r--r-- | src/com/android/gallery3d/ui/Label.java | 84 | ||||
| -rw-r--r-- | src/com/android/gallery3d/ui/ProgressBar.java | 65 | ||||
| -rw-r--r-- | src/com/android/gallery3d/ui/TextButton.java | 91 |
14 files changed, 391 insertions, 554 deletions
diff --git a/res/drawable-hdpi/ic_manage_pin_small.png b/res/drawable-hdpi/ic_manage_pin_small.png Binary files differnew file mode 100644 index 000000000..d29bbd06e --- /dev/null +++ b/res/drawable-hdpi/ic_manage_pin_small.png diff --git a/res/drawable-mdpi/ic_manage_pin_small.png b/res/drawable-mdpi/ic_manage_pin_small.png Binary files differnew file mode 100644 index 000000000..c1163d5f2 --- /dev/null +++ b/res/drawable-mdpi/ic_manage_pin_small.png diff --git a/res/layout-w480dp/manage_offline_bar.xml b/res/layout-w480dp/manage_offline_bar.xml new file mode 100644 index 000000000..d44ecf09f --- /dev/null +++ b/res/layout-w480dp/manage_offline_bar.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 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. +--> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:background="@drawable/manage_bar"> + <LinearLayout android:id="@+id/cache_bar" + android:gravity="center_vertical" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <TextView android:layout_width="wrap_content" + android:paddingLeft="2dp" + android:layout_height="wrap_content" + android:gravity="center_vertical|left" + android:drawablePadding="3dp" + android:text="@string/make_available_offline" + android:drawableLeft="@drawable/ic_manage_pin"/> + <ProgressBar android:id="@+id/progress" + style="?android:attr/progressBarStyleHorizontal" + android:max="100" + android:progress="30" + android:secondaryProgress="65" + android:layout_marginLeft="5dp" + android:layout_marginRight="5dp" + android:layout_weight="1" + android:layout_width="match_parent" + android:layout_height="10dp"/> + <TextView android:id="@+id/status" + android:paddingRight="2dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> + <View android:layout_width="2dp" + android:layout_height="match_parent" + android:background="@android:drawable/divider_horizontal_dark" /> + <Button android:id="@+id/done" + style="?android:attr/borderlessButtonStyle" + android:text="@string/done" + android:layout_weight="0" + android:layout_alignParentBottom="true" + android:layout_alignParentLeft="true" + android:layout_alignParentRight="true" + android:layout_width="wrap_content" + android:layout_height="match_parent"/> + </LinearLayout> +</FrameLayout> diff --git a/res/layout/main.xml b/res/layout/main.xml index d5188330e..b71ea502a 100644 --- a/res/layout/main.xml +++ b/res/layout/main.xml @@ -1,10 +1,21 @@ <?xml version="1.0" encoding="utf-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <com.android.gallery3d.ui.GLRootView - android:id="@+id/gl_root_view" - android:layout_width="match_parent" - android:layout_height="match_parent"/> -</LinearLayout> + android:id="@+id/gl_root_view" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_alignParentBottom="true" + android:layout_alignParentLeft="true" + android:layout_alignParentRight="true" + android:layout_alignParentTop="true"/> + <FrameLayout android:id="@+id/footer" + android:visibility="gone" + android:layout_alignParentBottom="true" + android:layout_alignParentLeft="true" + android:layout_alignParentRight="true" + android:layout_width="match_parent" + android:layout_height="wrap_content"/> +</RelativeLayout> diff --git a/res/layout/manage_offline_bar.xml b/res/layout/manage_offline_bar.xml new file mode 100644 index 000000000..b4bcec225 --- /dev/null +++ b/res/layout/manage_offline_bar.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 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. +--> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:background="@drawable/manage_bar"> + <LinearLayout android:id="@+id/cache_bar" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <LinearLayout android:orientation="vertical" + android:paddingLeft="10dp" + android:paddingRight="5dp" + android:paddingBottom="5dp" + android:paddingTop="5dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1"> + <TextView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="bottom" + android:drawablePadding="3dp" + android:text="@string/make_available_offline" + android:drawableRight="@drawable/ic_manage_pin_small"/> + <ProgressBar android:id="@+id/progress" + style="?android:attr/progressBarStyleHorizontal" + android:max="100" + android:progress="30" + android:secondaryProgress="65" + android:layout_marginTop="2dp" + android:layout_marginBottom="2dp" + android:layout_width="match_parent" + android:layout_height="3dp"/> + <TextView android:id="@+id/status" + android:layout_width="match_parent" + android:layout_height="wrap_content"/> + </LinearLayout> + <View android:layout_width="2dp" + android:layout_height="match_parent" + android:background="@android:drawable/divider_horizontal_dark" /> + <Button android:id="@+id/done" + style="?android:attr/borderlessButtonStyle" + android:text="@string/done" + android:layout_weight="0" + android:layout_alignParentBottom="true" + android:layout_alignParentLeft="true" + android:layout_alignParentRight="true" + android:layout_width="wrap_content" + android:layout_height="match_parent"/> + </LinearLayout> +</FrameLayout> diff --git a/src/com/android/gallery3d/app/AbstractGalleryActivity.java b/src/com/android/gallery3d/app/AbstractGalleryActivity.java index d0d7b0fad..0fde9ccf0 100644 --- a/src/com/android/gallery3d/app/AbstractGalleryActivity.java +++ b/src/com/android/gallery3d/app/AbstractGalleryActivity.java @@ -34,6 +34,7 @@ import android.content.DialogInterface.OnCancelListener; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.IntentFilter; +import android.content.res.Configuration; import android.os.Bundle; public class AbstractGalleryActivity extends Activity implements GalleryActivity { @@ -63,6 +64,12 @@ public class AbstractGalleryActivity extends Activity implements GalleryActivity } } + @Override + public void onConfigurationChanged(Configuration config) { + super.onConfigurationChanged(config); + mStateManager.onConfigurationChange(config); + } + public Context getAndroidContext() { return this; } diff --git a/src/com/android/gallery3d/app/ActivityState.java b/src/com/android/gallery3d/app/ActivityState.java index 9f90d7b3c..6a0c72c52 100644 --- a/src/com/android/gallery3d/app/ActivityState.java +++ b/src/com/android/gallery3d/app/ActivityState.java @@ -21,6 +21,7 @@ import com.android.gallery3d.ui.GLView; import android.app.ActionBar; import android.app.Activity; import android.content.Intent; +import android.content.res.Configuration; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; @@ -71,6 +72,9 @@ abstract public class ActivityState { mResult.resultData = data; } + protected void onConfigurationChanged(Configuration config) { + } + protected void onSaveState(Bundle outState) { } diff --git a/src/com/android/gallery3d/app/ManageCachePage.java b/src/com/android/gallery3d/app/ManageCachePage.java index d653786af..940f1be08 100644 --- a/src/com/android/gallery3d/app/ManageCachePage.java +++ b/src/com/android/gallery3d/app/ManageCachePage.java @@ -17,11 +17,12 @@ package com.android.gallery3d.app; import com.android.gallery3d.R; +import com.android.gallery3d.common.Utils; import com.android.gallery3d.data.MediaObject; import com.android.gallery3d.data.MediaSet; import com.android.gallery3d.data.Path; import com.android.gallery3d.ui.AlbumSetView; -import com.android.gallery3d.ui.CacheBarView; +import com.android.gallery3d.ui.CacheStorageUsageInfo; import com.android.gallery3d.ui.GLCanvas; import com.android.gallery3d.ui.GLView; import com.android.gallery3d.ui.ManageCacheDrawer; @@ -30,24 +31,41 @@ import com.android.gallery3d.ui.SelectionDrawer; import com.android.gallery3d.ui.SelectionManager; import com.android.gallery3d.ui.SlotView; import com.android.gallery3d.ui.StaticBackground; +import com.android.gallery3d.ui.SynchronizedHandler; +import com.android.gallery3d.util.Future; import com.android.gallery3d.util.GalleryUtils; +import com.android.gallery3d.util.ThreadPool.Job; +import com.android.gallery3d.util.ThreadPool.JobContext; -import android.app.ActionBar; import android.app.Activity; import android.content.Context; +import android.content.res.Configuration; import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.text.format.Formatter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.FrameLayout; +import android.widget.ProgressBar; +import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; public class ManageCachePage extends ActivityState implements - SelectionManager.SelectionListener, CacheBarView.Listener, - MenuExecutor.ProgressListener, EyePosition.EyePositionListener { + SelectionManager.SelectionListener, MenuExecutor.ProgressListener, + EyePosition.EyePositionListener, OnClickListener { public static final String KEY_MEDIA_PATH = "media-path"; + private static final String TAG = "ManageCachePage"; private static final float USER_DISTANCE_METER = 0.3f; private static final int DATA_CACHE_SIZE = 256; + private static final int MSG_REFRESH_STORAGE_INFO = 1; + private static final int MSG_REQUEST_LAYOUT = 2; + private static final int PROGRESS_BAR_MAX = 10000; private StaticBackground mStaticBackground; private AlbumSetView mAlbumSetView; @@ -59,8 +77,6 @@ public class ManageCachePage extends ActivityState implements private AlbumSetDataAdapter mAlbumSetDataAdapter; private float mUserDistance; // in pixel - private CacheBarView mCacheBar; - private EyePosition mEyePosition; // The eyes' position of the user, the origin is at the center of the @@ -70,6 +86,11 @@ public class ManageCachePage extends ActivityState implements private float mZ; private int mAlbumCountToMakeAvailableOffline; + private View mFooterContent; + private CacheStorageUsageInfo mCacheStorageInfo; + private Future<Void> mUpdateStorageInfo; + private Handler mHandler; + private boolean mLayoutReady = false; private GLView mRootPane = new GLView() { private float mMatrix[] = new float[16]; @@ -77,18 +98,29 @@ public class ManageCachePage extends ActivityState implements @Override protected void onLayout( boolean changed, int left, int top, int right, int bottom) { + // Hack: our layout depends on other components on the screen. + // We assume the other components will complete before we get a change + // to run a message in main thread. + if (!mLayoutReady) { + mHandler.sendEmptyMessage(MSG_REQUEST_LAYOUT); + return; + } + mLayoutReady = false; + mStaticBackground.layout(0, 0, right - left, bottom - top); mEyePosition.resetPosition(); - - Config.ManageCachePage config = Config.ManageCachePage.get((Context) mActivity); - - ActionBar actionBar = ((Activity) mActivity).getActionBar(); - int slotViewTop = GalleryActionBar.getHeight((Activity) mActivity); - int slotViewBottom = bottom - top - config.cacheBarHeight; + Activity activity = (Activity) mActivity; + int slotViewTop = GalleryActionBar.getHeight(activity); + int slotViewBottom = bottom - top; + + View cacheBar = activity.findViewById(R.id.cache_bar); + if (cacheBar != null) { + int location[] = {0, 0}; + cacheBar.getLocationOnScreen(location); + slotViewBottom = location[1]; + } mAlbumSetView.layout(0, slotViewTop, right - left, slotViewBottom); - mCacheBar.layout(0, bottom - top - config.cacheBarHeight, - right - left, bottom - top); } @Override @@ -139,11 +171,9 @@ public class ManageCachePage extends ActivityState implements } long sizeOfTarget = targetSet.getCacheSize(); - if (isFullyCached ^ isSelected) { - mCacheBar.increaseTargetCacheSize(-sizeOfTarget); - } else { - mCacheBar.increaseTargetCacheSize(sizeOfTarget); - } + mCacheStorageInfo.increaseTargetCacheSize( + (isFullyCached ^ isSelected) ? -sizeOfTarget : sizeOfTarget); + refreshCacheStorageInfo(); mSelectionManager.toggle(path); mAlbumSetView.invalidate(); @@ -151,31 +181,79 @@ public class ManageCachePage extends ActivityState implements @Override public void onCreate(Bundle data, Bundle restoreState) { - Log.v(TAG, "onCreate"); + mCacheStorageInfo = new CacheStorageUsageInfo(mActivity); initializeViews(); initializeData(data); mEyePosition = new EyePosition(mActivity.getAndroidContext(), this); + mHandler = new SynchronizedHandler(mActivity.getGLRoot()) { + @Override + public void handleMessage(Message message) { + switch (message.what) { + case MSG_REFRESH_STORAGE_INFO: + refreshCacheStorageInfo(); + break; + case MSG_REQUEST_LAYOUT: { + mLayoutReady = true; + removeMessages(MSG_REQUEST_LAYOUT); + mRootPane.requestLayout(); + break; + } + } + } + }; + } + + @Override + public void onConfigurationChanged(Configuration config) { + // We use different layout resources for different configs + initializeFooterViews(); + FrameLayout layout = (FrameLayout) ((Activity) mActivity).findViewById(R.id.footer); + if (layout.getVisibility() == View.VISIBLE) { + layout.removeAllViews(); + layout.addView(mFooterContent); + } } @Override public void onPause() { super.onPause(); - Log.v(TAG, "onPause"); mAlbumSetDataAdapter.pause(); mAlbumSetView.pause(); - mCacheBar.pause(); mEyePosition.pause(); + + if (mUpdateStorageInfo != null) { + mUpdateStorageInfo.cancel(); + mUpdateStorageInfo = null; + } + mHandler.removeMessages(MSG_REFRESH_STORAGE_INFO); + + FrameLayout layout = (FrameLayout) ((Activity) mActivity).findViewById(R.id.footer); + layout.removeAllViews(); + layout.setVisibility(View.INVISIBLE); } + private Job<Void> mUpdateStorageInfoJob = new Job<Void>() { + @Override + public Void run(JobContext jc) { + mCacheStorageInfo.loadStorageInfo(jc); + if (!jc.isCancelled()) { + mHandler.sendEmptyMessage(MSG_REFRESH_STORAGE_INFO); + } + return null; + } + }; + @Override public void onResume() { super.onResume(); - Log.v(TAG, "onResume"); setContentPane(mRootPane); mAlbumSetDataAdapter.resume(); mAlbumSetView.resume(); - mCacheBar.resume(); mEyePosition.resume(); + mUpdateStorageInfo = mActivity.getThreadPool().submit(mUpdateStorageInfoJob); + FrameLayout layout = (FrameLayout) ((Activity) mActivity).findViewById(R.id.footer); + layout.addView(mFooterContent); + layout.setVisibility(View.VISIBLE); } private void initializeData(Bundle data) { @@ -194,14 +272,16 @@ public class ManageCachePage extends ActivityState implements } private void initializeViews() { + Activity activity = (Activity) mActivity; + mSelectionManager = new SelectionManager(mActivity, true); mSelectionManager.setSelectionListener(this); - mStaticBackground = new StaticBackground(mActivity.getAndroidContext()); + mStaticBackground = new StaticBackground(activity); mRootPane.addComponent(mStaticBackground); mSelectionDrawer = new ManageCacheDrawer( (Context) mActivity, mSelectionManager); - Config.ManageCachePage config = Config.ManageCachePage.get((Context) mActivity); + Config.ManageCachePage config = Config.ManageCachePage.get(activity); mAlbumSetView = new AlbumSetView(mActivity, mSelectionDrawer, config.slotWidth, config.slotHeight, config.displayItemSize, config.labelFontSize, @@ -213,22 +293,25 @@ public class ManageCachePage extends ActivityState implements } }); mRootPane.addComponent(mAlbumSetView); + initializeFooterViews(); + } - mCacheBar = new CacheBarView(mActivity, R.drawable.manage_bar, - config.cacheBarHeight, - config.cacheBarPinLeftMargin, - config.cacheBarPinRightMargin, - config.cacheBarButtonRightMargin, - config.cacheBarFontSize); + private void initializeFooterViews() { + Activity activity = (Activity) mActivity; - mCacheBar.setListener(this); - mRootPane.addComponent(mCacheBar); + FrameLayout footer = (FrameLayout) activity.findViewById(R.id.footer); + LayoutInflater inflater = activity.getLayoutInflater(); + mFooterContent = inflater.inflate(R.layout.manage_offline_bar, null); - mStaticBackground.setImage(R.drawable.background, - R.drawable.background_portrait); + mFooterContent.findViewById(R.id.done).setOnClickListener(this); + mStaticBackground.setImage(R.drawable.background, R.drawable.background_portrait); + refreshCacheStorageInfo(); } - public void onDoneClicked() { + @Override + public void onClick(View view) { + Utils.assertTrue(view.getId() == R.id.done); + ArrayList<Path> ids = mSelectionManager.getSelected(false); if (ids.size() == 0) { onBackPressed(); @@ -236,8 +319,7 @@ public class ManageCachePage extends ActivityState implements } showToast(); - MenuExecutor menuExecutor = new MenuExecutor(mActivity, - mSelectionManager); + MenuExecutor menuExecutor = new MenuExecutor(mActivity, mSelectionManager); menuExecutor.startAction(R.id.action_toggle_full_caching, R.string.process_caching_requests, this); } @@ -259,6 +341,33 @@ public class ManageCachePage extends ActivityState implements Toast.LENGTH_SHORT).show(); } + private void refreshCacheStorageInfo() { + ProgressBar progressBar = (ProgressBar) mFooterContent.findViewById(R.id.progress); + TextView status = (TextView) mFooterContent.findViewById(R.id.status); + progressBar.setMax(PROGRESS_BAR_MAX); + long totalBytes = mCacheStorageInfo.getTotalBytes(); + long usedBytes = mCacheStorageInfo.getUsedBytes(); + long expectedBytes = mCacheStorageInfo.getExpectedUsedBytes(); + long freeBytes = mCacheStorageInfo.getFreeBytes(); + + Activity activity = (Activity) mActivity; + if (totalBytes == 0) { + progressBar.setProgress(0); + progressBar.setSecondaryProgress(0); + + // TODO: get the string translated + String label = activity.getString(R.string.free_space_format, "-"); + status.setText(label); + } else { + progressBar.setProgress((int) (usedBytes * PROGRESS_BAR_MAX / totalBytes)); + progressBar.setSecondaryProgress( + (int) (expectedBytes * PROGRESS_BAR_MAX / totalBytes)); + String label = activity.getString(R.string.free_space_format, + Formatter.formatFileSize(activity, freeBytes)); + status.setText(label); + } + } + public void onProgressComplete(int result) { onBackPressed(); } @@ -271,4 +380,5 @@ public class ManageCachePage extends ActivityState implements public void onSelectionChange(Path path, boolean selected) { } + } diff --git a/src/com/android/gallery3d/app/StateManager.java b/src/com/android/gallery3d/app/StateManager.java index caa6e7b58..9c55fbd15 100644 --- a/src/com/android/gallery3d/app/StateManager.java +++ b/src/com/android/gallery3d/app/StateManager.java @@ -20,6 +20,7 @@ import com.android.gallery3d.common.Utils; import android.app.Activity; import android.content.Intent; +import android.content.res.Configuration; import android.os.Bundle; import android.os.Parcelable; import android.view.Menu; @@ -106,6 +107,12 @@ public class StateManager { } } + public void onConfigurationChange(Configuration config) { + for (StateEntry entry : mStack) { + entry.activityState.onConfigurationChanged(config); + } + } + public void resume() { if (mIsResumed) return; mIsResumed = true; diff --git a/src/com/android/gallery3d/ui/CacheBarView.java b/src/com/android/gallery3d/ui/CacheBarView.java deleted file mode 100644 index 40f84d8f9..000000000 --- a/src/com/android/gallery3d/ui/CacheBarView.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (C) 2010 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.gallery3d.ui; - -import com.android.gallery3d.R; -import com.android.gallery3d.app.GalleryActivity; -import com.android.gallery3d.util.Future; -import com.android.gallery3d.util.FutureListener; -import com.android.gallery3d.util.ThreadPool.Job; -import com.android.gallery3d.util.ThreadPool.JobContext; - -import android.content.Context; -import android.graphics.Color; -import android.graphics.Rect; -import android.os.Handler; -import android.os.Message; -import android.os.StatFs; -import android.text.format.Formatter; -import android.view.View.MeasureSpec; - -import java.io.File; - -public class CacheBarView extends GLView implements TextButton.OnClickedListener { - private static final String TAG = "CacheBarView"; - private static final int FONT_COLOR = 0xffffffff; - private static final int MSG_REFRESH_STORAGE = 1; - private static final int PIN_SIZE = 36; - - public interface Listener { - void onDoneClicked(); - } - - private GalleryActivity mActivity; - private Context mContext; - - private StorageInfo mStorageInfo; - private long mUserChangeDelta; - private Future<StorageInfo> mStorageInfoFuture; - private Handler mHandler; - - private int mTotalHeight; - private int mPinLeftMargin; - private int mPinRightMargin; - private int mButtonRightMargin; - - private NinePatchTexture mBackground; - private GLView mLeftPin; // The pin icon. - private GLView mLeftLabel; // "Make available offline" - private ProgressBar mStorageBar; - private Label mStorageLabel; // "27.26 GB free" - private TextButton mDoneButton; // "Done" - - private Listener mListener; - - public CacheBarView(GalleryActivity activity, int resBackground, int height, - int pinLeftMargin, int pinRightMargin, int buttonRightMargin, - int fontSize) { - mActivity = activity; - mContext = activity.getAndroidContext(); - - mPinLeftMargin = pinLeftMargin; - mPinRightMargin = pinRightMargin; - mButtonRightMargin = buttonRightMargin; - - mBackground = new NinePatchTexture(mContext, resBackground); - Rect paddings = mBackground.getPaddings(); - - // The total height of the strip that includes the bar containing Pin, - // Label, DoneButton, ..., ect. and the extended fading bar. - mTotalHeight = height + paddings.top; - - mLeftPin = new Icon(mContext, R.drawable.ic_manage_pin, PIN_SIZE, PIN_SIZE); - mLeftLabel = new Label(mContext, R.string.make_available_offline, - fontSize, FONT_COLOR); - addComponent(mLeftPin); - addComponent(mLeftLabel); - - mDoneButton = new TextButton(mContext, R.string.done); - mDoneButton.setOnClickListener(this); - NinePatchTexture normal = new NinePatchTexture( - mContext, R.drawable.btn_default_normal_holo_dark); - NinePatchTexture pressed = new NinePatchTexture( - mContext, R.drawable.btn_default_pressed_holo_dark); - mDoneButton.setNormalBackground(normal); - mDoneButton.setPressedBackground(pressed); - addComponent(mDoneButton); - - // Initially the progress bar and label are invisible. - // It will be made visible after we have the storage information. - mStorageBar = new ProgressBar(mContext, - R.drawable.progress_primary_holo_dark, - R.drawable.progress_secondary_holo_dark, - R.drawable.progress_bg_holo_dark); - mStorageLabel = new Label(mContext, "", 14, Color.WHITE); - addComponent(mStorageBar); - addComponent(mStorageLabel); - mStorageBar.setVisibility(GLView.INVISIBLE); - mStorageLabel.setVisibility(GLView.INVISIBLE); - - mHandler = new SynchronizedHandler(activity.getGLRoot()) { - @Override - public void handleMessage(Message msg) { - switch(msg.what) { - case MSG_REFRESH_STORAGE: - mStorageInfo = (StorageInfo) msg.obj; - refreshStorageInfo(); - break; - } - } - }; - } - - public void setListener(Listener listener) { - mListener = listener; - } - - // Called by mDoneButton - public void onClicked(GLView source) { - if (mListener != null) { - mListener.onDoneClicked(); - } - } - - @Override - protected void onLayout( - boolean changed, int left, int top, int right, int bottom) { - // The size of mStorageLabel can change, so we need to layout - // even if the size of CacheBarView does not change. - int w = right - left; - int h = bottom - top; - - mLeftPin.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); - int pinH = mLeftPin.getMeasuredHeight(); - int pinW = mLeftPin.getMeasuredWidth(); - int pinT = (h - pinH) / 2; - int pinL = mPinLeftMargin; - mLeftPin.layout(pinL, pinT, pinL + pinW, pinT + pinH); - - mLeftLabel.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); - int labelH = mLeftLabel.getMeasuredHeight(); - int labelW = mLeftLabel.getMeasuredWidth(); - int labelT = (h - labelH) / 2; - int labelL = pinL + pinW + mPinRightMargin; - mLeftLabel.layout(labelL, labelT, labelL + labelW, labelT + labelH); - - mDoneButton.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); - int doneH = mDoneButton.getMeasuredHeight(); - int doneW = mDoneButton.getMeasuredWidth(); - int doneT = (h - doneH) / 2; - int doneR = w - mButtonRightMargin; - mDoneButton.layout(doneR - doneW, doneT, doneR, doneT + doneH); - - int centerX = w / 2; - int centerY = h / 2; - - int capBarH = 20; - int capBarW = 200; - int capBarT = centerY - capBarH / 2; - int capBarL = centerX - capBarW / 2; - mStorageBar.layout(capBarL, capBarT, capBarL + capBarW, - capBarT + capBarH); - - mStorageLabel.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); - int capLabelH = mStorageLabel.getMeasuredHeight(); - int capLabelW = mStorageLabel.getMeasuredWidth(); - int capLabelT = centerY - capLabelH / 2; - int capLabelL = centerX + capBarW / 2 + 8; - mStorageLabel.layout(capLabelL , capLabelT, capLabelL + capLabelW, - capLabelT + capLabelH); - } - - public void refreshStorageInfo() { - long used = mStorageInfo.usedBytes; - long total = mStorageInfo.totalBytes; - long cached = mStorageInfo.usedCacheBytes; - long target = mStorageInfo.targetCacheBytes; - - double primary = (double) used / total; - double secondary = - (double) (used - cached + target + mUserChangeDelta) / total; - - mStorageBar.setProgress((int) (primary * 10000)); - mStorageBar.setSecondaryProgress((int) (secondary * 10000)); - - long freeBytes = mStorageInfo.totalBytes - mStorageInfo.usedBytes; - String sizeString = Formatter.formatFileSize(mContext, freeBytes); - String label = mContext.getString(R.string.free_space_format, sizeString); - mStorageLabel.setText(label); - mStorageBar.setVisibility(GLView.VISIBLE); - mStorageLabel.setVisibility(GLView.VISIBLE); - requestLayout(); // because the size of the label may have changed. - } - - public void increaseTargetCacheSize(long delta) { - mUserChangeDelta += delta; - refreshStorageInfo(); - } - - @Override - protected void renderBackground(GLCanvas canvas) { - Rect paddings = mBackground.getPaddings(); - mBackground.draw(canvas, 0, -paddings.top, getWidth(), mTotalHeight); - } - - public void resume() { - mStorageInfoFuture = mActivity.getThreadPool().submit( - new StorageInfoJob(), - new FutureListener<StorageInfo>() { - public void onFutureDone(Future<StorageInfo> future) { - mStorageInfoFuture = null; - if (!future.isCancelled()) { - mHandler.sendMessage(mHandler.obtainMessage( - MSG_REFRESH_STORAGE, future.get())); - } - } - }); - } - - public void pause() { - if (mStorageInfoFuture != null) { - mStorageInfoFuture.cancel(); - mStorageInfoFuture = null; - } - mStorageBar.setVisibility(GLView.INVISIBLE); - mStorageLabel.setVisibility(GLView.INVISIBLE); - } - - public static class StorageInfo { - long totalBytes; // number of bytes the storage has. - long usedBytes; // number of bytes already used. - long usedCacheBytes; // number of bytes used for the cache (should be less - // then usedBytes). - long targetCacheBytes;// number of bytes used for the cache - // if all pending downloads (and removals) are completed. - } - - private class StorageInfoJob implements Job<StorageInfo> { - public StorageInfo run(JobContext jc) { - File cacheDir = mContext.getExternalCacheDir(); - if (cacheDir == null) { - cacheDir = mContext.getCacheDir(); - } - String path = cacheDir.getAbsolutePath(); - StatFs stat = new StatFs(path); - long blockSize = stat.getBlockSize(); - long availableBlocks = stat.getAvailableBlocks(); - long totalBlocks = stat.getBlockCount(); - StorageInfo si = new StorageInfo(); - si.totalBytes = blockSize * totalBlocks; - si.usedBytes = blockSize * (totalBlocks - availableBlocks); - si.usedCacheBytes = mActivity.getDataManager().getTotalUsedCacheSize(); - si.targetCacheBytes = mActivity.getDataManager().getTotalTargetCacheSize(); - return si; - } - } -} diff --git a/src/com/android/gallery3d/ui/CacheStorageUsageInfo.java b/src/com/android/gallery3d/ui/CacheStorageUsageInfo.java new file mode 100644 index 000000000..3c6e157ba --- /dev/null +++ b/src/com/android/gallery3d/ui/CacheStorageUsageInfo.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2010 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.gallery3d.ui; + +import com.android.gallery3d.app.GalleryActivity; +import com.android.gallery3d.util.ThreadPool.JobContext; + +import android.content.Context; +import android.os.StatFs; + +import java.io.File; + +public class CacheStorageUsageInfo { + private static final String TAG = "CacheStorageUsageInfo"; + + // number of bytes the storage has. + private long mTotalBytes; + + // number of bytes already used. + private long mUsedBytes; + + // number of bytes used for the cache (should be less then usedBytes). + private long mUsedCacheBytes; + + // number of bytes used for the cache if all pending downloads (and removals) are completed. + private long mTargetCacheBytes; + + private GalleryActivity mActivity; + private Context mContext; + private long mUserChangeDelta; + + public CacheStorageUsageInfo(GalleryActivity activity) { + mActivity = activity; + mContext = activity.getAndroidContext(); + } + + public void increaseTargetCacheSize(long delta) { + mUserChangeDelta += delta; + } + + public void loadStorageInfo(JobContext jc) { + File cacheDir = mContext.getExternalCacheDir(); + if (cacheDir == null) { + cacheDir = mContext.getCacheDir(); + } + + String path = cacheDir.getAbsolutePath(); + StatFs stat = new StatFs(path); + long blockSize = stat.getBlockSize(); + long availableBlocks = stat.getAvailableBlocks(); + long totalBlocks = stat.getBlockCount(); + + mTotalBytes = blockSize * totalBlocks; + mUsedBytes = blockSize * (totalBlocks - availableBlocks); + mUsedCacheBytes = mActivity.getDataManager().getTotalUsedCacheSize(); + mTargetCacheBytes = mActivity.getDataManager().getTotalTargetCacheSize(); + } + + public long getTotalBytes() { + return mTotalBytes; + } + + public long getExpectedUsedBytes() { + return mUsedBytes - mUsedCacheBytes + mTargetCacheBytes + mUserChangeDelta; + } + + public long getUsedBytes() { + // Should it be usedBytes - usedCacheBytes + targetCacheBytes ? + return mUsedBytes; + } + + public long getFreeBytes() { + return mTotalBytes - mUsedBytes; + } +} diff --git a/src/com/android/gallery3d/ui/Label.java b/src/com/android/gallery3d/ui/Label.java deleted file mode 100644 index 6a70a1895..000000000 --- a/src/com/android/gallery3d/ui/Label.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2010 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.gallery3d.ui; - -import android.content.Context; -import android.graphics.Color; -import android.graphics.Rect; - -public class Label extends GLView { - private static final String TAG = "Label"; - public static final int NULL_ID = 0; - - private static final int FONT_SIZE = 18; - private static final int FONT_COLOR = Color.WHITE; - - private String mText; - private StringTexture mTexture; - private int mFontSize, mFontColor; - - public Label(Context context, int stringId, - int fontSize, int fontColor) { - this(context, context.getString(stringId), fontSize, fontColor); - } - - public Label(Context context, int stringId) { - this(context, stringId, FONT_SIZE, FONT_COLOR); - } - - public Label(Context context, String text) { - this(context, text, FONT_SIZE, FONT_COLOR); - } - - public Label(Context context, String text, int fontSize, int fontColor) { - //TODO: cut the text if it is too long - mText = text; - mTexture = StringTexture.newInstance(text, fontSize, fontColor); - mFontSize = fontSize; - mFontColor = fontColor; - } - - public void setText(String text) { - if (!mText.equals(text)) { - mText = text; - mTexture = StringTexture.newInstance(text, mFontSize, mFontColor); - requestLayout(); - } - } - - @Override - protected void onMeasure(int widthSpec, int heightSpec) { - int width = mTexture.getWidth(); - int height = mTexture.getHeight(); - MeasureHelper.getInstance(this) - .setPreferredContentSize(width, height) - .measure(widthSpec, heightSpec); - } - - @Override - protected void render(GLCanvas canvas) { - Rect p = mPaddings; - - int width = getWidth() - p.left - p.right; - int height = getHeight() - p.top - p.bottom; - - int xoffset = p.left + (width - mTexture.getWidth()) / 2; - int yoffset = p.top + (height - mTexture.getHeight()) / 2; - - mTexture.draw(canvas, xoffset, yoffset); - } -} diff --git a/src/com/android/gallery3d/ui/ProgressBar.java b/src/com/android/gallery3d/ui/ProgressBar.java deleted file mode 100644 index c62fa9a62..000000000 --- a/src/com/android/gallery3d/ui/ProgressBar.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2010 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.gallery3d.ui; - -import android.content.Context; -import android.graphics.Rect; - -public class ProgressBar extends GLView { - private final int MAX_PROGRESS = 10000; - private int mProgress; - private int mSecondaryProgress; - private BasicTexture mProgressTexture; - private BasicTexture mSecondaryProgressTexture; - private BasicTexture mBackgrondTexture; - - - public ProgressBar(Context context, int resProgress, - int resSecondaryProgress, int resBackground) { - mProgressTexture = new NinePatchTexture(context, resProgress); - mSecondaryProgressTexture = new NinePatchTexture( - context, resSecondaryProgress); - mBackgrondTexture = new NinePatchTexture(context, resBackground); - - } - - // The progress value is between 0 (empty) and MAX_PROGRESS (full). - public void setProgress(int progress) { - mProgress = progress; - } - - public void setSecondaryProgress(int progress) { - mSecondaryProgress = progress; - } - - @Override - protected void render(GLCanvas canvas) { - Rect p = mPaddings; - - int width = getWidth() - p.left - p.right; - int height = getHeight() - p.top - p.bottom; - - int primary = width * mProgress / MAX_PROGRESS; - int secondary = width * mSecondaryProgress / MAX_PROGRESS; - int x = p.left; - int y = p.top; - - canvas.drawTexture(mBackgrondTexture, x, y, width, height); - canvas.drawTexture(mProgressTexture, x, y, primary, height); - canvas.drawTexture(mSecondaryProgressTexture, x, y, secondary, height); - } -} diff --git a/src/com/android/gallery3d/ui/TextButton.java b/src/com/android/gallery3d/ui/TextButton.java deleted file mode 100644 index c6b85bf55..000000000 --- a/src/com/android/gallery3d/ui/TextButton.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2010 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.gallery3d.ui; - -import static com.android.gallery3d.ui.TextButtonConfig.*; - -import android.content.Context; -import android.graphics.Rect; -import android.view.MotionEvent; - -public class TextButton extends Label { - private static final String TAG = "TextButton"; - private boolean mPressed; - private Texture mPressedBackground; - private Texture mNormalBackground; - private OnClickedListener mOnClickListener; - - public interface OnClickedListener { - public void onClicked(GLView source); - } - - public TextButton(Context context, int label) { - super(context, label); - setPaddings(HORIZONTAL_PADDINGS, VERTICAL_PADDINGS, - HORIZONTAL_PADDINGS, VERTICAL_PADDINGS); - } - - public void setOnClickListener(OnClickedListener listener) { - mOnClickListener = listener; - } - - public void setPressedBackground(Texture texture) { - mPressedBackground = texture; - } - - public void setNormalBackground(Texture texture) { - mNormalBackground = texture; - } - - @SuppressWarnings("fallthrough") - @Override - protected boolean onTouch(MotionEvent event) { - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - mPressed = true; - invalidate(); - break; - case MotionEvent.ACTION_UP: - if (mOnClickListener != null) { - mOnClickListener.onClicked(this); - } - // fall-through - case MotionEvent.ACTION_CANCEL: - mPressed = false; - invalidate(); - break; - } - return true; - } - - @Override - protected void render(GLCanvas canvas) { - Texture bg = mPressed ? mPressedBackground : mNormalBackground; - if (bg != null) { - int width = getWidth(); - int height = getHeight(); - if (bg instanceof NinePatchTexture) { - Rect p = ((NinePatchTexture) bg).getPaddings(); - bg.draw(canvas, -p.left, -p.top, - width + p.left + p.right, height + p.top + p.bottom); - } else { - bg.draw(canvas, 0, 0, width, height); - } - } - super.render(canvas); - } -} |
