summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOwen Lin <owenlin@google.com>2011-09-09 13:33:44 +0800
committerOwen Lin <owenlin@google.com>2011-09-14 14:34:56 +0800
commit8e565703e8d482421714383a8ad40a67929ce2da (patch)
tree4ad80e8db3d6886afa98249deceb0cc3107f6c16
parent3a54b9ae67eb7b38f19ea0bdeeef26efc0a1afa1 (diff)
downloadandroid_packages_apps_Gallery2-8e565703e8d482421714383a8ad40a67929ce2da.tar.gz
android_packages_apps_Gallery2-8e565703e8d482421714383a8ad40a67929ce2da.tar.bz2
android_packages_apps_Gallery2-8e565703e8d482421714383a8ad40a67929ce2da.zip
Use different UIs for phone's portrait mode in manage offline page.
fix: 5100503 The original UI design is not suitable for phone's portait mode. I move the UIs from GL view to android View to get better support. Change-Id: Ice5f536129f66b51cdaf4db1be750be7bc072c7f
-rw-r--r--res/drawable-hdpi/ic_manage_pin_small.pngbin0 -> 962 bytes
-rw-r--r--res/drawable-mdpi/ic_manage_pin_small.pngbin0 -> 615 bytes
-rw-r--r--res/layout-w480dp/manage_offline_bar.xml57
-rw-r--r--res/layout/main.xml21
-rw-r--r--res/layout/manage_offline_bar.xml62
-rw-r--r--src/com/android/gallery3d/app/AbstractGalleryActivity.java7
-rw-r--r--src/com/android/gallery3d/app/ActivityState.java4
-rw-r--r--src/com/android/gallery3d/app/ManageCachePage.java188
-rw-r--r--src/com/android/gallery3d/app/StateManager.java7
-rw-r--r--src/com/android/gallery3d/ui/CacheBarView.java270
-rw-r--r--src/com/android/gallery3d/ui/CacheStorageUsageInfo.java89
-rw-r--r--src/com/android/gallery3d/ui/Label.java84
-rw-r--r--src/com/android/gallery3d/ui/ProgressBar.java65
-rw-r--r--src/com/android/gallery3d/ui/TextButton.java91
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
new file mode 100644
index 000000000..d29bbd06e
--- /dev/null
+++ b/res/drawable-hdpi/ic_manage_pin_small.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_manage_pin_small.png b/res/drawable-mdpi/ic_manage_pin_small.png
new file mode 100644
index 000000000..c1163d5f2
--- /dev/null
+++ b/res/drawable-mdpi/ic_manage_pin_small.png
Binary files differ
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);
- }
-}