diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PlayAnimationMenu.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PlayAnimationMenu.java | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PlayAnimationMenu.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PlayAnimationMenu.java new file mode 100644 index 000000000..629a42f18 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PlayAnimationMenu.java @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php + * + * 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.ide.eclipse.adt.internal.editors.layout.gle2; + +import static com.android.SdkConstants.FD_RESOURCES; +import static com.android.SdkConstants.FD_RES_ANIMATOR; +import static com.android.ide.eclipse.adt.AdtConstants.WS_SEP; + +import com.android.ide.common.rendering.api.Capability; +import com.android.ide.common.rendering.api.IAnimationListener; +import com.android.ide.common.rendering.api.RenderSession; +import com.android.ide.common.rendering.api.Result; +import com.android.ide.eclipse.adt.AdtPlugin; +import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate; +import com.android.ide.eclipse.adt.internal.wizards.newxmlfile.NewXmlFileWizard; +import com.android.resources.ResourceType; +import com.android.utils.Pair; + +import org.eclipse.core.resources.IProject; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchWindow; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * "Play Animation" context menu which lists available animations in the project and in + * the framework, as well as a "Create Animation" shortcut, and allows the animation to be + * run on the selection + * <p/> + * TODO: Add transport controls for play/rewind/pause/loop, and (if possible) scrubbing + */ +public class PlayAnimationMenu extends SubmenuAction { + /** Associated canvas */ + private final LayoutCanvas mCanvas; + /** Whether this menu is showing local animations or framework animations */ + private boolean mFramework; + + /** + * Creates a "Play Animation" menu + * + * @param canvas associated canvas + */ + public PlayAnimationMenu(LayoutCanvas canvas) { + this(canvas, "Play Animation", false); + } + + /** + * Creates an animation menu; this can be used either for the outer Play animation + * menu, or the inner frameworks-animations list + * + * @param canvas the associated canvas + * @param title menu item name + * @param framework true to show the framework animations, false for the project (and + * nested framework-animation-menu) animations + */ + private PlayAnimationMenu(LayoutCanvas canvas, String title, boolean framework) { + super(title); + mCanvas = canvas; + mFramework = framework; + } + + @Override + protected void addMenuItems(Menu menu) { + SelectionManager selectionManager = mCanvas.getSelectionManager(); + List<SelectionItem> selection = selectionManager.getSelections(); + if (selection.size() != 1) { + addDisabledMessageItem("Select exactly one widget"); + return; + } + + GraphicalEditorPart graphicalEditor = mCanvas.getEditorDelegate().getGraphicalEditor(); + if (graphicalEditor.renderingSupports(Capability.PLAY_ANIMATION)) { + // List of animations + Collection<String> animationNames = graphicalEditor.getResourceNames(mFramework, + ResourceType.ANIMATOR); + if (animationNames.size() > 0) { + // Sort alphabetically + List<String> sortedNames = new ArrayList<String>(animationNames); + Collections.sort(sortedNames); + + for (String animation : sortedNames) { + String title = animation; + IAction action = new PlayAnimationAction(title, animation, mFramework); + new ActionContributionItem(action).fill(menu, -1); + } + + new Separator().fill(menu, -1); + } + + if (!mFramework) { + // Not in the framework submenu: include recent list and create new actions + + // "Create New" action + new ActionContributionItem(new CreateAnimationAction()).fill(menu, -1); + + // Framework resources submenu + new Separator().fill(menu, -1); + PlayAnimationMenu sub = new PlayAnimationMenu(mCanvas, "Android Builtin", true); + new ActionContributionItem(sub).fill(menu, -1); + } + } else { + addDisabledMessageItem( + "Not supported for this SDK version; try changing the Render Target"); + } + } + + private class PlayAnimationAction extends Action { + private final String mAnimationName; + private final boolean mIsFrameworkAnim; + + public PlayAnimationAction(String title, String animationName, boolean isFrameworkAnim) { + super(title, IAction.AS_PUSH_BUTTON); + mAnimationName = animationName; + mIsFrameworkAnim = isFrameworkAnim; + } + + @Override + public void run() { + SelectionManager selectionManager = mCanvas.getSelectionManager(); + List<SelectionItem> selection = selectionManager.getSelections(); + SelectionItem canvasSelection = selection.get(0); + CanvasViewInfo info = canvasSelection.getViewInfo(); + + Object viewObject = info.getViewObject(); + if (viewObject != null) { + ViewHierarchy viewHierarchy = mCanvas.getViewHierarchy(); + RenderSession session = viewHierarchy.getSession(); + Result r = session.animate(viewObject, mAnimationName, mIsFrameworkAnim, + new IAnimationListener() { + private boolean mPendingDrawing = false; + + @Override + public void onNewFrame(RenderSession s) { + SelectionOverlay selectionOverlay = mCanvas.getSelectionOverlay(); + if (!selectionOverlay.isHiding()) { + selectionOverlay.setHiding(true); + } + HoverOverlay hoverOverlay = mCanvas.getHoverOverlay(); + if (!hoverOverlay.isHiding()) { + hoverOverlay.setHiding(true); + } + + ImageOverlay imageOverlay = mCanvas.getImageOverlay(); + imageOverlay.setImage(s.getImage(), s.isAlphaChannelImage()); + synchronized (this) { + if (mPendingDrawing == false) { + mCanvas.getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + synchronized (this) { + mPendingDrawing = false; + } + mCanvas.redraw(); + } + }); + mPendingDrawing = true; + } + } + } + + @Override + public boolean isCanceled() { + return false; + } + + @Override + public void done(Result result) { + SelectionOverlay selectionOverlay = mCanvas.getSelectionOverlay(); + selectionOverlay.setHiding(false); + HoverOverlay hoverOverlay = mCanvas.getHoverOverlay(); + hoverOverlay.setHiding(false); + + // Must refresh view hierarchy to force objects back to + // their original positions in case animations have left + // them elsewhere + mCanvas.getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + GraphicalEditorPart graphicalEditor = mCanvas + .getEditorDelegate().getGraphicalEditor(); + graphicalEditor.recomputeLayout(); + } + }); + } + }); + + if (!r.isSuccess()) { + if (r.getErrorMessage() != null) { + AdtPlugin.log(r.getException(), r.getErrorMessage()); + } + } + } + } + } + + /** + * Action which brings up the "Create new XML File" wizard, pre-selected with the + * animation category + */ + private class CreateAnimationAction extends Action { + public CreateAnimationAction() { + super("Create...", IAction.AS_PUSH_BUTTON); + } + + @Override + public void run() { + Shell parent = mCanvas.getShell(); + NewXmlFileWizard wizard = new NewXmlFileWizard(); + LayoutEditorDelegate editor = mCanvas.getEditorDelegate(); + IWorkbenchWindow workbenchWindow = + editor.getEditor().getEditorSite().getWorkbenchWindow(); + IWorkbench workbench = workbenchWindow.getWorkbench(); + String animationDir = FD_RESOURCES + WS_SEP + FD_RES_ANIMATOR; + Pair<IProject, String> pair = Pair.of(editor.getEditor().getProject(), animationDir); + IStructuredSelection selection = new StructuredSelection(pair); + wizard.init(workbench, selection); + WizardDialog dialog = new WizardDialog(parent, wizard); + dialog.create(); + dialog.open(); + } + } +} |