diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutActionBar.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutActionBar.java | 732 |
1 files changed, 732 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutActionBar.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutActionBar.java new file mode 100644 index 000000000..1b1bd23c4 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutActionBar.java @@ -0,0 +1,732 @@ +/* + * 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.ANDROID_URI; +import static com.android.SdkConstants.ATTR_ID; + +import com.android.annotations.NonNull; +import com.android.ide.common.api.INode; +import com.android.ide.common.api.RuleAction; +import com.android.ide.common.api.RuleAction.Choices; +import com.android.ide.common.api.RuleAction.Separator; +import com.android.ide.common.api.RuleAction.Toggle; +import com.android.ide.common.layout.BaseViewRule; +import com.android.ide.eclipse.adt.internal.editors.IconFactory; +import com.android.ide.eclipse.adt.internal.editors.common.CommonXmlEditor; +import com.android.ide.eclipse.adt.internal.editors.layout.configuration.Configuration; +import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationChooser; +import com.android.ide.eclipse.adt.internal.editors.layout.gre.NodeProxy; +import com.android.ide.eclipse.adt.internal.editors.layout.gre.RulesEngine; +import com.android.ide.eclipse.adt.internal.lint.EclipseLintClient; +import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs; +import com.android.sdklib.devices.Device; +import com.android.sdklib.devices.Screen; +import com.android.sdkuilib.internal.widgets.ResolutionChooserDialog; +import com.google.common.base.Strings; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Toolbar shown at the top of the layout editor, which adds a number of context-sensitive + * layout actions (as well as zooming controls on the right). + */ +public class LayoutActionBar extends Composite { + private GraphicalEditorPart mEditor; + private ToolBar mLayoutToolBar; + private ToolBar mLintToolBar; + private ToolBar mZoomToolBar; + private ToolItem mZoomRealSizeButton; + private ToolItem mZoomOutButton; + private ToolItem mZoomResetButton; + private ToolItem mZoomInButton; + private ToolItem mZoomFitButton; + private ToolItem mLintButton; + private List<RuleAction> mPrevActions; + + /** + * Creates a new {@link LayoutActionBar} and adds it to the given parent. + * + * @param parent the parent composite to add the actions bar to + * @param style the SWT style to apply + * @param editor the associated layout editor + */ + public LayoutActionBar(Composite parent, int style, GraphicalEditorPart editor) { + super(parent, style | SWT.NO_FOCUS); + mEditor = editor; + + GridLayout layout = new GridLayout(3, false); + setLayout(layout); + + mLayoutToolBar = new ToolBar(this, /*SWT.WRAP |*/ SWT.FLAT | SWT.RIGHT | SWT.HORIZONTAL); + mLayoutToolBar.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false)); + mZoomToolBar = createZoomControls(); + mZoomToolBar.setLayoutData(new GridData(SWT.END, SWT.BEGINNING, false, false)); + mLintToolBar = createLintControls(); + + GridData lintData = new GridData(SWT.END, SWT.BEGINNING, false, false); + lintData.exclude = true; + mLintToolBar.setLayoutData(lintData); + } + + @Override + public void dispose() { + super.dispose(); + mPrevActions = null; + } + + /** Updates the layout contents based on the current selection */ + void updateSelection() { + NodeProxy parent = null; + LayoutCanvas canvas = mEditor.getCanvasControl(); + SelectionManager selectionManager = canvas.getSelectionManager(); + List<SelectionItem> selections = selectionManager.getSelections(); + if (selections.size() > 0) { + // TODO: better handle multi-selection -- maybe we should disable it or + // something. + // What if you select children with different parents? Of different types? + // etc. + NodeProxy node = selections.get(0).getNode(); + if (node != null && node.getParent() != null) { + parent = (NodeProxy) node.getParent(); + } + } + + if (parent == null) { + // Show the background's properties + CanvasViewInfo root = canvas.getViewHierarchy().getRoot(); + if (root == null) { + return; + } + parent = canvas.getNodeFactory().create(root); + selections = Collections.emptyList(); + } + + RulesEngine engine = mEditor.getRulesEngine(); + List<NodeProxy> selectedNodes = new ArrayList<NodeProxy>(); + for (SelectionItem item : selections) { + selectedNodes.add(item.getNode()); + } + List<RuleAction> actions = new ArrayList<RuleAction>(); + engine.callAddLayoutActions(actions, parent, selectedNodes); + + // Place actions in the correct order (the actions may come from different + // rules and should be merged properly via sorting keys) + Collections.sort(actions); + + // Add in actions for the child as well, if there is exactly one. + // These are not merged into the parent list of actions; they are appended + // at the end. + int index = -1; + String label = null; + if (selectedNodes.size() == 1) { + List<RuleAction> itemActions = new ArrayList<RuleAction>(); + NodeProxy selectedNode = selectedNodes.get(0); + engine.callAddLayoutActions(itemActions, selectedNode, null); + if (itemActions.size() > 0) { + Collections.sort(itemActions); + + if (!(itemActions.get(0) instanceof RuleAction.Separator)) { + actions.add(RuleAction.createSeparator(0)); + } + label = selectedNode.getStringAttr(ANDROID_URI, ATTR_ID); + if (label != null) { + label = BaseViewRule.stripIdPrefix(label); + index = actions.size(); + } + actions.addAll(itemActions); + } + } + + if (!updateActions(actions)) { + updateToolbar(actions, index, label); + } + mPrevActions = actions; + } + + /** Update the toolbar widgets */ + private void updateToolbar(final List<RuleAction> actions, final int labelIndex, + final String label) { + if (mLayoutToolBar == null || mLayoutToolBar.isDisposed()) { + return; + } + for (ToolItem c : mLayoutToolBar.getItems()) { + c.dispose(); + } + mLayoutToolBar.pack(); + addActions(actions, labelIndex, label); + mLayoutToolBar.pack(); + mLayoutToolBar.layout(); + } + + /** + * Attempts to update the existing toolbar actions, if the action list is + * similar to the current list. Returns false if this cannot be done and the + * contents must be replaced. + */ + private boolean updateActions(@NonNull List<RuleAction> actions) { + List<RuleAction> before = mPrevActions; + List<RuleAction> after = actions; + + if (before == null) { + return false; + } + + if (!before.equals(after) || after.size() > mLayoutToolBar.getItemCount()) { + return false; + } + + int actionIndex = 0; + for (int i = 0, max = mLayoutToolBar.getItemCount(); i < max; i++) { + ToolItem item = mLayoutToolBar.getItem(i); + int style = item.getStyle(); + Object data = item.getData(); + if (data != null) { + // One action can result in multiple toolbar items (e.g. a choice action + // can result in multiple radio buttons), so we've have to replace all of + // them with the corresponding new action + RuleAction prevAction = before.get(actionIndex); + while (prevAction != data) { + actionIndex++; + if (actionIndex == before.size()) { + return false; + } + prevAction = before.get(actionIndex); + if (prevAction == data) { + break; + } else if (!(prevAction instanceof RuleAction.Separator)) { + return false; + } + } + RuleAction newAction = after.get(actionIndex); + assert newAction.equals(prevAction); // Maybe I can do this lazily instead? + + // Update action binding to the new action + item.setData(newAction); + + // Sync button states: the checked state is not considered part of + // RuleAction equality + if ((style & SWT.CHECK) != 0) { + assert newAction instanceof Toggle; + Toggle toggle = (Toggle) newAction; + item.setSelection(toggle.isChecked()); + } else if ((style & SWT.RADIO) != 0) { + assert newAction instanceof Choices; + Choices choices = (Choices) newAction; + String current = choices.getCurrent(); + String id = (String) item.getData(ATTR_ID); + boolean selected = Strings.nullToEmpty(current).equals(id); + item.setSelection(selected); + } + } else { + // Must be a separator, or a label (which we insert for nested widgets) + assert (style & SWT.SEPARATOR) != 0 || !item.getText().isEmpty() : item; + } + } + + return true; + } + + private void addActions(List<RuleAction> actions, int labelIndex, String label) { + if (actions.size() > 0) { + // Flag used to indicate that if there are any actions -after- this, it + // should be separated from this current action (we don't unconditionally + // add a separator at the end of these groups in case there are no more + // actions at the end so that we don't have a trailing separator) + boolean needSeparator = false; + + int index = 0; + for (RuleAction action : actions) { + if (index == labelIndex) { + final ToolItem button = new ToolItem(mLayoutToolBar, SWT.PUSH); + button.setText(label); + needSeparator = false; + } + index++; + + if (action instanceof Separator) { + addSeparator(mLayoutToolBar); + needSeparator = false; + continue; + } else if (needSeparator) { + addSeparator(mLayoutToolBar); + needSeparator = false; + } + + if (action instanceof RuleAction.Choices) { + RuleAction.Choices choices = (Choices) action; + if (!choices.isRadio()) { + addDropdown(choices); + } else { + addSeparator(mLayoutToolBar); + addRadio(choices); + needSeparator = true; + } + } else if (action instanceof RuleAction.Toggle) { + addToggle((Toggle) action); + } else { + addPlainAction(action); + } + } + } + } + + /** Add a separator to the toolbar, unless there already is one there at the end already */ + private static void addSeparator(ToolBar toolBar) { + int n = toolBar.getItemCount(); + if (n > 0 && (toolBar.getItem(n - 1).getStyle() & SWT.SEPARATOR) == 0) { + ToolItem separator = new ToolItem(toolBar, SWT.SEPARATOR); + separator.setWidth(15); + } + } + + private void addToggle(Toggle toggle) { + final ToolItem button = new ToolItem(mLayoutToolBar, SWT.CHECK); + + URL iconUrl = toggle.getIconUrl(); + String title = toggle.getTitle(); + if (iconUrl != null) { + button.setImage(IconFactory.getInstance().getIcon(iconUrl)); + button.setToolTipText(title); + } else { + button.setText(title); + } + button.setData(toggle); + + button.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + Toggle toggle = (Toggle) button.getData(); + toggle.getCallback().action(toggle, getSelectedNodes(), + toggle.getId(), button.getSelection()); + updateSelection(); + } + }); + if (toggle.isChecked()) { + button.setSelection(true); + } + } + + private List<INode> getSelectedNodes() { + List<SelectionItem> selections = + mEditor.getCanvasControl().getSelectionManager().getSelections(); + List<INode> nodes = new ArrayList<INode>(selections.size()); + for (SelectionItem item : selections) { + nodes.add(item.getNode()); + } + + return nodes; + } + + + private void addPlainAction(RuleAction menuAction) { + final ToolItem button = new ToolItem(mLayoutToolBar, SWT.PUSH); + + URL iconUrl = menuAction.getIconUrl(); + String title = menuAction.getTitle(); + if (iconUrl != null) { + button.setImage(IconFactory.getInstance().getIcon(iconUrl)); + button.setToolTipText(title); + } else { + button.setText(title); + } + button.setData(menuAction); + + button.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + RuleAction menuAction = (RuleAction) button.getData(); + menuAction.getCallback().action(menuAction, getSelectedNodes(), menuAction.getId(), + false); + updateSelection(); + } + }); + } + + private void addRadio(RuleAction.Choices choices) { + List<URL> icons = choices.getIconUrls(); + List<String> titles = choices.getTitles(); + List<String> ids = choices.getIds(); + String current = choices.getCurrent() != null ? choices.getCurrent() : ""; //$NON-NLS-1$ + + assert icons != null; + assert icons.size() == titles.size(); + + for (int i = 0; i < icons.size(); i++) { + URL iconUrl = icons.get(i); + String title = titles.get(i); + final String id = ids.get(i); + final ToolItem item = new ToolItem(mLayoutToolBar, SWT.RADIO); + item.setToolTipText(title); + item.setImage(IconFactory.getInstance().getIcon(iconUrl)); + item.setData(choices); + item.setData(ATTR_ID, id); + item.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (item.getSelection()) { + RuleAction.Choices choices = (Choices) item.getData(); + choices.getCallback().action(choices, getSelectedNodes(), id, null); + updateSelection(); + } + } + }); + boolean selected = current.equals(id); + if (selected) { + item.setSelection(true); + } + } + } + + private void addDropdown(RuleAction.Choices choices) { + final ToolItem combo = new ToolItem(mLayoutToolBar, SWT.DROP_DOWN); + URL iconUrl = choices.getIconUrl(); + if (iconUrl != null) { + combo.setImage(IconFactory.getInstance().getIcon(iconUrl)); + combo.setToolTipText(choices.getTitle()); + } else { + combo.setText(choices.getTitle()); + } + combo.setData(choices); + + Listener menuListener = new Listener() { + @Override + public void handleEvent(Event event) { + Menu menu = new Menu(mLayoutToolBar.getShell(), SWT.POP_UP); + RuleAction.Choices choices = (Choices) combo.getData(); + List<URL> icons = choices.getIconUrls(); + List<String> titles = choices.getTitles(); + List<String> ids = choices.getIds(); + String current = choices.getCurrent() != null ? choices.getCurrent() : ""; //$NON-NLS-1$ + + for (int i = 0; i < titles.size(); i++) { + String title = titles.get(i); + final String id = ids.get(i); + URL itemIconUrl = icons != null && icons.size() > 0 ? icons.get(i) : null; + MenuItem item = new MenuItem(menu, SWT.CHECK); + item.setText(title); + if (itemIconUrl != null) { + Image itemIcon = IconFactory.getInstance().getIcon(itemIconUrl); + item.setImage(itemIcon); + } + + boolean selected = id.equals(current); + if (selected) { + item.setSelection(true); + } + + item.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + RuleAction.Choices choices = (Choices) combo.getData(); + choices.getCallback().action(choices, getSelectedNodes(), id, null); + updateSelection(); + } + }); + } + + Rectangle bounds = combo.getBounds(); + Point location = new Point(bounds.x, bounds.y + bounds.height); + location = combo.getParent().toDisplay(location); + menu.setLocation(location.x, location.y); + menu.setVisible(true); + } + }; + combo.addListener(SWT.Selection, menuListener); + } + + // ---- Zoom Controls ---- + + @SuppressWarnings("unused") // SWT constructors have side effects, they are not unused + private ToolBar createZoomControls() { + ToolBar toolBar = new ToolBar(this, SWT.FLAT | SWT.RIGHT | SWT.HORIZONTAL); + + IconFactory iconFactory = IconFactory.getInstance(); + mZoomRealSizeButton = new ToolItem(toolBar, SWT.CHECK); + mZoomRealSizeButton.setToolTipText("Emulate Real Size"); + mZoomRealSizeButton.setImage(iconFactory.getIcon("zoomreal")); //$NON-NLS-1$); + mZoomRealSizeButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + boolean newState = mZoomRealSizeButton.getSelection(); + if (rescaleToReal(newState)) { + mZoomOutButton.setEnabled(!newState); + mZoomResetButton.setEnabled(!newState); + mZoomInButton.setEnabled(!newState); + mZoomFitButton.setEnabled(!newState); + } else { + mZoomRealSizeButton.setSelection(!newState); + } + } + }); + + mZoomFitButton = new ToolItem(toolBar, SWT.PUSH); + mZoomFitButton.setToolTipText("Zoom to Fit (0)"); + mZoomFitButton.setImage(iconFactory.getIcon("zoomfit")); //$NON-NLS-1$); + mZoomFitButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + rescaleToFit(true); + } + }); + + mZoomResetButton = new ToolItem(toolBar, SWT.PUSH); + mZoomResetButton.setToolTipText("Reset Zoom to 100% (1)"); + mZoomResetButton.setImage(iconFactory.getIcon("zoom100")); //$NON-NLS-1$); + mZoomResetButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + resetScale(); + } + }); + + // Group zoom in/out separately + new ToolItem(toolBar, SWT.SEPARATOR); + + mZoomOutButton = new ToolItem(toolBar, SWT.PUSH); + mZoomOutButton.setToolTipText("Zoom Out (-)"); + mZoomOutButton.setImage(iconFactory.getIcon("zoomminus")); //$NON-NLS-1$); + mZoomOutButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + rescale(-1); + } + }); + + mZoomInButton = new ToolItem(toolBar, SWT.PUSH); + mZoomInButton.setToolTipText("Zoom In (+)"); + mZoomInButton.setImage(iconFactory.getIcon("zoomplus")); //$NON-NLS-1$); + mZoomInButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + rescale(+1); + } + }); + + return toolBar; + } + + @SuppressWarnings("unused") // SWT constructors have side effects, they are not unused + private ToolBar createLintControls() { + ToolBar toolBar = new ToolBar(this, SWT.FLAT | SWT.RIGHT | SWT.HORIZONTAL); + + // Separate from adjacent toolbar + new ToolItem(toolBar, SWT.SEPARATOR); + + ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages(); + mLintButton = new ToolItem(toolBar, SWT.PUSH); + mLintButton.setToolTipText("Show Lint Warnings for this Layout"); + mLintButton.setImage(sharedImages.getImage(ISharedImages.IMG_OBJS_WARN_TSK)); + mLintButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + CommonXmlEditor editor = mEditor.getEditorDelegate().getEditor(); + IFile file = editor.getInputFile(); + if (file != null) { + EclipseLintClient.showErrors(getShell(), file, editor); + } + } + }); + + return toolBar; + } + + /** + * Updates the lint indicator state in the given layout editor + */ + public void updateErrorIndicator() { + updateErrorIndicator(mEditor.getEditedFile()); + } + + /** + * Updates the lint indicator state for the given file + * + * @param file the file to show the indicator status for + */ + public void updateErrorIndicator(IFile file) { + IMarker[] markers = EclipseLintClient.getMarkers(file); + updateErrorIndicator(markers.length); + } + + /** + * Sets whether the action bar should show the "lint warnings" button + * + * @param hasLintWarnings whether there are lint errors to be shown + */ + private void updateErrorIndicator(final int markerCount) { + Display display = getDisplay(); + if (display.getThread() != Thread.currentThread()) { + display.asyncExec(new Runnable() { + @Override + public void run() { + if (!isDisposed()) { + updateErrorIndicator(markerCount); + } + } + }); + return; + } + + GridData layoutData = (GridData) mLintToolBar.getLayoutData(); + Integer existing = (Integer) mLintToolBar.getData(); + Integer current = Integer.valueOf(markerCount); + if (!current.equals(existing)) { + mLintToolBar.setData(current); + boolean layout = false; + boolean hasLintWarnings = markerCount > 0 && AdtPrefs.getPrefs().isLintOnSave(); + if (layoutData.exclude == hasLintWarnings) { + layoutData.exclude = !hasLintWarnings; + mLintToolBar.setVisible(hasLintWarnings); + layout = true; + } + if (markerCount > 0) { + String iconName = ""; + switch (markerCount) { + case 1: iconName = "lint1"; break; //$NON-NLS-1$ + case 2: iconName = "lint2"; break; //$NON-NLS-1$ + case 3: iconName = "lint3"; break; //$NON-NLS-1$ + case 4: iconName = "lint4"; break; //$NON-NLS-1$ + case 5: iconName = "lint5"; break; //$NON-NLS-1$ + case 6: iconName = "lint6"; break; //$NON-NLS-1$ + case 7: iconName = "lint7"; break; //$NON-NLS-1$ + case 8: iconName = "lint8"; break; //$NON-NLS-1$ + case 9: iconName = "lint9"; break; //$NON-NLS-1$ + default: iconName = "lint9p"; break;//$NON-NLS-1$ + } + mLintButton.setImage(IconFactory.getInstance().getIcon(iconName)); + } + if (layout) { + layout(); + } + redraw(); + } + } + + /** + * Returns true if zooming in/out/to-fit/etc is allowed (which is not the case while + * emulating real size) + * + * @return true if zooming is allowed + */ + boolean isZoomingAllowed() { + return mZoomInButton.isEnabled(); + } + + boolean isZoomingRealSize() { + return mZoomRealSizeButton.getSelection(); + } + + /** + * Rescales canvas. + * @param direction +1 for zoom in, -1 for zoom out + */ + void rescale(int direction) { + LayoutCanvas canvas = mEditor.getCanvasControl(); + double s = canvas.getScale(); + + if (direction > 0) { + s = s * 1.2; + } else { + s = s / 1.2; + } + + // Some operations are faster if the zoom is EXACTLY 1.0 rather than ALMOST 1.0. + // (This is because there is a fast-path when image copying and the scale is 1.0; + // in that case it does not have to do any scaling). + // + // If you zoom out 10 times and then back in 10 times, small rounding errors mean + // that you end up with a scale=1.0000000000000004. In the cases, when you get close + // to 1.0, just make the zoom an exact 1.0. + if (Math.abs(s-1.0) < 0.0001) { + s = 1.0; + } + + canvas.setScale(s, true /*redraw*/); + } + + /** + * Reset the canvas scale to 100% + */ + void resetScale() { + mEditor.getCanvasControl().setScale(1, true /*redraw*/); + } + + /** + * Reset the canvas scale to best fit (so content is as large as possible without scrollbars) + */ + void rescaleToFit(boolean onlyZoomOut) { + mEditor.getCanvasControl().setFitScale(onlyZoomOut, true /*allowZoomIn*/); + } + + boolean rescaleToReal(boolean real) { + if (real) { + return computeAndSetRealScale(true /*redraw*/); + } else { + // reset the scale to 100% + mEditor.getCanvasControl().setScale(1, true /*redraw*/); + return true; + } + } + + boolean computeAndSetRealScale(boolean redraw) { + // compute average dpi of X and Y + ConfigurationChooser chooser = mEditor.getConfigurationChooser(); + Configuration config = chooser.getConfiguration(); + Device device = config.getDevice(); + Screen screen = device.getDefaultHardware().getScreen(); + double dpi = (screen.getXdpi() + screen.getYdpi()) / 2.; + + // get the monitor dpi + float monitor = AdtPrefs.getPrefs().getMonitorDensity(); + if (monitor == 0.f) { + ResolutionChooserDialog dialog = new ResolutionChooserDialog(chooser.getShell()); + if (dialog.open() == Window.OK) { + monitor = dialog.getDensity(); + AdtPrefs.getPrefs().setMonitorDensity(monitor); + } else { + return false; + } + } + + mEditor.getCanvasControl().setScale(monitor / dpi, redraw); + return true; + } +} |