summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/ui
diff options
context:
space:
mode:
authorRay Chen <raychen@google.com>2011-08-24 11:40:04 +0800
committerRay Chen <raychen@google.com>2011-08-26 20:20:48 +0800
commit327eeb846fa6b2649db90fc4e5708f7fdcbbfaa2 (patch)
tree36c467e95a6ccd0d704fb073310c7fbac0fb2721 /src/com/android/gallery3d/ui
parentca69a7dd02057818b7d3d61979561958d6109758 (diff)
downloadandroid_packages_apps_Snap-327eeb846fa6b2649db90fc4e5708f7fdcbbfaa2.tar.gz
android_packages_apps_Snap-327eeb846fa6b2649db90fc4e5708f7fdcbbfaa2.tar.bz2
android_packages_apps_Snap-327eeb846fa6b2649db90fc4e5708f7fdcbbfaa2.zip
Fix 5133608 [UI] Details should be displayed as a system dialog in phone UI
Fix 5132798 [UI] Details popup on tablet is incorrectly placed and should not have x icon to close Fix 5199822 Long press and select "detail" shows details of another item Change-Id: I0e992ded8a154edb1c7a81b75d0461d5bf309f31
Diffstat (limited to 'src/com/android/gallery3d/ui')
-rw-r--r--src/com/android/gallery3d/ui/DetailsAddressResolver.java116
-rw-r--r--src/com/android/gallery3d/ui/DetailsHelper.java144
-rw-r--r--src/com/android/gallery3d/ui/DialogDetailsView.java239
-rw-r--r--src/com/android/gallery3d/ui/GLDetailsView.java (renamed from src/com/android/gallery3d/ui/DetailsWindow.java)195
-rw-r--r--src/com/android/gallery3d/ui/ScrollView.java12
5 files changed, 545 insertions, 161 deletions
diff --git a/src/com/android/gallery3d/ui/DetailsAddressResolver.java b/src/com/android/gallery3d/ui/DetailsAddressResolver.java
new file mode 100644
index 000000000..fdf94ba09
--- /dev/null
+++ b/src/com/android/gallery3d/ui/DetailsAddressResolver.java
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.app.GalleryActivity;
+import com.android.gallery3d.data.MediaDetails;
+import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.FutureListener;
+import com.android.gallery3d.util.GalleryUtils;
+import com.android.gallery3d.util.ReverseGeocoder;
+import com.android.gallery3d.util.ThreadPool.Job;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+import android.content.Context;
+import android.location.Address;
+import android.os.Handler;
+import android.os.Looper;
+
+public class DetailsAddressResolver {
+ private AddressResolvingListener mListener;
+ private double[] mLatlng;
+ private GalleryActivity mContext;
+ private Future<Address> mAddressLookupJob;
+ private Handler mHandler;
+
+ private class AddressLookupJob implements Job<Address> {
+
+ protected AddressLookupJob(double[] latlng) {
+ mLatlng = latlng;
+ }
+
+ public Address run(JobContext jc) {
+ ReverseGeocoder geocoder = new ReverseGeocoder(mContext.getAndroidContext());
+ return geocoder.lookupAddress(mLatlng[0], mLatlng[1], true);
+ }
+ }
+
+ public interface AddressResolvingListener {
+ public void onAddressAvailable(String address);
+ }
+
+ public DetailsAddressResolver(GalleryActivity context) {
+ mContext = context;
+ mHandler = new Handler(Looper.getMainLooper());
+ }
+
+ public String resolveAddress(double[] latlng, AddressResolvingListener listener) {
+ mLatlng = latlng;
+ mListener = listener;
+ mAddressLookupJob = mContext.getThreadPool().submit(
+ new AddressLookupJob(latlng),
+ new FutureListener<Address>() {
+ public void onFutureDone(final Future<Address> future) {
+ mAddressLookupJob = null;
+ if (!future.isCancelled()) {
+ mHandler.post(new Runnable() {
+ public void run() {
+ updateLocation(future.get());
+ }
+ });
+ }
+ }
+ });
+ return GalleryUtils.formatLatitudeLongitude("(%f,%f)", mLatlng[0], mLatlng[1]);
+ }
+
+ private void updateLocation(Address address) {
+ if (address != null) {
+ Context context = mContext.getAndroidContext();
+ String parts[] = {
+ address.getAdminArea(),
+ address.getSubAdminArea(),
+ address.getLocality(),
+ address.getSubLocality(),
+ address.getThoroughfare(),
+ address.getSubThoroughfare(),
+ address.getPremises(),
+ address.getPostalCode(),
+ address.getCountryName()
+ };
+
+ String addressText = "";
+ for (int i = 0; i < parts.length; i++) {
+ if (parts[i] == null || parts[i].isEmpty()) continue;
+ if (!addressText.isEmpty()) {
+ addressText += ", ";
+ }
+ addressText += parts[i];
+ }
+ String text = String.format("%s : %s", DetailsHelper.getDetailsName(
+ context, MediaDetails.INDEX_LOCATION), addressText);
+ mListener.onAddressAvailable(text);
+ }
+ }
+
+ public void cancel() {
+ if (mAddressLookupJob != null) {
+ mAddressLookupJob.cancel();
+ mAddressLookupJob = null;
+ }
+ }
+}
diff --git a/src/com/android/gallery3d/ui/DetailsHelper.java b/src/com/android/gallery3d/ui/DetailsHelper.java
new file mode 100644
index 000000000..0ff01e6f3
--- /dev/null
+++ b/src/com/android/gallery3d/ui/DetailsHelper.java
@@ -0,0 +1,144 @@
+/*
+ * 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.data.MediaDetails;
+import com.android.gallery3d.ui.DetailsAddressResolver.AddressResolvingListener;
+
+import android.content.Context;
+import android.view.View.MeasureSpec;
+
+public class DetailsHelper {
+ private static DetailsAddressResolver sAddressResolver;
+ private DetailsViewContainer mContainer;
+
+ public interface DetailsSource {
+ public int size();
+ public int getIndex();
+ public int findIndex(int indexHint);
+ public MediaDetails getDetails();
+ }
+
+ public interface CloseListener {
+ public void onClose();
+ }
+
+ public interface DetailsViewContainer {
+ public void reloadDetails(int indexHint);
+ public void setCloseListener(CloseListener listener);
+ public void show();
+ public void hide();
+ }
+
+ public DetailsHelper(GalleryActivity activity, GLView rootPane, DetailsSource source) {
+ boolean useDialog = activity.getAndroidContext().getResources().getBoolean(
+ R.bool.dialog_details_view);
+ if (useDialog) {
+ mContainer = new DialogDetailsView(activity, source);
+ } else {
+ mContainer = new GLDetailsView(activity, source);
+ rootPane.addComponent((GLView) mContainer);
+ }
+ }
+
+ public void layout(int left, int top, int right, int bottom) {
+ if (mContainer instanceof GLView) {
+ GLView view = (GLView) mContainer;
+ view.measure(MeasureSpec.UNSPECIFIED,
+ MeasureSpec.makeMeasureSpec(bottom - top, MeasureSpec.AT_MOST));
+ view.layout(0, top, view.getMeasuredWidth(), top + view.getMeasuredHeight());
+ }
+ }
+
+ public void reloadDetails(int indexHint) {
+ mContainer.reloadDetails(indexHint);
+ }
+
+ public void setCloseListener(CloseListener listener) {
+ mContainer.setCloseListener(listener);
+ }
+
+ public static String resolveAddress(GalleryActivity activity, double[] latlng,
+ AddressResolvingListener listener) {
+ if (sAddressResolver == null) {
+ sAddressResolver = new DetailsAddressResolver(activity);
+ } else {
+ sAddressResolver.cancel();
+ }
+ return sAddressResolver.resolveAddress(latlng, listener);
+ }
+
+ public static void pause() {
+ if (sAddressResolver != null) sAddressResolver.cancel();
+ }
+
+ public void show() {
+ mContainer.show();
+ }
+
+ public void hide() {
+ mContainer.hide();
+ }
+
+ public static String getDetailsName(Context context, int key) {
+ switch (key) {
+ case MediaDetails.INDEX_TITLE:
+ return context.getString(R.string.title);
+ case MediaDetails.INDEX_DESCRIPTION:
+ return context.getString(R.string.description);
+ case MediaDetails.INDEX_DATETIME:
+ return context.getString(R.string.time);
+ case MediaDetails.INDEX_LOCATION:
+ return context.getString(R.string.location);
+ case MediaDetails.INDEX_PATH:
+ return context.getString(R.string.path);
+ case MediaDetails.INDEX_WIDTH:
+ return context.getString(R.string.width);
+ case MediaDetails.INDEX_HEIGHT:
+ return context.getString(R.string.height);
+ case MediaDetails.INDEX_ORIENTATION:
+ return context.getString(R.string.orientation);
+ case MediaDetails.INDEX_DURATION:
+ return context.getString(R.string.duration);
+ case MediaDetails.INDEX_MIMETYPE:
+ return context.getString(R.string.mimetype);
+ case MediaDetails.INDEX_SIZE:
+ return context.getString(R.string.file_size);
+ case MediaDetails.INDEX_MAKE:
+ return context.getString(R.string.maker);
+ case MediaDetails.INDEX_MODEL:
+ return context.getString(R.string.model);
+ case MediaDetails.INDEX_FLASH:
+ return context.getString(R.string.flash);
+ case MediaDetails.INDEX_APERTURE:
+ return context.getString(R.string.aperture);
+ case MediaDetails.INDEX_FOCAL_LENGTH:
+ return context.getString(R.string.focal_length);
+ case MediaDetails.INDEX_WHITE_BALANCE:
+ return context.getString(R.string.white_balance);
+ case MediaDetails.INDEX_EXPOSURE_TIME:
+ return context.getString(R.string.exposure_time);
+ case MediaDetails.INDEX_ISO:
+ return context.getString(R.string.iso);
+ default:
+ return "Unknown key" + key;
+ }
+ }
+}
+
+
diff --git a/src/com/android/gallery3d/ui/DialogDetailsView.java b/src/com/android/gallery3d/ui/DialogDetailsView.java
new file mode 100644
index 000000000..030bc34e8
--- /dev/null
+++ b/src/com/android/gallery3d/ui/DialogDetailsView.java
@@ -0,0 +1,239 @@
+/*
+ * 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.
+ */
+
+package com.android.gallery3d.ui;
+
+import static com.android.gallery3d.ui.DetailsWindowConfig.FONT_SIZE;
+import static com.android.gallery3d.ui.DetailsWindowConfig.LEFT_RIGHT_EXTRA_PADDING;
+import static com.android.gallery3d.ui.DetailsWindowConfig.LINE_SPACING;
+import static com.android.gallery3d.ui.DetailsWindowConfig.PREFERRED_WIDTH;
+import static com.android.gallery3d.ui.DetailsWindowConfig.TOP_BOTTOM_EXTRA_PADDING;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.app.GalleryActivity;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.MediaDetails;
+import com.android.gallery3d.ui.DetailsAddressResolver.AddressResolvingListener;
+import com.android.gallery3d.ui.DetailsHelper.CloseListener;
+import com.android.gallery3d.ui.DetailsHelper.DetailsViewContainer;
+import com.android.gallery3d.ui.DetailsHelper.DetailsSource;
+import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.FutureListener;
+import com.android.gallery3d.util.GalleryUtils;
+import com.android.gallery3d.util.ReverseGeocoder;
+import com.android.gallery3d.util.ThreadPool.Job;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.database.DataSetObserver;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.location.Address;
+import android.os.Handler;
+import android.os.Message;
+import android.text.format.Formatter;
+import android.view.ContextThemeWrapper;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.MeasureSpec;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.Map.Entry;
+
+public class DialogDetailsView implements DetailsViewContainer {
+ @SuppressWarnings("unused")
+ private static final String TAG = "DialogDetailsView";
+
+ private GalleryActivity mContext;
+ private DetailsAdapter mAdapter;
+ private MediaDetails mDetails;
+ private DetailsSource mSource;
+ private int mIndex;
+ private Dialog mDialog;
+ private int mLocationIndex;
+
+ public DialogDetailsView(GalleryActivity activity, DetailsSource source) {
+ mContext = activity;
+ mSource = source;
+ }
+
+ public void show() {
+ reloadDetails(mSource.getIndex());
+ mDialog.show();
+ }
+
+ public void hide() {
+ mDialog.hide();
+ }
+
+ public void reloadDetails(int indexHint) {
+ int index = mSource.findIndex(indexHint);
+ if (index == -1) return;
+ MediaDetails details = mSource.getDetails();
+ if (details != null) {
+ if (mIndex == index && mDetails == details) return;
+ mIndex = index;
+ mDetails = details;
+ setDetails(details);
+ }
+ }
+
+ public boolean isVisible() {
+ return mDialog.isShowing();
+ }
+
+ private void setDetails(MediaDetails details) {
+ mAdapter = new DetailsAdapter(details);
+ String title = String.format(
+ mContext.getAndroidContext().getString(R.string.details_title),
+ mIndex + 1, mSource.size());
+ mDialog = new AlertDialog.Builder((Activity) mContext)
+ .setAdapter(mAdapter, null)
+ .setTitle(title)
+ .setPositiveButton(R.string.close, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ mDialog.dismiss();
+ }
+ })
+ .create();
+ }
+
+ private class DetailsAdapter extends BaseAdapter implements AddressResolvingListener {
+ private ArrayList<String> mItems;
+
+ public DetailsAdapter(MediaDetails details) {
+ Context context = mContext.getAndroidContext();
+ mItems = new ArrayList<String>(details.size());
+ mLocationIndex = -1;
+ setDetails(context, details);
+ }
+
+ private void setDetails(Context context, MediaDetails details) {
+ for (Entry<Integer, Object> detail : details) {
+ String value;
+ switch (detail.getKey()) {
+ case MediaDetails.INDEX_LOCATION: {
+ double[] latlng = (double[]) detail.getValue();
+ mLocationIndex = mItems.size();
+ value = DetailsHelper.resolveAddress(mContext, latlng, mAdapter);
+ break;
+ }
+ case MediaDetails.INDEX_SIZE: {
+ value = Formatter.formatFileSize(
+ context, (Long) detail.getValue());
+ break;
+ }
+ case MediaDetails.INDEX_WHITE_BALANCE: {
+ value = "1".equals(detail.getValue())
+ ? context.getString(R.string.manual)
+ : context.getString(R.string.auto);
+ break;
+ }
+ case MediaDetails.INDEX_FLASH: {
+ MediaDetails.FlashState flash =
+ (MediaDetails.FlashState) detail.getValue();
+ // TODO: camera doesn't fill in the complete values, show more information
+ // when it is fixed.
+ if (flash.isFlashFired()) {
+ value = context.getString(R.string.flash_on);
+ } else {
+ value = context.getString(R.string.flash_off);
+ }
+ break;
+ }
+ case MediaDetails.INDEX_EXPOSURE_TIME: {
+ value = (String) detail.getValue();
+ double time = Double.valueOf(value);
+ if (time < 1.0f) {
+ value = String.format("1/%d", (int) (0.5f + 1 / time));
+ } else {
+ int integer = (int) time;
+ time -= integer;
+ value = String.valueOf(integer) + "''";
+ if (time > 0.0001) {
+ value += String.format(" 1/%d", (int) (0.5f + 1 / time));
+ }
+ }
+ break;
+ }
+ default: {
+ Object valueObj = detail.getValue();
+ // This shouldn't happen, log its key to help us diagnose the problem.
+ Utils.assertTrue(valueObj != null, "%s's value is Null",
+ DetailsHelper.getDetailsName(context, detail.getKey()));
+ value = valueObj.toString();
+ }
+ }
+ int key = detail.getKey();
+ if (details.hasUnit(key)) {
+ value = String.format("%s : %s %s", DetailsHelper.getDetailsName(
+ context, key), value, context.getString(details.getUnit(key)));
+ } else {
+ value = String.format("%s : %s", DetailsHelper.getDetailsName(
+ context, key), value);
+ }
+ mItems.add(value);
+ }
+ }
+
+ public boolean areAllItemsEnabled() {
+ return false;
+ }
+
+ public boolean isEnabled(int position) {
+ return false;
+ }
+
+ public int getCount() {
+ return mItems.size();
+ }
+
+ public Object getItem(int position) {
+ return mDetails.getDetail(position);
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ TextView tv;
+ if (convertView == null) {
+ tv = (TextView) LayoutInflater.from(mContext.getAndroidContext()).inflate(
+ R.layout.details, parent, false);
+ } else {
+ tv = (TextView) convertView;
+ }
+ tv.setText(mItems.get(position));
+ return tv;
+ }
+
+ public void onAddressAvailable(String address) {
+ mItems.set(mLocationIndex, address);
+ }
+ }
+
+ public void setCloseListener(CloseListener listener) {
+ }
+}
diff --git a/src/com/android/gallery3d/ui/DetailsWindow.java b/src/com/android/gallery3d/ui/GLDetailsView.java
index 760b73a91..cb98d4ee7 100644
--- a/src/com/android/gallery3d/ui/DetailsWindow.java
+++ b/src/com/android/gallery3d/ui/GLDetailsView.java
@@ -26,19 +26,14 @@ import com.android.gallery3d.R;
import com.android.gallery3d.app.GalleryActivity;
import com.android.gallery3d.common.Utils;
import com.android.gallery3d.data.MediaDetails;
-import com.android.gallery3d.util.Future;
-import com.android.gallery3d.util.FutureListener;
-import com.android.gallery3d.util.GalleryUtils;
-import com.android.gallery3d.util.ReverseGeocoder;
-import com.android.gallery3d.util.ThreadPool.Job;
-import com.android.gallery3d.util.ThreadPool.JobContext;
+import com.android.gallery3d.ui.DetailsAddressResolver.AddressResolvingListener;
+import com.android.gallery3d.ui.DetailsHelper.DetailsSource;
+import com.android.gallery3d.ui.DetailsHelper.DetailsViewContainer;
+import com.android.gallery3d.ui.DetailsHelper.CloseListener;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Rect;
-import android.location.Address;
-import android.os.Handler;
-import android.os.Message;
import android.text.format.Formatter;
import android.view.MotionEvent;
import android.view.View.MeasureSpec;
@@ -46,11 +41,9 @@ import android.view.View.MeasureSpec;
import java.util.ArrayList;
import java.util.Map.Entry;
-// TODO: Add scroll bar to this window.
-public class DetailsWindow extends GLView {
+public class GLDetailsView extends GLView implements DetailsViewContainer {
@SuppressWarnings("unused")
- private static final String TAG = "DetailsWindow";
- private static final int MSG_REFRESH_LOCATION = 1;
+ private static final String TAG = "GLDetailsView";
private static final int FONT_COLOR = Color.WHITE;
private static final int CLOSE_BUTTON_SIZE = 32;
@@ -62,8 +55,6 @@ public class DetailsWindow extends GLView {
private DetailsSource mSource;
private int mIndex;
private int mLocationIndex;
- private Future<Address> mAddressLookupJob;
- private Handler mHandler;
private Icon mCloseButton;
private int mMaxDetailLength;
private CloseListener mListener;
@@ -71,32 +62,12 @@ public class DetailsWindow extends GLView {
private ScrollView mScrollView;
private DetailsPanel mDetailPanel = new DetailsPanel();
- public interface DetailsSource {
- public int size();
- public int findIndex(int indexHint);
- public MediaDetails getDetails();
- }
-
- public interface CloseListener {
- public void onClose();
- }
-
- public DetailsWindow(GalleryActivity activity, DetailsSource source) {
+ public GLDetailsView(GalleryActivity activity, DetailsSource source) {
mContext = activity;
mSource = source;
- mHandler = new SynchronizedHandler(activity.getGLRoot()) {
- @Override
- public void handleMessage(Message msg) {
- switch(msg.what) {
- case MSG_REFRESH_LOCATION:
- mModel.updateLocation((Address) msg.obj);
- invalidate();
- break;
- }
- }
- };
+
Context context = activity.getAndroidContext();
- ResourceTexture icon = new ResourceTexture(context, R.drawable.ic_menu_cancel_holo_light);
+ ResourceTexture icon = new ResourceTexture(context, R.drawable.ic_lockscreen_chevron_up);
setBackground(new NinePatchTexture(context, R.drawable.popup_full_dark));
mCloseButton = new Icon(context, icon, CLOSE_BUTTON_SIZE, CLOSE_BUTTON_SIZE) {
@@ -114,8 +85,6 @@ public class DetailsWindow extends GLView {
super.addComponent(mScrollView);
super.addComponent(mCloseButton);
-
- reloadDetails(0);
}
public void setCloseListener(CloseListener listener) {
@@ -162,15 +131,16 @@ public class DetailsWindow extends GLView {
@Override
protected void onMeasure(int widthSpec, int heightSpec) {
- int height = MeasureSpec.getSize(heightSpec);
+ mScrollView.measure(widthSpec, heightSpec);
+ mCloseButton.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+ int height = mScrollView.getMeasuredHeight() + mCloseButton.getMeasuredHeight();
MeasureHelper.getInstance(this)
- .setPreferredContentSize(PREFERRED_WIDTH, height)
+ .setPreferredContentSize(mScrollView.getMeasuredWidth(), height)
.measure(widthSpec, heightSpec);
}
@Override
protected void onLayout(boolean sizeChange, int l, int t, int r, int b) {
- mCloseButton.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
int bWidth = mCloseButton.getMeasuredWidth();
int bHeight = mCloseButton.getMeasuredHeight();
int width = getWidth();
@@ -184,6 +154,7 @@ public class DetailsWindow extends GLView {
}
public void show() {
+ reloadDetails(mSource.getIndex());
setVisibility(GLView.VISIBLE);
requestLayout();
}
@@ -193,14 +164,6 @@ public class DetailsWindow extends GLView {
requestLayout();
}
- public void pause() {
- Future<Address> lookupJob = mAddressLookupJob;
- if (lookupJob != null) {
- lookupJob.cancel();
- lookupJob.waitDone();
- }
- }
-
public void reloadDetails(int indexHint) {
int index = mSource.findIndex(indexHint);
if (index == -1) return;
@@ -219,19 +182,7 @@ public class DetailsWindow extends GLView {
invalidate();
}
- private class AddressLookupJob implements Job<Address> {
- double[] mLatlng;
- protected AddressLookupJob(double[] latlng) {
- mLatlng = latlng;
- }
-
- public Address run(JobContext jc) {
- ReverseGeocoder geocoder = new ReverseGeocoder(mContext.getAndroidContext());
- return geocoder.lookupAddress(mLatlng[0], mLatlng[1], true);
- }
- }
-
- private class MyDataModel {
+ private class MyDataModel implements AddressResolvingListener {
ArrayList<Texture> mItems;
public MyDataModel(MediaDetails details) {
@@ -248,7 +199,9 @@ public class DetailsWindow extends GLView {
String value;
switch (detail.getKey()) {
case MediaDetails.INDEX_LOCATION: {
- value = getLocationText((double[]) detail.getValue());
+ double[] latlng = (double[]) detail.getValue();
+ mLocationIndex = mItems.size();
+ value = DetailsHelper.resolveAddress(mContext, latlng, this);
break;
}
case MediaDetails.INDEX_SIZE: {
@@ -293,16 +246,17 @@ public class DetailsWindow extends GLView {
Object valueObj = detail.getValue();
// This shouldn't happen, log its key to help us diagnose the problem.
Utils.assertTrue(valueObj != null, "%s's value is Null",
- getName(context, detail.getKey()));
+ DetailsHelper.getDetailsName(context, detail.getKey()));
value = valueObj.toString();
}
}
int key = detail.getKey();
if (details.hasUnit(key)) {
- value = String.format("%s : %s %s", getName(context, key), value,
- context.getString(details.getUnit(key)));
+ value = String.format("%s : %s %s", DetailsHelper.getDetailsName(
+ context, key), value, context.getString(details.getUnit(key)));
} else {
- value = String.format("%s : %s", getName(context, key), value);
+ value = String.format("%s : %s", DetailsHelper.getDetailsName(
+ context, key), value);
}
Texture label = MultiLineTexture.newInstance(
value, mMaxDetailLength, FONT_SIZE, FONT_COLOR);
@@ -310,54 +264,6 @@ public class DetailsWindow extends GLView {
}
}
- private String getLocationText(double[] latlng) {
- String text = GalleryUtils.formatLatitudeLongitude("(%f,%f)", latlng[0], latlng[1]);
- mAddressLookupJob = mContext.getThreadPool().submit(
- new AddressLookupJob(latlng),
- new FutureListener<Address>() {
- public void onFutureDone(Future<Address> future) {
- mAddressLookupJob = null;
- if (!future.isCancelled()) {
- mHandler.sendMessage(mHandler.obtainMessage(
- MSG_REFRESH_LOCATION, future.get()));
- }
- }
- });
- mLocationIndex = mItems.size();
- return text;
- }
-
- public void updateLocation(Address address) {
- int index = mLocationIndex;
- if (address != null && index >=0 && index < mItems.size()) {
- Context context = mContext.getAndroidContext();
- String parts[] = {
- address.getAdminArea(),
- address.getSubAdminArea(),
- address.getLocality(),
- address.getSubLocality(),
- address.getThoroughfare(),
- address.getSubThoroughfare(),
- address.getPremises(),
- address.getPostalCode(),
- address.getCountryName()
- };
-
- String addressText = "";
- for (int i = 0; i < parts.length; i++) {
- if (parts[i] == null || parts[i].isEmpty()) continue;
- if (!addressText.isEmpty()) {
- addressText += ", ";
- }
- addressText += parts[i];
- }
- String text = String.format("%s : %s", getName(context,
- MediaDetails.INDEX_LOCATION), addressText);
- mItems.set(index, MultiLineTexture.newInstance(
- text, mMaxDetailLength, FONT_SIZE, FONT_COLOR));
- }
- }
-
public Texture getView(int index) {
return mItems.get(index);
}
@@ -365,50 +271,11 @@ public class DetailsWindow extends GLView {
public int size() {
return mItems.size();
}
- }
- private static String getName(Context context, int key) {
- switch (key) {
- case MediaDetails.INDEX_TITLE:
- return context.getString(R.string.title);
- case MediaDetails.INDEX_DESCRIPTION:
- return context.getString(R.string.description);
- case MediaDetails.INDEX_DATETIME:
- return context.getString(R.string.time);
- case MediaDetails.INDEX_LOCATION:
- return context.getString(R.string.location);
- case MediaDetails.INDEX_PATH:
- return context.getString(R.string.path);
- case MediaDetails.INDEX_WIDTH:
- return context.getString(R.string.width);
- case MediaDetails.INDEX_HEIGHT:
- return context.getString(R.string.height);
- case MediaDetails.INDEX_ORIENTATION:
- return context.getString(R.string.orientation);
- case MediaDetails.INDEX_DURATION:
- return context.getString(R.string.duration);
- case MediaDetails.INDEX_MIMETYPE:
- return context.getString(R.string.mimetype);
- case MediaDetails.INDEX_SIZE:
- return context.getString(R.string.file_size);
- case MediaDetails.INDEX_MAKE:
- return context.getString(R.string.maker);
- case MediaDetails.INDEX_MODEL:
- return context.getString(R.string.model);
- case MediaDetails.INDEX_FLASH:
- return context.getString(R.string.flash);
- case MediaDetails.INDEX_APERTURE:
- return context.getString(R.string.aperture);
- case MediaDetails.INDEX_FOCAL_LENGTH:
- return context.getString(R.string.focal_length);
- case MediaDetails.INDEX_WHITE_BALANCE:
- return context.getString(R.string.white_balance);
- case MediaDetails.INDEX_EXPOSURE_TIME:
- return context.getString(R.string.exposure_time);
- case MediaDetails.INDEX_ISO:
- return context.getString(R.string.iso);
- default:
- return "Unknown key" + key;
+ public void onAddressAvailable(String address) {
+ mItems.set(mLocationIndex, MultiLineTexture.newInstance(
+ address, mMaxDetailLength, FONT_SIZE, FONT_COLOR));
+ GLDetailsView.this.invalidate();
}
}
@@ -423,10 +290,12 @@ public class DetailsWindow extends GLView {
return;
}
- int h = getPaddings().top + LINE_SPACING;
+ Rect p = getPaddings();
+ int h = p.top + LINE_SPACING;
for (int i = 0, n = mModel.size(); i < n; ++i) {
h += mModel.getView(i).getHeight() + LINE_SPACING;
}
+ h += p.bottom;
MeasureHelper.getInstance(this)
.setPreferredContentSize(PREFERRED_WIDTH, h)
@@ -449,4 +318,8 @@ public class DetailsWindow extends GLView {
}
}
}
+
+ public GLView getGLView() {
+ return this;
+ }
}
diff --git a/src/com/android/gallery3d/ui/ScrollView.java b/src/com/android/gallery3d/ui/ScrollView.java
index f7628335c..23a8bb5bf 100644
--- a/src/com/android/gallery3d/ui/ScrollView.java
+++ b/src/com/android/gallery3d/ui/ScrollView.java
@@ -44,6 +44,18 @@ public class ScrollView extends GLView {
}
@Override
+ protected void onMeasure(int widthSpec, int heightSpec) {
+ GLView view = getContentView();
+ if (view != null) {
+ view.measure(widthSpec, heightSpec);
+ MeasureHelper.getInstance(this)
+ .setPreferredContentSize(view.getMeasuredWidth(),
+ view.getMeasuredHeight())
+ .measure(widthSpec, heightSpec);
+ }
+ }
+
+ @Override
public void onLayout(boolean sizeChange, int l, int t, int r, int b) {
GLView content = getContentView();
int width = getWidth();