diff options
Diffstat (limited to 'src/plugins/emulator/src/com/motorola/studio/android/emulator/device/ui/StartupOptionsComposite.java')
-rw-r--r-- | src/plugins/emulator/src/com/motorola/studio/android/emulator/device/ui/StartupOptionsComposite.java | 435 |
1 files changed, 435 insertions, 0 deletions
diff --git a/src/plugins/emulator/src/com/motorola/studio/android/emulator/device/ui/StartupOptionsComposite.java b/src/plugins/emulator/src/com/motorola/studio/android/emulator/device/ui/StartupOptionsComposite.java new file mode 100644 index 0000000..b6f3f9c --- /dev/null +++ b/src/plugins/emulator/src/com/motorola/studio/android/emulator/device/ui/StartupOptionsComposite.java @@ -0,0 +1,435 @@ +/* +* 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.device.ui; + +import java.util.List; + +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.fieldassist.ControlDecoration; +import org.eclipse.jface.fieldassist.FieldDecoration; +import org.eclipse.jface.fieldassist.FieldDecorationRegistry; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.DirectoryDialog; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.TabItem; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.PlatformUI; + +import com.motorola.studio.android.emulator.core.skin.IAndroidSkin; +import com.motorola.studio.android.emulator.device.IAndroidDeviceConstants; +import com.motorola.studio.android.emulator.device.instance.options.IStartupOptionsConstants; +import com.motorola.studio.android.emulator.device.instance.options.StartupOption; +import com.motorola.studio.android.emulator.device.instance.options.StartupOptionsGroup; +import com.motorola.studio.android.emulator.device.instance.options.StartupOptionsMgt; +import com.motorola.studio.android.emulator.i18n.EmulatorNLS; + +/** + * DESCRIPTION: + * <br> + * This class implements the UI for showing all Android Emulator Device Instance startup options information. + * <br> + * It extends the AbstractPropertiesComposite so as to use its common functionalities. + * <br> + * RESPONSIBILITY: + * <br> + * - Show Android Emulator Device Instance main information on the UI + * <br> + * COLABORATORS: + * <br> + * AbstractPropertiesComposite: extends this class + * <br> + * USAGE: + * <br> + * This class should be added as a regular composite whenever startup options information on Android Emulator + * Device Instance is necessary to be shown and edited on the UI. + */ +public class StartupOptionsComposite extends AbstractPropertiesComposite implements + IStartupOptionsConstants +{ + // The widget which displays the current command line used to pass the startup options + private Text commandLine; + + private final IAndroidSkin skin; + + private final int TABFOLDER_HEIGHT_HINT = 350; + + private boolean canCalculateScale = true; + + /** + * Creates a StartupOptionsComposite object. + * + * @param parent the parent composite + * @param canCalculateScale + */ + public StartupOptionsComposite(Composite parent, String startupOptions, IAndroidSkin skin, + boolean canCalculateScale) + { + super(parent); + + this.skin = skin; + this.canCalculateScale = canCalculateScale; + StartupOptionsMgt.loadFromCommandLine(startupOptions); + createUI(); + + // Set context Help + PlatformUI.getWorkbench().getHelpSystem() + .setHelp(parent, IAndroidDeviceConstants.STARTUP_OPTIONS_HELP); + } + + /** + * Create widgets for startup options + */ + private void createUI() + { + + Composite mainComposite = this; + Layout mainLayout = new GridLayout(); + mainComposite.setLayout(mainLayout); + + // list of startup options groups + List<StartupOptionsGroup> startupOptionsGroupsList = + StartupOptionsMgt.getStartupOptionsGroupsList(); + + // list of startup options in each group + List<StartupOption> startupOptions = null; + + // Create Tab Folder + final TabFolder tabFolder = new TabFolder(mainComposite, SWT.NULL); + GridData data = new GridData(SWT.FILL, SWT.FILL, true, false); + data.heightHint = TABFOLDER_HEIGHT_HINT; + tabFolder.setLayoutData(data); + + /* + * Iterate through Startup Groups + */ + for (StartupOptionsGroup startupOptionGroup : startupOptionsGroupsList) + { + + // Create Tab Item + TabItem tabItem = new TabItem(tabFolder, SWT.NULL); + tabItem.setText(startupOptionGroup.getTitle()); + Composite group = new Composite(tabFolder, SWT.NULL); + group.setLayout(new GridLayout(3, false)); + group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + tabItem.setControl(group); + + // get startup options in this group + startupOptions = startupOptionGroup.getStartupOptions(); + + /* + * Iterate through Startup Options in this group + */ + for (final StartupOption startupOption : startupOptions) + { + + // create a checkbox for each startup option + Button checkbox = new Button(group, SWT.CHECK); + checkbox.setSelection(startupOption.isChecked()); + checkbox.setText(startupOption.getUserFriendlyName()); + checkbox.setToolTipText(startupOption.getName() + ": " //$NON-NLS-1$ + + startupOption.getDescription()); + startupOption.setCheckedWidget(checkbox); + checkbox.addSelectionListener(new SelectionAdapter() + { + @Override + public void widgetSelected(SelectionEvent e) + { + boolean checkedStatus = ((Button) e.widget).getSelection(); + startupOption.setChecked(checkedStatus); + notifyCompositeChangeListeners(); + } + }); + GridData checkboxData = new GridData(SWT.NULL, SWT.FILL, false, false); + checkbox.setLayoutData(checkboxData); + + // Create input fields depending on the startup option type + switch (startupOption.getType()) + { + case TYPE_NONE: + // extend checkbox area along the line + checkboxData.widthHint = SWT.DEFAULT; + checkboxData.horizontalSpan = 3; + checkbox.setLayoutData(checkboxData); + break; + + case TYPE_TEXT: + case TYPE_NUMBER: + createWidgetsForTextOrNumberType(group, startupOption); + break; + + case TYPE_PATH: + createWidgetsForPathType(group, startupOption); + break; + + default: + // none + + } + } + } + + /* + * Command Line area + */ + Composite commandLineArea = new Composite(mainComposite, SWT.NONE); // composite + commandLineArea.setLayout(new GridLayout(2, false)); + data = new GridData(SWT.FILL, SWT.FILL, true, true); + commandLineArea.setLayoutData(data); + + Label commandLineLabel = new Label(commandLineArea, SWT.NONE); // label + commandLineLabel.setText(""); //$NON-NLS-1$ + data = new GridData(SWT.FILL, SWT.FILL, false, true); + commandLineLabel.setLayoutData(data); + + commandLine = new Text(commandLineArea, SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL); // text + data = new GridData(SWT.FILL, SWT.FILL, true, true); + commandLineArea.pack(); + data.widthHint = commandLineArea.getBounds().width - commandLineLabel.getBounds().width; + data.heightHint = commandLineArea.getBounds().height; + commandLine.setLayoutData(data); + commandLine.setText(StartupOptionsMgt.getParamList()); + commandLine.setEditable(false); + } + + /** + * Create widgets to enable user to input data for fields of text or number type + * + * @param parent composite where the widgets will be attached to + * @param startupOption the corresponding startup option + */ + private void createWidgetsForTextOrNumberType(final Composite parent, + final StartupOption startupOption) + { + // create input text with calc button + if (startupOption.getName().equals(SCALE)) + { + final Text inputText = new Text(parent, SWT.SINGLE | SWT.BORDER); + inputText.setText(startupOption.getValue()); + startupOption.setValueWidget(inputText); + inputText.setLayoutData(new GridData(SWT.FILL, SWT.NULL, true, false)); + inputText.addModifyListener(new ModifyListener() + { + public void modifyText(ModifyEvent e) + { + startupOption.setValue(inputText.getText()); + notifyCompositeChangeListeners(); + } + }); + + Button calc = new Button(parent, SWT.PUSH); + calc.setText(EmulatorNLS.UI_DpiScale_Calculator); + GridData calcData = new GridData(SWT.NULL, SWT.NULL, false, false); + calc.setLayoutData(calcData); + calc.addSelectionListener(new SelectionAdapter() + { + @Override + public void widgetSelected(SelectionEvent e) + { + DpiScaleCalculatorDialog dialog = + new DpiScaleCalculatorDialog(new Shell(parent.getShell()), skin); + if (dialog.open() == Dialog.OK) + { + for (StartupOptionsGroup group : StartupOptionsMgt + .getStartupOptionsGroupsList()) + { + for (StartupOption startupOption : group.getStartupOptions()) + { + if (startupOption.getName().equals(SCALE)) + { + startupOption.setChecked(true); + startupOption.setValue(dialog.getResultScaleValue()); + startupOption.updateUI(); + } + } + } + } + } + }); + calc.setEnabled(canCalculateScale); + if (!canCalculateScale) + { + ControlDecoration controlDecoration = + new ControlDecoration(inputText, SWT.LEFT | SWT.TOP); + controlDecoration + .setDescriptionText(EmulatorNLS.StartupOptionsComposite_Error_Loading_Skin_Cant_Calculate_Scale); + FieldDecoration fieldDecoration = + FieldDecorationRegistry.getDefault().getFieldDecoration( + FieldDecorationRegistry.DEC_WARNING); + controlDecoration.setImage(fieldDecoration.getImage()); + } + } + // create input text + else if ((startupOption.getPreDefinedValues() == null) + || (startupOption.getPreDefinedValues().size() == 0)) + { + final Text inputText = new Text(parent, SWT.SINGLE | SWT.BORDER); + inputText.setText(startupOption.getValue()); + startupOption.setValueWidget(inputText); + inputText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); + inputText.addModifyListener(new ModifyListener() + { + public void modifyText(ModifyEvent e) + { + startupOption.setValue(inputText.getText()); + notifyCompositeChangeListeners(); + } + }); + } + // create combobox + else + { + final Combo combo = new Combo(parent, SWT.READ_ONLY); + startupOption.setValueWidget(combo); + int selectedIndex = 0; + for (String preDefinedValue : startupOption.getPreDefinedValues()) + { + combo.add(preDefinedValue); + if (startupOption.getValue().equals(preDefinedValue)) + { + combo.select(selectedIndex); + } + else + { + selectedIndex++; + } + } + combo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); + combo.addModifyListener(new ModifyListener() + { + public void modifyText(ModifyEvent e) + { + startupOption.setValue(combo.getText()); + notifyCompositeChangeListeners(); + } + }); + } + } + + /** + * Create widgets to enable user to input data for fields of path type + * + * @param parent composite where the widgets will be attached to + * @param startupOption the corresponding startup option + */ + private void createWidgetsForPathType(final Composite parent, final StartupOption startupOption) + { + // create input text + final Text pathText = new Text(parent, SWT.SINGLE | SWT.BORDER); + pathText.setText(startupOption.getValue()); + startupOption.setValueWidget(pathText); + pathText.setLayoutData(new GridData(SWT.FILL, SWT.NULL, true, false)); + pathText.addModifyListener(new ModifyListener() + { + public void modifyText(ModifyEvent e) + { + startupOption.setValue(pathText.getText()); + notifyCompositeChangeListeners(); + } + }); + // create browse button + Button pathBrowseButton = new Button(parent, SWT.PUSH); + pathBrowseButton.setText(EmulatorNLS.UI_General_BrowseButtonLabel); + GridData data = new GridData(SWT.NULL, SWT.NULL, false, false); + pathBrowseButton.setLayoutData(data); + pathBrowseButton.addSelectionListener(new SelectionAdapter() + { + @Override + public void widgetSelected(SelectionEvent e) + { + String selectedPath = null; + + if (startupOption.getTypeDetails().equalsIgnoreCase(TYPE_PATH_DIR)) + { + DirectoryDialog directoryDialog = new DirectoryDialog(getShell(), SWT.OPEN); + selectedPath = directoryDialog.open(); + } + else + { + FileDialog fileDialog = new FileDialog(getShell(), SWT.OPEN); + String[] filterExtensions = + { + "*" + startupOption.getTypeDetails() //$NON-NLS-1$ + }; + fileDialog.setFilterExtensions(filterExtensions); + selectedPath = fileDialog.open(); + } + + if (selectedPath != null) + { + pathText.setText(selectedPath); + } + } + }); + } + + /** + * Update command line value + * + * @see com.motorola.studio.android.emulator.device.ui.AbstractPropertiesComposite#notifyCompositeChangeListeners() + */ + @Override + protected void notifyCompositeChangeListeners() + { + commandLine.setText(StartupOptionsMgt.getParamList()); + super.notifyCompositeChangeListeners(); + } + + /** + * Retrieves the error message associated to this composites current state. + * The order of precedence of error is the same as the fields displayed on the + * UI, which means errors on fields drawn first are shown with a higher precedence + * than the errors of fields drawn last. + * The instance description field is the only non required field. + * + * @return the error message, or <code>null</code> if there are no errors + */ + @Override + public String getErrorMessage() + { + String errMsg = null; + Status status = StartupOptionsMgt.validate(); + if (status.getSeverity() == Status.ERROR) + { + errMsg = status.getMessage(); + } + return errMsg; + } + + /** + * Reload the values being displayed in the UI as well as the ones + * in the model. + * + * @param startupOptions commandLine the command line used to start the emulator + */ + public void reloadValues(String commandLine) + { + StartupOptionsMgt.loadFromCommandLine(commandLine); + } +} |