summaryrefslogtreecommitdiff
path: root/src/plugins/emulator/src/com/motorola/studio/android/emulator/ui/perspective/AndroidEmulatorPerspective.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/emulator/src/com/motorola/studio/android/emulator/ui/perspective/AndroidEmulatorPerspective.java')
-rw-r--r--src/plugins/emulator/src/com/motorola/studio/android/emulator/ui/perspective/AndroidEmulatorPerspective.java254
1 files changed, 254 insertions, 0 deletions
diff --git a/src/plugins/emulator/src/com/motorola/studio/android/emulator/ui/perspective/AndroidEmulatorPerspective.java b/src/plugins/emulator/src/com/motorola/studio/android/emulator/ui/perspective/AndroidEmulatorPerspective.java
new file mode 100644
index 0000000..e1ba398
--- /dev/null
+++ b/src/plugins/emulator/src/com/motorola/studio/android/emulator/ui/perspective/AndroidEmulatorPerspective.java
@@ -0,0 +1,254 @@
+/*
+* Copyright (C) 2012 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.motorola.studio.android.emulator.ui.perspective;
+
+import static com.motorola.studio.android.common.log.StudioLogger.error;
+import static com.motorola.studio.android.common.log.StudioLogger.warn;
+
+import java.util.Collection;
+import java.util.TreeSet;
+
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+import org.eclipse.ui.PartInitException;
+
+import com.motorola.studio.android.common.utilities.EclipseUtils;
+import com.motorola.studio.android.emulator.ui.perspective.extension.AndroidPerspectiveExtensionBean;
+import com.motorola.studio.android.emulator.ui.perspective.extension.AndroidPerspectiveExtensionBean.PerspectiveAreas;
+import com.motorola.studio.android.emulator.ui.perspective.extension.AndroidPerspectiveExtensionReader;
+import com.motorola.studio.android.emulator.ui.perspective.extension.IAndroidPerspectiveExtensionConstants;
+import com.motorola.studio.android.emulator.ui.view.AndroidView;
+import com.motorola.studio.android.emulator.ui.view.MainDisplayView;
+
+/**
+ * DESCRIPTION:
+ * This class represents the Android Emulator perspective.
+ *
+ * RESPONSIBILITY:
+ * Create the Android Emulator perspective.
+ *
+ * COLABORATORS:
+ * None
+ *
+ * USAGE:
+ * This class is referenced by the plugin.xml file of this plugin.
+ */
+public class AndroidEmulatorPerspective implements IPerspectiveFactory
+{
+ private static String LAUNCH_COOLBAR_SHORTCUT = "org.eclipse.debug.ui.launchActionSet";
+
+ /**
+ * Creates the initial layout for a page.
+ *
+ * @param layout the page layout
+ *
+ * @see IPerspectiveFactory#createInitialLayout(IPageLayout)
+ */
+ public void createInitialLayout(IPageLayout layout)
+ {
+ // ---------------HOW THE PERSPECTIVE IS LAID OUT---------------
+ //
+ // The Android Perspective will be dynamically populated according to
+ // the contributions declared to it through the androidPerspectiveExtension
+ // extension point.
+ // The perspective consists of three areas:
+ // - the area where the Android Emulator View is placed, on the right side
+ // - the area where device management related views are placed, on the left side
+ // - the area for emulation views, on the middle
+ // The areas that are dynamically populated are the two last ones, and they will
+ // be referred to as 'dynamic areas' by methods.
+ //
+ // The first area is filled by the code on this method by itself, and the two other
+ // ones are filled depending on what is found for the extension point.
+ // The following drawing illustrates the position of each area on the workbench:
+ //
+ // ____________________________________
+ // | | | |
+ // | | | |
+ // | Dev | | Moto |
+ // | Mgt | | magx |
+ // | Views | Emu Views Area | Emu |
+ // | Area | | View |
+ // | | | Area |
+ // | | | |
+ // |_______|___________________|_______|
+ //
+ // Device Management views are placed atop of each other on their respective area.
+ // Emulation views are laid out depending on the number of views declared. If there
+ // is only one emulation view, it is placed occupying the entire emulation views area.
+ // If there are two emulation views, they divide the emulation views area in half and
+ // occupy the area from bottom to top, as seen on the following drawing:
+ //
+ // ____________________________________
+ // | | | |
+ // | | | |
+ // | Dev | Emu Views part 2 | Moto |
+ // | Mgt | | magx |
+ // | Views |___________________| Emu |
+ // | Area | | View |
+ // | | Emu Views part 1 | Area |
+ // | | | |
+ // |_______|___________________|_______|
+ //
+ // If there are three emulation views or more, they divide the emulation views area in
+ // three parts, which are occupied from bottom to top, as seen on the following drawing:
+ //
+ // ____________________________________
+ // | | | |
+ // | | Emu Views part 3 | |
+ // | Dev |___________________| Moto |
+ // | Mgt | | magx |
+ // | Views | Emu Views part 2 | Emu |
+ // | Area |___________________| View |
+ // | | | Area |
+ // | | Emu Views part 1 | |
+ // |_______|___________________|_______|
+ //
+ // If there are no device management or no emulation views (or both), their folders are
+ // always created so that the workbench is always divided into the correct areas for
+ // better user experience.
+ //
+ // -------------------------------------------------------------
+
+ addEmulatorView(layout);
+ addRunCoolbar(layout);
+ createAndPopulateDynamicAreas(layout);
+
+ // hide the editor area (not necessary on this perspective)
+ layout.setEditorAreaVisible(false);
+ }
+
+ private void addEmulatorView(IPageLayout layout)
+ {
+ // emulator view is a sticky view, no place holder is necessary (only open it)
+ try
+ {
+ EclipseUtils.showView(AndroidView.ANDROID_VIEW_ID);
+ }
+ catch (PartInitException e)
+ {
+ error("Unable to open Android Emulator View on Android Emulator Perspective.");
+ }
+
+ layout.addShowViewShortcut(AndroidView.ANDROID_VIEW_ID);
+ layout.addShowViewShortcut(MainDisplayView.EMULATOR_MAIN_DISPLAY_VIEW_ID);
+ }
+
+ private void addRunCoolbar(IPageLayout layout)
+ {
+ layout.addActionSet(LAUNCH_COOLBAR_SHORTCUT);
+ }
+
+ private void createAndPopulateDynamicAreas(IPageLayout layout)
+ {
+ // read the extensions for this perspective, as declared by the androidPerspectiveExtension
+ // extension point
+ Collection<AndroidPerspectiveExtensionBean> perspectiveExtensionBeans =
+ AndroidPerspectiveExtensionReader.readAndroidPerspectiveExtensions();
+
+ // the folder for placing device management related views
+ IFolderLayout devMgtArea = createDeviceMgtViewsArea(layout);
+
+ // collection of emuy area view ids for later placement
+ // it is alphabetically ordered (so that a group of defined
+ // views always open on the same location)
+ Collection<String> emuAreaViewIds = new TreeSet<String>();
+
+ for (AndroidPerspectiveExtensionBean extensionBean : perspectiveExtensionBeans)
+ {
+ if (PerspectiveAreas.DEVICE_MANAGEMENT_VIEWS_AREA.equals(extensionBean.getArea()))
+ {
+ // put dev mgt views atop of each other on the folder
+ devMgtArea.addView(extensionBean.getViewId());
+ }
+ else if (PerspectiveAreas.EMULATION_VIEWS_AREA.equals(extensionBean.getArea()))
+ {
+ // collect emu views for later placement
+ emuAreaViewIds.add(extensionBean.getViewId());
+ }
+ else
+ {
+ // in case of something not expected, log the problem
+ warn("View of id " + extensionBean.getViewId()
+ + " could not be added to Android Emulator perspective");
+ }
+ }
+
+ // the number of emu views, for defining the number of folders necessary
+ int numEmuViews = emuAreaViewIds.size();
+
+ // create the emu area folders, which will be at most size 3
+ IFolderLayout[] emuAreaFolders = createEmuArea(layout, numEmuViews);
+
+ // place the views on the correct folder by using the leftover of dividing the
+ // number of the current view by number of maximum folders (3)
+ int i = 0;
+ for (String viewId : emuAreaViewIds)
+ {
+ emuAreaFolders[i % 3].addView(viewId);
+ i++; // next view
+ }
+ }
+
+ private IFolderLayout createDeviceMgtViewsArea(IPageLayout layout)
+ {
+ return layout.createFolder(IAndroidPerspectiveExtensionConstants.ATT_AREA_DEVMGT_VALUE,
+ IPageLayout.LEFT, 0.30f, IPageLayout.ID_EDITOR_AREA);
+ }
+
+ private IFolderLayout[] createEmuArea(IPageLayout layout, int numEmuViews)
+ {
+ // at most 3 folders are necessary
+ IFolderLayout[] emuAreaFolders = new IFolderLayout[3];
+
+ // the number of divisions the emu views area will be divided into
+ int div = (numEmuViews >= 3 ? 3 : (numEmuViews == 2 ? 2 : 1));
+
+ // the ratio for the first folder to be placed (the bottom one, which may turn
+ // to be the only one if div is equal to 1)
+ float ratio = 1.00f / div;
+
+ // the bottom folder (#1) is always necessary
+ // for 3 folders, ratio = 0.33f; for 2 folders, ratio = 0.5f
+ emuAreaFolders[0] =
+ layout.createFolder("emuAreaBottom", IPageLayout.BOTTOM, ratio,
+ IPageLayout.ID_EDITOR_AREA);
+
+ // create folder #2 only if necessary
+ if (numEmuViews >= 2)
+ {
+ // adjust ratio depending on the number of folders in total:
+ // for 3 folders, ratio = 0.67f; for 2 folders, ratio = 0.5f
+ if (numEmuViews > 2)
+ {
+ ratio = 2 * ratio;
+ }
+ emuAreaFolders[1] =
+ layout.createFolder("emuAreaMiddle", IPageLayout.TOP, ratio, "emuAreaBottom");
+ }
+
+ // create folder #3 only if necessary
+ if (numEmuViews >= 3)
+ {
+ // ratio is always half of folder #2 space
+ emuAreaFolders[2] =
+ layout.createFolder("emuAreaTop", IPageLayout.TOP, 0.50f, "emuAreaMiddle");
+ }
+
+ return emuAreaFolders;
+ }
+}