summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/photoeditor
diff options
context:
space:
mode:
authorYuli Huang <yuli@google.com>2011-10-01 02:05:06 +0800
committerYuli Huang <yuli@google.com>2011-10-04 00:26:14 +0800
commit305740f973407ec783fac92490a6df1b675632e2 (patch)
tree2a7da0aea8fdced2d639bbe04c2f101f8d41aa9b /src/com/android/gallery3d/photoeditor
parente0856697e69a7802040c004232e4cdec4113a88e (diff)
downloadandroid_packages_apps_Snap-305740f973407ec783fac92490a6df1b675632e2.tar.gz
android_packages_apps_Snap-305740f973407ec783fac92490a6df1b675632e2.tar.bz2
android_packages_apps_Snap-305740f973407ec783fac92490a6df1b675632e2.zip
Fix b/5317371 to make action-bar consistent with framework CAB.
1. Refactor to decouple ActionBar from FilterStackListener and ActionBarListener to avoid FilterStack/Toolbar depending on ActionBar. 2. Recreate the action-bar on configuration changes and restore button status and behaviors from the old action-bar. 3. Use framework CAB styles/dimensions to have consistent look and feel. Change-Id: Ib7be0e0b8135f5f86af65b320f09b3d691464f54
Diffstat (limited to 'src/com/android/gallery3d/photoeditor')
-rw-r--r--src/com/android/gallery3d/photoeditor/ActionBar.java125
-rw-r--r--src/com/android/gallery3d/photoeditor/FilterStack.java13
-rw-r--r--src/com/android/gallery3d/photoeditor/LoadScreennailTask.java8
-rw-r--r--src/com/android/gallery3d/photoeditor/PhotoEditor.java203
-rw-r--r--src/com/android/gallery3d/photoeditor/SaveCopyTask.java2
-rw-r--r--src/com/android/gallery3d/photoeditor/Toolbar.java169
-rw-r--r--src/com/android/gallery3d/photoeditor/ToolbarIdleHandler.java91
-rw-r--r--src/com/android/gallery3d/photoeditor/YesNoCancelDialogBuilder.java39
8 files changed, 305 insertions, 345 deletions
diff --git a/src/com/android/gallery3d/photoeditor/ActionBar.java b/src/com/android/gallery3d/photoeditor/ActionBar.java
index 32eb79274..5a423b905 100644
--- a/src/com/android/gallery3d/photoeditor/ActionBar.java
+++ b/src/com/android/gallery3d/photoeditor/ActionBar.java
@@ -17,66 +17,36 @@
package com.android.gallery3d.photoeditor;
import android.content.Context;
-import android.os.Handler;
-import android.os.Message;
import android.util.AttributeSet;
import android.view.View;
import android.widget.RelativeLayout;
import com.android.gallery3d.R;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map.Entry;
+
/**
- * Action bar that contains buttons such as undo, redo, save, etc. and listens to stack changes for
- * enabling/disabling buttons.
+ * Action bar that contains buttons such as undo, redo, save, etc.
*/
-public class ActionBar extends RelativeLayout implements FilterStack.StackListener {
-
- /**
- * Listener of action button clicked.
- */
- public interface ActionBarListener {
-
- void onUndo();
+public class ActionBar extends RelativeLayout {
- void onRedo();
-
- void onSave();
- }
-
- private static final int ENABLE_BUTTON = 1;
private static final float ENABLED_ALPHA = 1;
private static final float DISABLED_ALPHA = 0.47f;
- private final Handler handler;
- private View undo;
- private View redo;
- private View save;
+ private final HashMap<Integer, Runnable> buttonRunnables = new HashMap<Integer, Runnable>();
+ private final HashSet<Integer> changedButtons = new HashSet<Integer>();
public ActionBar(Context context, AttributeSet attrs) {
super(context, attrs);
-
- handler = new Handler() {
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case ENABLE_BUTTON:
- boolean canUndo = (msg.arg1 > 0);
- boolean canRedo = (msg.arg2 > 0);
- enableButton(undo, canUndo);
- enableButton(redo, canRedo);
- enableButton(save, canUndo);
- break;
- }
- }
- };
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
- // Show action-bar title only when there's still room for it; otherwise, hide it.
+ // Show the action-bar title only when there's still room for it; otherwise, hide it.
int width = 0;
for (int i = 0; i < getChildCount(); i++) {
width += getChildAt(i).getWidth();
@@ -84,67 +54,58 @@ public class ActionBar extends RelativeLayout implements FilterStack.StackListen
findViewById(R.id.action_bar_title).setVisibility(((width > r - l)) ? INVISIBLE: VISIBLE);
}
- /**
- * Initializes with a non-null ActionBarListener.
- */
- public void initialize(final ActionBarListener listener) {
- undo = findViewById(R.id.undo_button);
- undo.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- if (isEnabled()) {
- listener.onUndo();
- }
- }
- });
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
- redo = findViewById(R.id.redo_button);
- redo.setOnClickListener(new OnClickListener() {
+ enableButton(R.id.undo_button, false);
+ enableButton(R.id.redo_button, false);
+ enableButton(R.id.save_button, false);
+ }
- @Override
- public void onClick(View v) {
- if (isEnabled()) {
- listener.onRedo();
- }
- }
- });
+ /**
+ * Restores the passed action-bar.
+ *
+ * @return the passed parameter.
+ */
+ public ActionBar restore(ActionBar actionBar) {
+ // Restores by runnables and enabled status of buttons that have been changed.
+ for (Entry<Integer, Runnable> entry : buttonRunnables.entrySet()) {
+ actionBar.setRunnable(entry.getKey(), entry.getValue());
+ }
+ for (int buttonId : changedButtons) {
+ actionBar.enableButton(buttonId, isButtonEnabled(buttonId));
+ }
+ return actionBar;
+ }
- save = findViewById(R.id.save_button);
- save.setOnClickListener(new OnClickListener() {
+ public void setRunnable(int buttonId, final Runnable r) {
+ findViewById(buttonId).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (isEnabled()) {
- listener.onSave();
+ r.run();
}
}
});
-
- resetButtons();
+ buttonRunnables.put(buttonId, r);
}
- public void resetButtons() {
- // Disable buttons immediately instead of waiting for ENABLE_BUTTON messages which may
- // happen some time later after stack changes.
- enableButton(undo, false);
- enableButton(redo, false);
- enableButton(save, false);
+ public void clickButton(int buttonId) {
+ findViewById(buttonId).performClick();
}
- public void disableSave() {
- enableButton(save, false);
+ public boolean isButtonEnabled(int buttonId) {
+ return findViewById(buttonId).isEnabled();
}
- private void enableButton(View button, boolean enabled) {
+ public void enableButton(int buttonId, boolean enabled) {
+ View button = findViewById(buttonId);
button.setEnabled(enabled);
button.setAlpha(enabled ? ENABLED_ALPHA : DISABLED_ALPHA);
- }
- @Override
- public void onStackChanged(boolean canUndo, boolean canRedo) {
- // Listens to stack changes that may come from the worker thread; send messages to enable
- // buttons only in the UI thread.
- handler.sendMessage(handler.obtainMessage(ENABLE_BUTTON, canUndo ? 1 : 0, canRedo ? 1 : 0));
+ // Track buttons whose enabled status has been updated.
+ changedButtons.add(buttonId);
}
}
diff --git a/src/com/android/gallery3d/photoeditor/FilterStack.java b/src/com/android/gallery3d/photoeditor/FilterStack.java
index 3b35aa3e1..5b8d0d743 100644
--- a/src/com/android/gallery3d/photoeditor/FilterStack.java
+++ b/src/com/android/gallery3d/photoeditor/FilterStack.java
@@ -113,7 +113,7 @@ public class FilterStack {
}
private void callbackDone(final OnDoneCallback callback) {
- // Call back in UI thread to report done.
+ // GL thread calls back to report UI thread the task is done.
photoView.post(new Runnable() {
@Override
@@ -124,7 +124,16 @@ public class FilterStack {
}
private void stackChanged() {
- stackListener.onStackChanged(!appliedStack.empty(), !redoStack.empty());
+ // GL thread calls back to report UI thread the stack is changed.
+ final boolean canUndo = !appliedStack.empty();
+ final boolean canRedo = !redoStack.empty();
+ photoView.post(new Runnable() {
+
+ @Override
+ public void run() {
+ stackListener.onStackChanged(canUndo, canRedo);
+ }
+ });
}
public void saveBitmap(final OnDoneBitmapCallback callback) {
diff --git a/src/com/android/gallery3d/photoeditor/LoadScreennailTask.java b/src/com/android/gallery3d/photoeditor/LoadScreennailTask.java
index 914d50b9d..9ac85af93 100644
--- a/src/com/android/gallery3d/photoeditor/LoadScreennailTask.java
+++ b/src/com/android/gallery3d/photoeditor/LoadScreennailTask.java
@@ -35,7 +35,7 @@ public class LoadScreennailTask extends AsyncTask<Uri, Void, Bitmap> {
*/
public interface Callback {
- void onComplete(Bitmap bitmap);
+ void onComplete(Bitmap result);
}
private static final int SCREENNAIL_WIDTH = 1280;
@@ -61,12 +61,12 @@ public class LoadScreennailTask extends AsyncTask<Uri, Void, Bitmap> {
}
@Override
- protected void onPostExecute(Bitmap bitmap) {
- if (bitmap == null) {
+ protected void onPostExecute(Bitmap result) {
+ if (result == null) {
Toast toast = Toast.makeText(context, R.string.loading_failure, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
- callback.onComplete(bitmap);
+ callback.onComplete(result);
}
}
diff --git a/src/com/android/gallery3d/photoeditor/PhotoEditor.java b/src/com/android/gallery3d/photoeditor/PhotoEditor.java
index c7ec48f33..e36071eea 100644
--- a/src/com/android/gallery3d/photoeditor/PhotoEditor.java
+++ b/src/com/android/gallery3d/photoeditor/PhotoEditor.java
@@ -17,24 +17,25 @@
package com.android.gallery3d.photoeditor;
import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
import android.content.Intent;
+import android.content.res.Configuration;
+import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
+import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
import com.android.gallery3d.R;
/**
- * Main activity of the photo editor.
+ * Main activity of the photo editor that opens a photo and prepares tools for photo editing.
*/
public class PhotoEditor extends Activity {
private Uri uri;
private FilterStack filterStack;
- private Toolbar toolbar;
- private View backButton;
+ private ActionBar actionBar;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -44,79 +45,167 @@ public class PhotoEditor extends Activity {
Intent intent = getIntent();
uri = Intent.ACTION_EDIT.equalsIgnoreCase(intent.getAction()) ? intent.getData() : null;
- final ActionBar actionBar = (ActionBar) findViewById(R.id.action_bar);
- filterStack = new FilterStack((PhotoView) findViewById(R.id.photo_view), actionBar);
- toolbar = (Toolbar) findViewById(R.id.toolbar);
- toolbar.initialize(filterStack);
+ actionBar = (ActionBar) findViewById(R.id.action_bar);
+ filterStack = new FilterStack((PhotoView) findViewById(R.id.photo_view),
+ new FilterStack.StackListener() {
- final EffectsBar effectsBar = (EffectsBar) findViewById(R.id.effects_bar);
- backButton = findViewById(R.id.action_bar_back);
- backButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onStackChanged(boolean canUndo, boolean canRedo) {
+ actionBar.enableButton(R.id.undo_button, canUndo);
+ actionBar.enableButton(R.id.redo_button, canRedo);
+ actionBar.enableButton(R.id.save_button, canUndo);
+ }
+ });
+
+ EffectsBar effectsBar = (EffectsBar) findViewById(R.id.effects_bar);
+ effectsBar.initialize(filterStack);
+
+ actionBar.setRunnable(R.id.undo_button, createUndoRedoRunnable(true, effectsBar));
+ actionBar.setRunnable(R.id.redo_button, createUndoRedoRunnable(false, effectsBar));
+ actionBar.setRunnable(R.id.save_button, createSaveRunnable(effectsBar));
+ actionBar.setRunnable(R.id.action_bar_back, createBackRunnable(effectsBar));
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
+ actionBar = actionBar.restore((ActionBar) recreateView(
+ actionBar, inflater, R.layout.photoeditor_actionbar));
+ }
+
+ /**
+ * Recreates the view by inflating the given layout id.
+ */
+ private View recreateView(View view, LayoutInflater inflater, int layoutId) {
+ ViewGroup parent = (ViewGroup) view.getParent();
+ int index = parent.indexOfChild(view);
+ parent.removeViewAt(index);
+
+ View recreated = inflater.inflate(layoutId, parent, false);
+ parent.addView(recreated, index);
+ return recreated;
+ }
+
+ private SpinnerProgressDialog createProgressDialog() {
+ return SpinnerProgressDialog.show((ViewGroup) findViewById(R.id.toolbar));
+ }
+
+ private void openPhoto() {
+ final SpinnerProgressDialog progressDialog = createProgressDialog();
+ LoadScreennailTask.Callback callback = new LoadScreennailTask.Callback() {
@Override
- public void onClick(View v) {
- if (actionBar.isEnabled()) {
- // Exit effects or go back to the previous activity on pressing back button.
- if (!effectsBar.exit(null)) {
- tryRun(new Runnable() {
+ public void onComplete(final Bitmap result) {
+ filterStack.setPhotoSource(result, new OnDoneCallback() {
+
+ @Override
+ public void onDone() {
+ progressDialog.dismiss();
+ }
+ });
+ }
+ };
+ new LoadScreennailTask(this, callback).execute(uri);
+ }
+
+ private Runnable createUndoRedoRunnable(final boolean undo, final EffectsBar effectsBar) {
+ return new Runnable() {
+
+ @Override
+ public void run() {
+ effectsBar.exit(new Runnable() {
+
+ @Override
+ public void run() {
+ final SpinnerProgressDialog progressDialog = createProgressDialog();
+ OnDoneCallback callback = new OnDoneCallback() {
@Override
- public void run() {
- finish();
+ public void onDone() {
+ progressDialog.dismiss();
+ }
+ };
+ if (undo) {
+ filterStack.undo(callback);
+ } else {
+ filterStack.redo(callback);
+ }
+ }
+ });
+ }
+ };
+ }
+
+ private Runnable createSaveRunnable(final EffectsBar effectsBar) {
+ return new Runnable() {
+
+ @Override
+ public void run() {
+ effectsBar.exit(new Runnable() {
+
+ @Override
+ public void run() {
+ final SpinnerProgressDialog progressDialog = createProgressDialog();
+ filterStack.saveBitmap(new OnDoneBitmapCallback() {
+
+ @Override
+ public void onDone(Bitmap bitmap) {
+ SaveCopyTask.Callback callback = new SaveCopyTask.Callback() {
+
+ @Override
+ public void onComplete(Uri result) {
+ progressDialog.dismiss();
+ actionBar.enableButton(R.id.save_button, (result == null));
+ }
+ };
+ new SaveCopyTask(PhotoEditor.this, uri, callback).execute(bitmap);
}
});
}
- }
+ });
}
- });
+ };
}
- private void tryRun(final Runnable runnable) {
- if (findViewById(R.id.save_button).isEnabled()) {
- // Pop-up a dialog before executing the runnable to save unsaved photo.
- AlertDialog.Builder builder = new AlertDialog.Builder(this)
- .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- toolbar.savePhoto(new Runnable() {
-
- @Override
- public void run() {
- runnable.run();
- }
- });
- }
- })
- .setNeutralButton(R.string.no, new DialogInterface.OnClickListener() {
+ private Runnable createBackRunnable(final EffectsBar effectsBar) {
+ return new Runnable() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- runnable.run();
- }
- })
- .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ @Override
+ public void run() {
+ // Exit effects or go back to the previous activity on pressing back button.
+ if (!effectsBar.exit(null)) {
+ // Pop-up a dialog to save unsaved photo.
+ if (actionBar.isButtonEnabled(R.id.save_button)) {
+ new YesNoCancelDialogBuilder(PhotoEditor.this, new Runnable() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // no-op
- }
- });
- builder.setMessage(R.string.save_photo).show();
- return;
- }
+ @Override
+ public void run() {
+ actionBar.clickButton(R.id.save_button);
+ }
+ }, new Runnable() {
- runnable.run();
+ @Override
+ public void run() {
+ finish();
+ }
+ }, R.string.save_photo).show();
+ } else {
+ finish();
+ }
+ }
+ }
+ };
}
@Override
public void onBackPressed() {
- backButton.performClick();
+ actionBar.clickButton(R.id.action_bar_back);
}
@Override
protected void onPause() {
- // TODO: Close running spinner progress dialogs as all pending operations will be paused.
+ // TODO: Close running progress dialogs as all pending operations will be paused.
super.onPause();
filterStack.onPause();
}
@@ -125,6 +214,6 @@ public class PhotoEditor extends Activity {
protected void onResume() {
super.onResume();
filterStack.onResume();
- toolbar.openPhoto(uri);
+ openPhoto();
}
}
diff --git a/src/com/android/gallery3d/photoeditor/SaveCopyTask.java b/src/com/android/gallery3d/photoeditor/SaveCopyTask.java
index d46756335..bedd4169a 100644
--- a/src/com/android/gallery3d/photoeditor/SaveCopyTask.java
+++ b/src/com/android/gallery3d/photoeditor/SaveCopyTask.java
@@ -45,7 +45,7 @@ public class SaveCopyTask extends AsyncTask<Bitmap, Void, Uri> {
*/
public interface Callback {
- void onComplete(Uri uri);
+ void onComplete(Uri result);
}
private static final String TIME_STAMP_NAME = "'IMG'_yyyyMMdd_HHmmss";
diff --git a/src/com/android/gallery3d/photoeditor/Toolbar.java b/src/com/android/gallery3d/photoeditor/Toolbar.java
index 72f243bab..45ec016bb 100644
--- a/src/com/android/gallery3d/photoeditor/Toolbar.java
+++ b/src/com/android/gallery3d/photoeditor/Toolbar.java
@@ -17,30 +17,33 @@
package com.android.gallery3d.photoeditor;
import android.content.Context;
-import android.graphics.Bitmap;
-import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
+import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
import android.widget.RelativeLayout;
import com.android.gallery3d.R;
+import java.util.ArrayList;
+import java.util.List;
+
/**
- * Toolbar that contains all tools and handles all operations for editing photo.
+ * Toolbar that contains all tools and controls their idle/awake behaviors from UI thread.
*/
public class Toolbar extends RelativeLayout {
private final ToolbarIdleHandler idleHandler;
- private FilterStack filterStack;
- private EffectsBar effectsBar;
- private ActionBar actionBar;
- private Uri sourceUri;
public Toolbar(Context context, AttributeSet attrs) {
super(context, attrs);
idleHandler = new ToolbarIdleHandler(context);
setOnHierarchyChangeListener(idleHandler);
+ idleHandler.killIdle();
}
@Override
@@ -49,111 +52,61 @@ public class Toolbar extends RelativeLayout {
return super.dispatchTouchEvent(ev);
}
- public void initialize(FilterStack filterStack) {
- this.filterStack = filterStack;
- effectsBar = (EffectsBar) findViewById(R.id.effects_bar);
- effectsBar.initialize(filterStack);
- actionBar = (ActionBar) findViewById(R.id.action_bar);
- actionBar.initialize(createActionBarListener());
- idleHandler.killIdle();
- }
-
- private ActionBar.ActionBarListener createActionBarListener() {
- actionBar = (ActionBar) findViewById(R.id.action_bar);
- return new ActionBar.ActionBarListener() {
-
- @Override
- public void onUndo() {
- effectsBar.exit(new Runnable() {
-
- @Override
- public void run() {
- final SpinnerProgressDialog progressDialog = SpinnerProgressDialog.show(
- Toolbar.this);
- filterStack.undo(new OnDoneCallback() {
-
- @Override
- public void onDone() {
- progressDialog.dismiss();
+ private static class ToolbarIdleHandler implements OnHierarchyChangeListener {
+
+ private static final int MAKE_IDLE = 1;
+ private static final int TIMEOUT_IDLE = 8000;
+
+ private final List<View> childViews = new ArrayList<View>();
+ private final Handler mainHandler;
+ private final Animation fadeIn;
+ private final Animation fadeOut;
+ private boolean idle;
+
+ public ToolbarIdleHandler(Context context) {
+ mainHandler = new Handler() {
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MAKE_IDLE:
+ if (!idle) {
+ idle = true;
+ for (View view : childViews) {
+ view.startAnimation(fadeOut);
+ }
}
- });
+ break;
}
- });
+ }
+ };
+
+ fadeIn = AnimationUtils.loadAnimation(context, R.anim.photoeditor_fade_in);
+ fadeOut = AnimationUtils.loadAnimation(context, R.anim.photoeditor_fade_out);
+ }
+
+ public void killIdle() {
+ mainHandler.removeMessages(MAKE_IDLE);
+ if (idle) {
+ idle = false;
+ for (View view : childViews) {
+ view.startAnimation(fadeIn);
+ }
}
-
- @Override
- public void onRedo() {
- effectsBar.exit(new Runnable() {
-
- @Override
- public void run() {
- final SpinnerProgressDialog progressDialog = SpinnerProgressDialog.show(
- Toolbar.this);
- filterStack.redo(new OnDoneCallback() {
-
- @Override
- public void onDone() {
- progressDialog.dismiss();
- }
- });
- }
- });
+ mainHandler.sendEmptyMessageDelayed(MAKE_IDLE, TIMEOUT_IDLE);
+ }
+
+ @Override
+ public void onChildViewAdded(View parent, View child) {
+ // All child views, except photo-view, will fade out on inactivity timeout.
+ if (child.getId() != R.id.photo_view) {
+ childViews.add(child);
}
+ }
- @Override
- public void onSave() {
- effectsBar.exit(new Runnable() {
-
- @Override
- public void run() {
- savePhoto(null);
- }
- });
- }
- };
- }
-
- public void openPhoto(Uri uri) {
- sourceUri = uri;
-
- final SpinnerProgressDialog progressDialog = SpinnerProgressDialog.show(this);
- new LoadScreennailTask(getContext(), new LoadScreennailTask.Callback() {
-
- @Override
- public void onComplete(final Bitmap bitmap) {
- filterStack.setPhotoSource(bitmap, new OnDoneCallback() {
-
- @Override
- public void onDone() {
- progressDialog.dismiss();
- }
- });
- }
- }).execute(sourceUri);
- }
-
- /**
- * Saves photo and executes runnable (if provided) after saving done.
- */
- public void savePhoto(final Runnable runnable) {
- final SpinnerProgressDialog progressDialog = SpinnerProgressDialog.show(this);
- filterStack.saveBitmap(new OnDoneBitmapCallback() {
-
- @Override
- public void onDone(Bitmap bitmap) {
- new SaveCopyTask(getContext(), sourceUri, new SaveCopyTask.Callback() {
-
- @Override
- public void onComplete(Uri uri) {
- // TODO: Handle saving failure.
- progressDialog.dismiss();
- actionBar.disableSave();
- if (runnable != null) {
- runnable.run();
- }
- }
- }).execute(bitmap);
- }
- });
+ @Override
+ public void onChildViewRemoved(View parent, View child) {
+ childViews.remove(child);
+ }
}
}
diff --git a/src/com/android/gallery3d/photoeditor/ToolbarIdleHandler.java b/src/com/android/gallery3d/photoeditor/ToolbarIdleHandler.java
deleted file mode 100644
index 5cef56686..000000000
--- a/src/com/android/gallery3d/photoeditor/ToolbarIdleHandler.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.photoeditor;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.Message;
-import android.view.View;
-import android.view.ViewGroup.OnHierarchyChangeListener;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
-
-import com.android.gallery3d.R;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Handler that controls idle/awake behaviors of toolbar's child views from UI thread.
- */
-class ToolbarIdleHandler implements OnHierarchyChangeListener {
-
- private static final int MAKE_IDLE = 1;
- private static final int TIMEOUT_IDLE = 8000;
-
- private final List<View> childViews = new ArrayList<View>();
- private final Handler mainHandler;
- private final Animation fadeIn;
- private final Animation fadeOut;
- private boolean idle;
-
- public ToolbarIdleHandler(Context context) {
- mainHandler = new Handler() {
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MAKE_IDLE:
- if (!idle) {
- idle = true;
- for (View view : childViews) {
- view.startAnimation(fadeOut);
- }
- }
- break;
- }
- }
- };
-
- fadeIn = AnimationUtils.loadAnimation(context, R.anim.photoeditor_fade_in);
- fadeOut = AnimationUtils.loadAnimation(context, R.anim.photoeditor_fade_out);
- }
-
- public void killIdle() {
- mainHandler.removeMessages(MAKE_IDLE);
- if (idle) {
- idle = false;
- for (View view : childViews) {
- view.startAnimation(fadeIn);
- }
- }
- mainHandler.sendEmptyMessageDelayed(MAKE_IDLE, TIMEOUT_IDLE);
- }
-
- @Override
- public void onChildViewAdded(View parent, View child) {
- // All child views, except photo-view, will fade out on inactivity timeout.
- if (child.getId() != R.id.photo_view) {
- childViews.add(child);
- }
- }
-
- @Override
- public void onChildViewRemoved(View parent, View child) {
- childViews.remove(child);
- }
-}
diff --git a/src/com/android/gallery3d/photoeditor/YesNoCancelDialogBuilder.java b/src/com/android/gallery3d/photoeditor/YesNoCancelDialogBuilder.java
new file mode 100644
index 000000000..fcc99c0d3
--- /dev/null
+++ b/src/com/android/gallery3d/photoeditor/YesNoCancelDialogBuilder.java
@@ -0,0 +1,39 @@
+package com.android.gallery3d.photoeditor;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+
+import com.android.gallery3d.R;
+
+/**
+ * Alert dialog builder that builds a simple Yes/No/Cancel dialog.
+ */
+public class YesNoCancelDialogBuilder extends AlertDialog.Builder {
+
+ public YesNoCancelDialogBuilder(Context context, final Runnable yes, final Runnable no,
+ int messageId) {
+ super(context);
+ setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ yes.run();
+ }
+ })
+ .setNeutralButton(R.string.no, new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ no.run();
+ }
+ })
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // no-op
+ }
+ }).setMessage(messageId);
+ }
+}