diff options
Diffstat (limited to 'hierarchyviewer2/app/src/com/android')
24 files changed, 2421 insertions, 81 deletions
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/AboutDialog.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/AboutDialog.java new file mode 100644 index 0000000..54edbc8 --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/AboutDialog.java @@ -0,0 +1,72 @@ +/* + * 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.hierarchyviewer; + +import com.android.ddmuilib.ImageLoader; +import com.android.hierarchyviewerlib.HierarchyViewerDirector; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +public class AboutDialog extends Dialog { + private Image aboutImage; + + private Image smallImage; + + public AboutDialog(Shell shell) { + super(shell); + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + smallImage = imageLoader.loadImage("load-view-hierarchy.png", Display.getDefault()); + aboutImage = imageLoader.loadImage("about.jpg", Display.getDefault()); + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite control = new Composite(parent, SWT.NONE); + control.setLayout(new GridLayout(2, true)); + Composite imageControl = new Composite(control, SWT.BORDER); + imageControl.setLayout(new FillLayout()); + imageControl.setLayoutData(new GridData(GridData.FILL_VERTICAL)); + Label imageLabel = new Label(imageControl, SWT.CENTER); + imageLabel.setImage(aboutImage); + + CLabel textLabel = new CLabel(control, SWT.NONE); + textLabel + .setText("Hierarchy Viewer\nCopyright 2010, The Android Open Source Project\nAll Rights Reserved."); + textLabel.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, true, true)); + getShell().setText("About..."); + getShell().setImage(smallImage); + return control; + + } +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java index c3538dc..c967d6b 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java @@ -16,27 +16,1201 @@ package com.android.hierarchyviewer; -import com.android.hierarchyviewerlib.ComponentRegistry; +import com.android.ddmlib.IDevice; +import com.android.ddmuilib.ImageLoader; +import com.android.hierarchyviewer.actions.AboutAction; +import com.android.hierarchyviewer.actions.CapturePSDAction; +import com.android.hierarchyviewer.actions.DisplayViewAction; +import com.android.hierarchyviewer.actions.InspectScreenshotAction; +import com.android.hierarchyviewer.actions.InvalidateAction; +import com.android.hierarchyviewer.actions.LoadAllViewsAction; +import com.android.hierarchyviewer.actions.LoadOverlayAction; +import com.android.hierarchyviewer.actions.LoadViewHierarchyAction; +import com.android.hierarchyviewer.actions.PixelPerfectAutoRefreshAction; +import com.android.hierarchyviewer.actions.QuitAction; +import com.android.hierarchyviewer.actions.RefreshPixelPerfectAction; +import com.android.hierarchyviewer.actions.RefreshPixelPerfectTreeAction; +import com.android.hierarchyviewer.actions.RefreshViewAction; +import com.android.hierarchyviewer.actions.RefreshWindowsAction; +import com.android.hierarchyviewer.actions.RequestLayoutAction; +import com.android.hierarchyviewer.actions.SavePixelPerfectAction; +import com.android.hierarchyviewer.actions.SaveTreeViewAction; +import com.android.hierarchyviewer.actions.ShowOverlayAction; +import com.android.hierarchyviewer.util.ActionButton; import com.android.hierarchyviewerlib.HierarchyViewerDirector; +import com.android.hierarchyviewerlib.device.Window; import com.android.hierarchyviewerlib.models.DeviceSelectionModel; import com.android.hierarchyviewerlib.models.PixelPerfectModel; import com.android.hierarchyviewerlib.models.TreeViewModel; +import com.android.hierarchyviewerlib.models.DeviceSelectionModel.WindowChangeListener; +import com.android.hierarchyviewerlib.models.PixelPerfectModel.ImageChangeListener; +import com.android.hierarchyviewerlib.models.TreeViewModel.TreeChangeListener; +import com.android.hierarchyviewerlib.ui.DeviceSelector; +import com.android.hierarchyviewerlib.ui.LayoutViewer; +import com.android.hierarchyviewerlib.ui.PixelPerfect; +import com.android.hierarchyviewerlib.ui.PixelPerfectLoupe; +import com.android.hierarchyviewerlib.ui.PixelPerfectPixelPanel; +import com.android.hierarchyviewerlib.ui.PixelPerfectTree; +import com.android.hierarchyviewerlib.ui.PropertyViewer; +import com.android.hierarchyviewerlib.ui.TreeView; +import com.android.hierarchyviewerlib.ui.TreeViewOverview; -public class HierarchyViewerApplication { - public static void main(String[] args) { - HierarchyViewerDirector director = new HierarchyViewerApplicationDirector(); - ComponentRegistry.setDirector(director); - ComponentRegistry.setDeviceSelectionModel(new DeviceSelectionModel()); - ComponentRegistry.setPixelPerfectModel(new PixelPerfectModel()); - ComponentRegistry.setTreeViewModel(new TreeViewModel()); +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.window.ApplicationWindow; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.custom.StackLayout; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.ProgressBar; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Slider; +import org.eclipse.swt.widgets.Text; + +public class HierarchyViewerApplication extends ApplicationWindow { + + private static final int INITIAL_WIDTH = 1024; + + private static final int INITIAL_HEIGHT = 768; + + private static HierarchyViewerApplication APP; + + private Image deviceViewImage; + + private Image pixelPerfectImage; + + private Image treeViewImage; + + private Image deviceViewSelectedImage; + + private Image pixelPerfectSelectedImage; + + private Image treeViewSelectedImage; + + private Button treeViewButton; + + private Button pixelPerfectButton; + + private Button deviceViewButton; + + private Label progressLabel; + + private ProgressBar progressBar; + + private String progressString; + + private Composite deviceSelectorPanel; + + private Composite treeViewPanel; + + private Composite pixelPerfectPanel; + + private StackLayout mainWindowStackLayout; + + private DeviceSelector deviceSelector; + + private Composite statusBar; + + private TreeView treeView; + + private Composite mainWindow; + + private Image onBlackImage; + + private Image onWhiteImage; + + private Button onBlackWhiteButton; + + private Button showExtras; + + private LayoutViewer layoutViewer; + + private StackLayout statusBarStackLayout; + + private Composite treeViewControls; + + private Slider zoomSlider; + + private Text filterText; + + private Composite statusBarControlPanel; + + private PixelPerfectLoupe pixelPerfectLoupe; + + private boolean autoRefresh = false; + + private int refreshInterval = 5; + + private int refreshTimeLeft = 5; + + private Slider overlaySlider; + + private Slider ppZoomSlider; + + private Slider refreshSlider; + + public static final HierarchyViewerApplication getApp() { + return APP; + } + + public HierarchyViewerApplication() { + super(null); + + APP = this; + + addMenuBar(); + } + + @Override + protected void configureShell(Shell shell) { + super.configureShell(shell); + shell.setText("Hierarchy Viewer"); + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + Image image = imageLoader.loadImage("load-view-hierarchy.png", Display.getDefault()); + shell.setImage(image); + } + + @Override + public MenuManager createMenuManager() { + return new MenuManager(); + } + + public void run() { + HierarchyViewerDirector director = HierarchyViewerApplicationDirector.createDirector(); director.initDebugBridge(); director.startListenForDevices(); director.populateDeviceSelectionModel(); + DeviceSelectionModel.getModel().addWindowChangeListener(windowChangeListener); + TreeViewModel.getModel().addTreeChangeListener(treeChangeListener); + PixelPerfectModel.getModel().addImageChangeListener(imageChangeListener); + + setBlockOnOpen(true); + + Thread pixelPerfectRefreshingThread = new Thread(autoRefresher); + pixelPerfectRefreshingThread.start(); - UIThread.runUI(); + open(); + + pixelPerfectRefreshingThread.interrupt(); + + DeviceSelectionModel.getModel().removeWindowChangeListener(windowChangeListener); + TreeViewModel.getModel().removeTreeChangeListener(treeChangeListener); + PixelPerfectModel.getModel().removeImageChangeListener(imageChangeListener); + + Display.getCurrent().dispose(); + ImageLoader.dispose(); director.stopListenForDevices(); director.stopDebugBridge(); director.terminate(); + } + + @Override + protected void initializeBounds() { + Rectangle monitorArea = Display.getDefault().getPrimaryMonitor().getBounds(); + getShell().setSize(Math.min(monitorArea.width, INITIAL_WIDTH), + Math.min(monitorArea.height, INITIAL_HEIGHT)); + getShell().setLocation(monitorArea.x + (monitorArea.width - INITIAL_WIDTH) / 2, + monitorArea.y + (monitorArea.height - INITIAL_HEIGHT) / 2); + } + + private void loadResources() { + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + treeViewImage = imageLoader.loadImage("tree-view.png", Display.getDefault()); + treeViewSelectedImage = + imageLoader.loadImage("tree-view-selected.png", Display.getDefault()); + pixelPerfectImage = imageLoader.loadImage("pixel-perfect-view.png", Display.getDefault()); + pixelPerfectSelectedImage = + imageLoader.loadImage("pixel-perfect-view-selected.png", Display.getDefault()); + deviceViewImage = imageLoader.loadImage("device-view.png", Display.getDefault()); + deviceViewSelectedImage = + imageLoader.loadImage("device-view-selected.png", Display.getDefault()); + onBlackImage = imageLoader.loadImage("on-black.png", Display.getDefault()); + onWhiteImage = imageLoader.loadImage("on-white.png", Display.getDefault()); + } + + @Override + protected Control createContents(Composite parent) { + loadResources(); + + Composite control = new Composite(parent, SWT.NONE); + GridLayout mainLayout = new GridLayout(); + mainLayout.marginHeight = mainLayout.marginWidth = 0; + mainLayout.verticalSpacing = mainLayout.horizontalSpacing = 0; + control.setLayout(mainLayout); + mainWindow = new Composite(control, SWT.NONE); + mainWindow.setLayoutData(new GridData(GridData.FILL_BOTH)); + mainWindowStackLayout = new StackLayout(); + mainWindow.setLayout(mainWindowStackLayout); + + buildDeviceSelectorPanel(mainWindow); + buildTreeViewPanel(mainWindow); + buildPixelPerfectPanel(mainWindow); + + buildStatusBar(control); + + showDeviceSelector(); + + return control; + } + + private void buildStatusBar(Composite parent) { + statusBar = new Composite(parent, SWT.NONE); + statusBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + FormLayout statusBarLayout = new FormLayout(); + statusBarLayout.marginHeight = statusBarLayout.marginWidth = 2; + + statusBar.setLayout(statusBarLayout); + + deviceViewButton = new Button(statusBar, SWT.TOGGLE); + deviceViewButton.setImage(deviceViewImage); + deviceViewButton.setToolTipText("Switch to the window selection view"); + deviceViewButton.addSelectionListener(deviceViewButtonSelectionListener); + FormData deviceViewButtonFormData = new FormData(); + deviceViewButtonFormData.left = new FormAttachment(); + deviceViewButton.setLayoutData(deviceViewButtonFormData); + + treeViewButton = new Button(statusBar, SWT.TOGGLE); + treeViewButton.setImage(treeViewImage); + treeViewButton.setEnabled(false); + treeViewButton.setToolTipText("Switch to the tree view"); + treeViewButton.addSelectionListener(treeViewButtonSelectionListener); + FormData treeViewButtonFormData = new FormData(); + treeViewButtonFormData.left = new FormAttachment(deviceViewButton, 2); + treeViewButton.setLayoutData(treeViewButtonFormData); + + pixelPerfectButton = new Button(statusBar, SWT.TOGGLE); + pixelPerfectButton.setImage(pixelPerfectImage); + pixelPerfectButton.setEnabled(false); + pixelPerfectButton.setToolTipText("Switch to the pixel perfect view"); + pixelPerfectButton.addSelectionListener(pixelPerfectButtonSelectionListener); + FormData pixelPerfectButtonFormData = new FormData(); + pixelPerfectButtonFormData.left = new FormAttachment(treeViewButton, 2); + pixelPerfectButton.setLayoutData(pixelPerfectButtonFormData); + + // Control panel should go here. + statusBarControlPanel = new Composite(statusBar, SWT.NONE); + FormData statusBarControlPanelFormData = new FormData(); + statusBarControlPanelFormData.left = new FormAttachment(pixelPerfectButton, 2); + statusBarControlPanelFormData.top = new FormAttachment(treeViewButton, 0, SWT.CENTER); + statusBarControlPanel.setLayoutData(statusBarControlPanelFormData); + + // Label should go on top + progressLabel = new Label(statusBar, SWT.RIGHT); + + progressBar = new ProgressBar(statusBar, SWT.HORIZONTAL | SWT.INDETERMINATE | SWT.SMOOTH); + FormData progressBarFormData = new FormData(); + progressBarFormData.right = new FormAttachment(100, 0); + progressBarFormData.top = new FormAttachment(treeViewButton, 0, SWT.CENTER); + progressBar.setLayoutData(progressBarFormData); + + FormData progressLabelFormData = new FormData(); + progressLabelFormData.right = new FormAttachment(progressBar, -2); + progressLabelFormData.top = new FormAttachment(treeViewButton, 0, SWT.CENTER); + progressLabel.setLayoutData(progressLabelFormData); + + if (progressString == null) { + progressLabel.setVisible(false); + progressBar.setVisible(false); + } else { + progressLabel.setText(progressString); + } + + statusBarStackLayout = new StackLayout(); + statusBarControlPanel.setLayout(statusBarStackLayout); + + treeViewControls = new Composite(statusBarControlPanel, SWT.NONE); + GridLayout treeViewControlLayout = new GridLayout(5, false); + treeViewControlLayout.marginWidth = treeViewControlLayout.marginHeight = 2; + treeViewControlLayout.verticalSpacing = treeViewControlLayout.horizontalSpacing = 4; + treeViewControls.setLayout(treeViewControlLayout); + + Label filterLabel = new Label(treeViewControls, SWT.NONE); + filterLabel.setText("Filter by class or id:"); + filterLabel.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, true)); + + filterText = new Text(treeViewControls, SWT.LEFT | SWT.SINGLE); + GridData filterTextGridData = new GridData(GridData.FILL_HORIZONTAL); + filterTextGridData.widthHint = 148; + filterText.setLayoutData(filterTextGridData); + filterText.addModifyListener(filterTextModifyListener); + + Label smallZoomLabel = new Label(treeViewControls, SWT.NONE); + smallZoomLabel.setText(" 20%"); + smallZoomLabel + .setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, true)); + + zoomSlider = new Slider(treeViewControls, SWT.HORIZONTAL); + GridData zoomSliderGridData = new GridData(GridData.CENTER, GridData.CENTER, false, false); + zoomSliderGridData.widthHint = 190; + zoomSlider.setLayoutData(zoomSliderGridData); + zoomSlider.setMinimum((int) (TreeViewModel.MIN_ZOOM * 10)); + zoomSlider.setMaximum((int) (TreeViewModel.MAX_ZOOM * 10 + 1)); + zoomSlider.setThumb(1); + zoomSlider.setSelection(10); + + zoomSlider.addSelectionListener(zoomSliderSelectionListener); + + Label largeZoomLabel = new Label(treeViewControls, SWT.NONE); + largeZoomLabel + .setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, true)); + largeZoomLabel.setText("200%"); + } + + private void buildDeviceSelectorPanel(Composite parent) { + deviceSelectorPanel = new Composite(parent, SWT.NONE); + GridLayout gridLayout = new GridLayout(); + gridLayout.marginWidth = gridLayout.marginHeight = 0; + gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0; + deviceSelectorPanel.setLayout(gridLayout); + + Composite buttonPanel = new Composite(deviceSelectorPanel, SWT.NONE); + buttonPanel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + GridLayout buttonLayout = new GridLayout(); + buttonLayout.marginWidth = buttonLayout.marginHeight = 0; + buttonLayout.horizontalSpacing = buttonLayout.verticalSpacing = 0; + buttonPanel.setLayout(buttonLayout); + + Composite innerButtonPanel = new Composite(buttonPanel, SWT.NONE); + innerButtonPanel.setLayoutData(new GridData(GridData.FILL_VERTICAL)); + GridLayout innerButtonPanelLayout = new GridLayout(3, true); + innerButtonPanelLayout.marginWidth = innerButtonPanelLayout.marginHeight = 2; + innerButtonPanelLayout.horizontalSpacing = innerButtonPanelLayout.verticalSpacing = 2; + innerButtonPanel.setLayout(innerButtonPanelLayout); + + ActionButton refreshWindows = + new ActionButton(innerButtonPanel, RefreshWindowsAction.getAction()); + refreshWindows.setLayoutData(new GridData(GridData.FILL_BOTH)); + + ActionButton loadViewHierarchyButton = + new ActionButton(innerButtonPanel, LoadViewHierarchyAction.getAction()); + loadViewHierarchyButton.setLayoutData(new GridData(GridData.FILL_BOTH)); + LoadViewHierarchyAction.getAction().setEnabled(false); + + ActionButton inspectScreenshotButton = + new ActionButton(innerButtonPanel, InspectScreenshotAction.getAction()); + inspectScreenshotButton.setLayoutData(new GridData(GridData.FILL_BOTH)); + InspectScreenshotAction.getAction().setEnabled(false); + + Composite deviceSelectorContainer = new Composite(deviceSelectorPanel, SWT.BORDER); + deviceSelectorContainer.setLayoutData(new GridData(GridData.FILL_BOTH)); + deviceSelectorContainer.setLayout(new FillLayout()); + deviceSelector = new DeviceSelector(deviceSelectorContainer); + } + + public void buildTreeViewPanel(Composite parent) { + treeViewPanel = new Composite(parent, SWT.NONE); + GridLayout gridLayout = new GridLayout(); + gridLayout.marginWidth = gridLayout.marginHeight = 0; + gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0; + treeViewPanel.setLayout(gridLayout); + + Composite buttonPanel = new Composite(treeViewPanel, SWT.NONE); + buttonPanel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + GridLayout buttonLayout = new GridLayout(); + buttonLayout.marginWidth = buttonLayout.marginHeight = 0; + buttonLayout.horizontalSpacing = buttonLayout.verticalSpacing = 0; + buttonPanel.setLayout(buttonLayout); + + Composite innerButtonPanel = new Composite(buttonPanel, SWT.NONE); + innerButtonPanel.setLayoutData(new GridData(GridData.FILL_VERTICAL)); + GridLayout innerButtonPanelLayout = new GridLayout(6, true); + innerButtonPanelLayout.marginWidth = innerButtonPanelLayout.marginHeight = 2; + innerButtonPanelLayout.horizontalSpacing = innerButtonPanelLayout.verticalSpacing = 2; + innerButtonPanel.setLayout(innerButtonPanelLayout); + + ActionButton saveTreeView = + new ActionButton(innerButtonPanel, SaveTreeViewAction.getAction(getShell())); + saveTreeView.setLayoutData(new GridData(GridData.FILL_BOTH)); + + ActionButton capturePSD = + new ActionButton(innerButtonPanel, CapturePSDAction.getAction(getShell())); + capturePSD.setLayoutData(new GridData(GridData.FILL_BOTH)); + + ActionButton refreshViewAction = + new ActionButton(innerButtonPanel, RefreshViewAction.getAction()); + refreshViewAction.setLayoutData(new GridData(GridData.FILL_BOTH)); + + ActionButton displayView = + new ActionButton(innerButtonPanel, DisplayViewAction.getAction(getShell())); + displayView.setLayoutData(new GridData(GridData.FILL_BOTH)); + + ActionButton invalidate = new ActionButton(innerButtonPanel, InvalidateAction.getAction()); + invalidate.setLayoutData(new GridData(GridData.FILL_BOTH)); + + ActionButton requestLayout = + new ActionButton(innerButtonPanel, RequestLayoutAction.getAction()); + requestLayout.setLayoutData(new GridData(GridData.FILL_BOTH)); + + SashForm mainSash = new SashForm(treeViewPanel, SWT.HORIZONTAL | SWT.SMOOTH); + mainSash.setLayoutData(new GridData(GridData.FILL_BOTH)); + Composite treeViewContainer = new Composite(mainSash, SWT.BORDER); + treeViewContainer.setLayout(new FillLayout()); + treeView = new TreeView(treeViewContainer); + + SashForm sideSash = new SashForm(mainSash, SWT.VERTICAL | SWT.SMOOTH); + + mainSash.SASH_WIDTH = 4; + mainSash.setWeights(new int[] { + 7, 3 + }); + + Composite treeViewOverviewContainer = new Composite(sideSash, SWT.BORDER); + treeViewOverviewContainer.setLayout(new FillLayout()); + TreeViewOverview treeViewOverview = new TreeViewOverview(treeViewOverviewContainer); + + Composite propertyViewerContainer = new Composite(sideSash, SWT.BORDER); + propertyViewerContainer.setLayout(new FillLayout()); + PropertyViewer propertyViewer = new PropertyViewer(propertyViewerContainer); + + Composite layoutViewerContainer = new Composite(sideSash, SWT.NONE); + GridLayout layoutViewerLayout = new GridLayout(); + layoutViewerLayout.marginWidth = layoutViewerLayout.marginHeight = 0; + layoutViewerLayout.horizontalSpacing = layoutViewerLayout.verticalSpacing = 1; + layoutViewerContainer.setLayout(layoutViewerLayout); + + Composite fullButtonBar = new Composite(layoutViewerContainer, SWT.NONE); + fullButtonBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + GridLayout fullButtonBarLayout = new GridLayout(2, false); + fullButtonBarLayout.marginWidth = fullButtonBarLayout.marginHeight = 0; + fullButtonBarLayout.marginRight = 2; + fullButtonBarLayout.horizontalSpacing = fullButtonBarLayout.verticalSpacing = 0; + fullButtonBar.setLayout(fullButtonBarLayout); + + Composite buttonBar = new Composite(fullButtonBar, SWT.NONE); + buttonBar.setLayoutData(new GridData(GridData.FILL_VERTICAL)); + RowLayout rowLayout = new RowLayout(SWT.HORIZONTAL); + rowLayout.marginLeft = + rowLayout.marginRight = rowLayout.marginTop = rowLayout.marginBottom = 0; + rowLayout.pack = true; + rowLayout.center = true; + buttonBar.setLayout(rowLayout); + + onBlackWhiteButton = new Button(buttonBar, SWT.PUSH); + onBlackWhiteButton.setImage(onWhiteImage); + onBlackWhiteButton.addSelectionListener(onBlackWhiteSelectionListener); + + showExtras = new Button(buttonBar, SWT.CHECK); + showExtras.setText("Show Extras"); + showExtras.addSelectionListener(showExtrasSelectionListener); + + ActionButton loadAllViewsButton = + new ActionButton(fullButtonBar, LoadAllViewsAction.getAction()); + loadAllViewsButton.setLayoutData(new GridData(GridData.END, GridData.CENTER, true, true)); + loadAllViewsButton.addSelectionListener(loadAllViewsSelectionListener); + + Composite layoutViewerMainContainer = new Composite(layoutViewerContainer, SWT.BORDER); + layoutViewerMainContainer.setLayoutData(new GridData(GridData.FILL_BOTH)); + layoutViewerMainContainer.setLayout(new FillLayout()); + layoutViewer = new LayoutViewer(layoutViewerMainContainer); + + sideSash.SASH_WIDTH = 4; + sideSash.setWeights(new int[] { + 238, 332, 416 + }); + + } + + private void buildPixelPerfectPanel(Composite parent) { + pixelPerfectPanel = new Composite(parent, SWT.NONE); + GridLayout gridLayout = new GridLayout(); + gridLayout.marginWidth = gridLayout.marginHeight = 0; + gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0; + pixelPerfectPanel.setLayout(gridLayout); + + Composite buttonPanel = new Composite(pixelPerfectPanel, SWT.NONE); + buttonPanel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + GridLayout buttonLayout = new GridLayout(); + buttonLayout.marginWidth = buttonLayout.marginHeight = 0; + buttonLayout.horizontalSpacing = buttonLayout.verticalSpacing = 0; + buttonPanel.setLayout(buttonLayout); + + Composite innerButtonPanel = new Composite(buttonPanel, SWT.NONE); + innerButtonPanel.setLayoutData(new GridData(GridData.FILL_VERTICAL)); + GridLayout innerButtonPanelLayout = new GridLayout(6, true); + innerButtonPanelLayout.marginWidth = innerButtonPanelLayout.marginHeight = 2; + innerButtonPanelLayout.horizontalSpacing = innerButtonPanelLayout.verticalSpacing = 2; + innerButtonPanel.setLayout(innerButtonPanelLayout); + + ActionButton saveTreeView = + new ActionButton(innerButtonPanel, SavePixelPerfectAction.getAction(getShell())); + saveTreeView.setLayoutData(new GridData(GridData.FILL_BOTH)); + + ActionButton refreshPixelPerfect = + new ActionButton(innerButtonPanel, RefreshPixelPerfectAction.getAction()); + refreshPixelPerfect.setLayoutData(new GridData(GridData.FILL_BOTH)); + + ActionButton refreshPixelPerfectTree = + new ActionButton(innerButtonPanel, RefreshPixelPerfectTreeAction.getAction()); + refreshPixelPerfectTree.setLayoutData(new GridData(GridData.FILL_BOTH)); + + ActionButton loadOverlay = + new ActionButton(innerButtonPanel, LoadOverlayAction.getAction(getShell())); + loadOverlay.setLayoutData(new GridData(GridData.FILL_BOTH)); + + ActionButton showInLoupe = + new ActionButton(innerButtonPanel, ShowOverlayAction.getAction()); + showInLoupe.setLayoutData(new GridData(GridData.FILL_BOTH)); + + ShowOverlayAction.getAction().setEnabled(false); + + ActionButton autoRefresh = + new ActionButton(innerButtonPanel, PixelPerfectAutoRefreshAction.getAction()); + autoRefresh.setLayoutData(new GridData(GridData.FILL_BOTH)); + + SashForm mainSash = new SashForm(pixelPerfectPanel, SWT.HORIZONTAL | SWT.SMOOTH); + mainSash.setLayoutData(new GridData(GridData.FILL_BOTH)); + mainSash.SASH_WIDTH = 4; + + Composite pixelPerfectTreeContainer = new Composite(mainSash, SWT.BORDER); + pixelPerfectTreeContainer.setLayout(new FillLayout()); + PixelPerfectTree pixelPerfectTree = new PixelPerfectTree(pixelPerfectTreeContainer); + + Composite pixelPerfectLoupeContainer = new Composite(mainSash, SWT.NONE); + GridLayout loupeLayout = new GridLayout(); + loupeLayout.marginWidth = loupeLayout.marginHeight = 0; + loupeLayout.horizontalSpacing = loupeLayout.verticalSpacing = 0; + pixelPerfectLoupeContainer.setLayout(loupeLayout); + + Composite pixelPerfectLoupeBorder = new Composite(pixelPerfectLoupeContainer, SWT.BORDER); + pixelPerfectLoupeBorder.setLayoutData(new GridData(GridData.FILL_BOTH)); + GridLayout pixelPerfectLoupeBorderGridLayout = new GridLayout(); + pixelPerfectLoupeBorderGridLayout.marginWidth = + pixelPerfectLoupeBorderGridLayout.marginHeight = 0; + pixelPerfectLoupeBorderGridLayout.horizontalSpacing = + pixelPerfectLoupeBorderGridLayout.verticalSpacing = 0; + pixelPerfectLoupeBorder.setLayout(pixelPerfectLoupeBorderGridLayout); + + pixelPerfectLoupe = new PixelPerfectLoupe(pixelPerfectLoupeBorder); + pixelPerfectLoupe.setLayoutData(new GridData(GridData.FILL_BOTH)); + + PixelPerfectPixelPanel pixelPerfectPixelPanel = + new PixelPerfectPixelPanel(pixelPerfectLoupeBorder); + pixelPerfectPixelPanel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Composite pixelPerfectControls = new Composite(pixelPerfectLoupeContainer, SWT.NONE); + pixelPerfectControls.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + pixelPerfectControls.setLayout(new FormLayout()); + + Label overlayTransparencyRight = new Label(pixelPerfectControls, SWT.NONE); + overlayTransparencyRight.setText("100%"); + FormData overlayTransparencyRightData = new FormData(); + overlayTransparencyRightData.right = new FormAttachment(100, -2); + overlayTransparencyRightData.top = new FormAttachment(0, 2); + overlayTransparencyRight.setLayoutData(overlayTransparencyRightData); + + Label refreshRight = new Label(pixelPerfectControls, SWT.NONE); + refreshRight.setText("40s"); + FormData refreshRightData = new FormData(); + refreshRightData.right = new FormAttachment(100, -2); + refreshRightData.top = new FormAttachment(overlayTransparencyRight, 2); + refreshRightData.left = new FormAttachment(overlayTransparencyRight, 0, SWT.LEFT); + refreshRight.setLayoutData(refreshRightData); + + Label zoomRight = new Label(pixelPerfectControls, SWT.NONE); + zoomRight.setText("24x"); + FormData zoomRightData = new FormData(); + zoomRightData.right = new FormAttachment(100, -2); + zoomRightData.top = new FormAttachment(refreshRight, 2); + zoomRightData.left = new FormAttachment(overlayTransparencyRight, 0, SWT.LEFT); + zoomRight.setLayoutData(zoomRightData); + + Label overlayTransparency = new Label(pixelPerfectControls, SWT.NONE); + Label refresh = new Label(pixelPerfectControls, SWT.NONE); + + overlayTransparency.setText("Overlay:"); + FormData overlayTransparencyData = new FormData(); + overlayTransparencyData.left = new FormAttachment(0, 2); + overlayTransparencyData.top = new FormAttachment(0, 2); + overlayTransparencyData.right = new FormAttachment(refresh, 0, SWT.RIGHT); + overlayTransparency.setLayoutData(overlayTransparencyData); + + refresh.setText("Refresh Rate:"); + FormData refreshData = new FormData(); + refreshData.top = new FormAttachment(overlayTransparency, 2); + refreshData.left = new FormAttachment(0, 2); + refresh.setLayoutData(refreshData); + + Label zoom = new Label(pixelPerfectControls, SWT.NONE); + zoom.setText("Zoom:"); + FormData zoomData = new FormData(); + zoomData.right = new FormAttachment(refresh, 0, SWT.RIGHT); + zoomData.top = new FormAttachment(refresh, 2); + zoomData.left = new FormAttachment(0, 2); + zoom.setLayoutData(zoomData); + + Label overlayTransparencyLeft = new Label(pixelPerfectControls, SWT.RIGHT); + overlayTransparencyLeft.setText("0%"); + FormData overlayTransparencyLeftData = new FormData(); + overlayTransparencyLeftData.top = new FormAttachment(0, 2); + overlayTransparencyLeftData.left = new FormAttachment(overlayTransparency, 2); + overlayTransparencyLeft.setLayoutData(overlayTransparencyLeftData); + + Label refreshLeft = new Label(pixelPerfectControls, SWT.RIGHT); + refreshLeft.setText("1s"); + FormData refreshLeftData = new FormData(); + refreshLeftData.top = new FormAttachment(overlayTransparencyLeft, 2); + refreshLeftData.left = new FormAttachment(refresh, 2); + refreshLeft.setLayoutData(refreshLeftData); + + Label zoomLeft = new Label(pixelPerfectControls, SWT.RIGHT); + zoomLeft.setText("2x"); + FormData zoomLeftData = new FormData(); + zoomLeftData.top = new FormAttachment(refreshLeft, 2); + zoomLeftData.left = new FormAttachment(zoom, 2); + zoomLeft.setLayoutData(zoomLeftData); + + overlaySlider = new Slider(pixelPerfectControls, SWT.HORIZONTAL); + overlaySlider.setMinimum(0); + overlaySlider.setMaximum(101); + overlaySlider.setThumb(1); + overlaySlider.setSelection(50); + overlaySlider.setEnabled(false); + FormData overlaySliderData = new FormData(); + overlaySliderData.right = new FormAttachment(overlayTransparencyRight, -4); + overlaySliderData.top = new FormAttachment(0, 2); + overlaySliderData.left = new FormAttachment(overlayTransparencyLeft, 4); + overlaySlider.setLayoutData(overlaySliderData); + + overlaySlider.addSelectionListener(overlaySliderSelectionListener); + + refreshSlider = new Slider(pixelPerfectControls, SWT.HORIZONTAL); + refreshSlider.setMinimum(1); + refreshSlider.setMaximum(41); + refreshSlider.setThumb(1); + refreshSlider.setSelection(refreshInterval); + FormData refreshSliderData = new FormData(); + refreshSliderData.right = new FormAttachment(overlayTransparencyRight, -4); + refreshSliderData.top = new FormAttachment(overlayTransparencyRight, 2); + refreshSliderData.left = new FormAttachment(overlaySlider, 0, SWT.LEFT); + refreshSlider.setLayoutData(refreshSliderData); + + refreshSlider.addSelectionListener(refreshSliderSelectionListener); + + ppZoomSlider = new Slider(pixelPerfectControls, SWT.HORIZONTAL); + ppZoomSlider.setMinimum(2); + ppZoomSlider.setMaximum(25); + ppZoomSlider.setThumb(1); + ppZoomSlider.setSelection(PixelPerfectModel.DEFAULT_ZOOM); + FormData zoomSliderData = new FormData(); + zoomSliderData.right = new FormAttachment(overlayTransparencyRight, -4); + zoomSliderData.top = new FormAttachment(refreshRight, 2); + zoomSliderData.left = new FormAttachment(overlaySlider, 0, SWT.LEFT); + ppZoomSlider.setLayoutData(zoomSliderData); + + ppZoomSlider.addSelectionListener(ppZoomSliderSelectionListener); + + Composite pixelPerfectContainer = new Composite(mainSash, SWT.BORDER); + pixelPerfectContainer.setLayout(new FillLayout()); + PixelPerfect pixelPerfect = new PixelPerfect(pixelPerfectContainer); + + mainSash.setWeights(new int[] { + 272, 376, 346 + }); + + } + + public void setAutoRefresh(boolean value) { + if (value) { + refreshTimeLeft = refreshInterval; + autoRefresh = true; + } else { + autoRefresh = false; + } + } + + public void showOverlayInLoupe(boolean value) { + pixelPerfectLoupe.setShowOverlay(value); + } + + public void startTask(final String taskName) { + progressString = taskName; + Display.getDefault().syncExec(new Runnable() { + public void run() { + if (progressLabel != null && progressBar != null) { + progressLabel.setText(taskName); + progressLabel.setVisible(true); + progressBar.setVisible(true); + statusBar.layout(); + } + } + }); + } + + public void endTask() { + progressString = null; + Display.getDefault().syncExec(new Runnable() { + public void run() { + if (progressLabel != null && progressBar != null) { + progressLabel.setVisible(false); + progressBar.setVisible(false); + } + } + }); + } + + public void showDeviceSelector() { + // Show the menus. + MenuManager mm = getMenuBarManager(); + mm.removeAll(); + + MenuManager file = new MenuManager("&File"); + mm.add(file); + + file.add(QuitAction.getAction()); + + MenuManager device = new MenuManager("&Devices"); + mm.add(device); + + device.add(RefreshWindowsAction.getAction()); + device.add(LoadViewHierarchyAction.getAction()); + device.add(InspectScreenshotAction.getAction()); + + MenuManager help = new MenuManager("&Help"); + mm.add(help); + + help.add(AboutAction.getAction(getShell())); + + mm.updateAll(true); + + deviceViewButton.setSelection(true); + deviceViewButton.setImage(deviceViewSelectedImage); + + treeViewButton.setSelection(false); + treeViewButton.setImage(treeViewImage); + + pixelPerfectButton.setSelection(false); + pixelPerfectButton.setImage(pixelPerfectImage); + + mainWindowStackLayout.topControl = deviceSelectorPanel; + + mainWindow.layout(); + + deviceSelector.setFocus(); + + statusBarStackLayout.topControl = null; + statusBarControlPanel.setVisible(false); + statusBarControlPanel.layout(); + } + + public void showTreeView() { + // Show the menus. + MenuManager mm = getMenuBarManager(); + mm.removeAll(); + + MenuManager file = new MenuManager("&File"); + mm.add(file); + + file.add(QuitAction.getAction()); + + MenuManager treeViewMenu = new MenuManager("&Tree View"); + mm.add(treeViewMenu); + + treeViewMenu.add(SaveTreeViewAction.getAction(getShell())); + treeViewMenu.add(CapturePSDAction.getAction(getShell())); + treeViewMenu.add(new Separator()); + treeViewMenu.add(RefreshViewAction.getAction()); + treeViewMenu.add(DisplayViewAction.getAction(getShell())); + treeViewMenu.add(new Separator()); + treeViewMenu.add(InvalidateAction.getAction()); + treeViewMenu.add(RequestLayoutAction.getAction()); + + MenuManager help = new MenuManager("&Help"); + mm.add(help); + + help.add(AboutAction.getAction(getShell())); + + mm.updateAll(true); + + deviceViewButton.setSelection(false); + deviceViewButton.setImage(deviceViewImage); + + treeViewButton.setSelection(true); + treeViewButton.setImage(treeViewSelectedImage); + + pixelPerfectButton.setSelection(false); + pixelPerfectButton.setImage(pixelPerfectImage); + + mainWindowStackLayout.topControl = treeViewPanel; + + mainWindow.layout(); + + treeView.setFocus(); + + statusBarStackLayout.topControl = treeViewControls; + statusBarControlPanel.setVisible(true); + statusBarControlPanel.layout(); + } + + public void showPixelPerfect() { + // Show the menus. + MenuManager mm = getMenuBarManager(); + mm.removeAll(); + + MenuManager file = new MenuManager("&File"); + mm.add(file); + + file.add(QuitAction.getAction()); + + MenuManager pixelPerfect = new MenuManager("&Pixel Perfect"); + pixelPerfect.add(SavePixelPerfectAction.getAction(getShell())); + pixelPerfect.add(RefreshPixelPerfectAction.getAction()); + pixelPerfect.add(RefreshPixelPerfectTreeAction.getAction()); + pixelPerfect.add(PixelPerfectAutoRefreshAction.getAction()); + pixelPerfect.add(new Separator()); + pixelPerfect.add(LoadOverlayAction.getAction(getShell())); + pixelPerfect.add(ShowOverlayAction.getAction()); + + mm.add(pixelPerfect); + + MenuManager help = new MenuManager("&Help"); + mm.add(help); + + help.add(AboutAction.getAction(getShell())); + + mm.updateAll(true); + + deviceViewButton.setSelection(false); + deviceViewButton.setImage(deviceViewImage); + + treeViewButton.setSelection(false); + treeViewButton.setImage(treeViewImage); + + pixelPerfectButton.setSelection(true); + pixelPerfectButton.setImage(pixelPerfectSelectedImage); + + mainWindowStackLayout.topControl = pixelPerfectPanel; + + mainWindow.layout(); + + pixelPerfectLoupe.setFocus(); + + statusBarStackLayout.topControl = null; + statusBarControlPanel.setVisible(false); + statusBarControlPanel.layout(); + } + + private SelectionListener deviceViewButtonSelectionListener = new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + // pass + } + + public void widgetSelected(SelectionEvent e) { + deviceViewButton.setSelection(true); + showDeviceSelector(); + } + }; + + private SelectionListener treeViewButtonSelectionListener = new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + // pass + } + + public void widgetSelected(SelectionEvent e) { + treeViewButton.setSelection(true); + showTreeView(); + } + }; + + private SelectionListener pixelPerfectButtonSelectionListener = new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + // pass + } + + public void widgetSelected(SelectionEvent e) { + pixelPerfectButton.setSelection(true); + showPixelPerfect(); + } + }; + + private SelectionListener onBlackWhiteSelectionListener = new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + // pass + } + + public void widgetSelected(SelectionEvent e) { + if (layoutViewer.getOnBlack()) { + layoutViewer.setOnBlack(false); + onBlackWhiteButton.setImage(onBlackImage); + } else { + layoutViewer.setOnBlack(true); + onBlackWhiteButton.setImage(onWhiteImage); + } + } + }; + + private SelectionListener showExtrasSelectionListener = new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + // pass + } + + public void widgetSelected(SelectionEvent e) { + layoutViewer.setShowExtras(showExtras.getSelection()); + } + }; + + private SelectionListener loadAllViewsSelectionListener = new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + // pass + } + + public void widgetSelected(SelectionEvent e) { + showExtras.setSelection(true); + showExtrasSelectionListener.widgetSelected(null); + } + }; + + private SelectionListener zoomSliderSelectionListener = new SelectionListener() { + private int oldValue; + + public void widgetDefaultSelected(SelectionEvent e) { + // pass + } + + public void widgetSelected(SelectionEvent e) { + int newValue = zoomSlider.getSelection(); + if (oldValue != newValue) { + TreeViewModel.getModel().removeTreeChangeListener(treeChangeListener); + TreeViewModel.getModel().setZoom(newValue / 10.0); + TreeViewModel.getModel().addTreeChangeListener(treeChangeListener); + oldValue = newValue; + } + } + }; + + private Runnable autoRefresher = new Runnable() { + public void run() { + while (!Thread.currentThread().isInterrupted()) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + break; + } + refreshTimeLeft--; + if (autoRefresh && refreshTimeLeft <= 0) { + HierarchyViewerDirector.getDirector().refreshPixelPerfect(); + refreshTimeLeft = refreshInterval; + } + } + } + }; + + private SelectionListener overlaySliderSelectionListener = new SelectionListener() { + private int oldValue; + + public void widgetDefaultSelected(SelectionEvent e) { + // pass + } + + public void widgetSelected(SelectionEvent e) { + int newValue = overlaySlider.getSelection(); + if (oldValue != newValue) { + PixelPerfectModel.getModel().removeImageChangeListener(imageChangeListener); + PixelPerfectModel.getModel().setOverlayTransparency(newValue / 100.0); + PixelPerfectModel.getModel().addImageChangeListener(imageChangeListener); + oldValue = newValue; + } + } + }; + + private SelectionListener refreshSliderSelectionListener = new SelectionListener() { + private int oldValue; + + public void widgetDefaultSelected(SelectionEvent e) { + // pass + } + + public void widgetSelected(SelectionEvent e) { + int newValue = refreshSlider.getSelection(); + if (oldValue != newValue) { + refreshInterval = newValue; + oldValue = newValue; + } + } + }; + + private SelectionListener ppZoomSliderSelectionListener = new SelectionListener() { + private int oldValue; + + public void widgetDefaultSelected(SelectionEvent e) { + // pass + } + + public void widgetSelected(SelectionEvent e) { + int newValue = ppZoomSlider.getSelection(); + if (oldValue != newValue) { + PixelPerfectModel.getModel().removeImageChangeListener(imageChangeListener); + PixelPerfectModel.getModel().setZoom(newValue); + PixelPerfectModel.getModel().addImageChangeListener(imageChangeListener); + oldValue = newValue; + } + } + }; + + private ModifyListener filterTextModifyListener = new ModifyListener() { + public void modifyText(ModifyEvent e) { + HierarchyViewerDirector.getDirector().filterNodes(filterText.getText()); + } + }; + + private WindowChangeListener windowChangeListener = new WindowChangeListener() { + public void deviceChanged(IDevice device) { + // pass + } + + public void deviceConnected(IDevice device) { + // pass + } + + public void deviceDisconnected(IDevice device) { + // pass + } + + public void focusChanged(IDevice device) { + // pass + } + + public void selectionChanged(final IDevice device, final Window window) { + Display.getDefault().syncExec(new Runnable() { + public void run() { + if (window == null) { + LoadViewHierarchyAction.getAction().setEnabled(false); + } else { + LoadViewHierarchyAction.getAction().setEnabled(true); + } + if (device == null) { + InspectScreenshotAction.getAction().setEnabled(false); + } else { + InspectScreenshotAction.getAction().setEnabled(true); + } + } + }); + } + }; + + private TreeChangeListener treeChangeListener = new TreeChangeListener() { + public void selectionChanged() { + // pass + } + + public void treeChanged() { + Display.getDefault().syncExec(new Runnable() { + public void run() { + if (TreeViewModel.getModel().getTree() == null) { + showDeviceSelector(); + treeViewButton.setEnabled(false); + } else { + showTreeView(); + treeViewButton.setEnabled(true); + zoomSlider.setSelection((int) Math + .round(TreeViewModel.getModel().getZoom() * 10)); + filterText.setText(""); + } + } + }); + } + + public void viewportChanged() { + // pass + } + + public void zoomChanged() { + // pass + zoomSlider.setSelection((int) Math.round(TreeViewModel.getModel().getZoom() * 10)); + } + }; + + private ImageChangeListener imageChangeListener = new ImageChangeListener() { + + public void crosshairMoved() { + // pass + } + + public void treeChanged() { + // pass + } + + public void imageChanged() { + // pass + } + + public void imageLoaded() { + Display.getDefault().syncExec(new Runnable() { + public void run() { + Image overlayImage = PixelPerfectModel.getModel().getOverlayImage(); + ShowOverlayAction.getAction().setEnabled(overlayImage != null); + overlaySlider.setEnabled(overlayImage != null); + if (PixelPerfectModel.getModel().getImage() == null) { + pixelPerfectButton.setEnabled(false); + showDeviceSelector(); + } else { + ppZoomSlider.setSelection(PixelPerfectModel.getModel().getZoom()); + pixelPerfectButton.setEnabled(true); + showPixelPerfect(); + } + } + }); + } + + public void overlayChanged() { + Display.getDefault().syncExec(new Runnable() { + public void run() { + Image overlayImage = PixelPerfectModel.getModel().getOverlayImage(); + ShowOverlayAction.getAction().setEnabled(overlayImage != null); + overlaySlider.setEnabled(overlayImage != null); + } + }); + } + + public void overlayTransparencyChanged() { + Display.getDefault().syncExec(new Runnable() { + public void run() { + overlaySlider.setSelection((int) (PixelPerfectModel.getModel() + .getOverlayTransparency() * 100)); + } + }); + } + + public void selectionChanged() { + // pass + } + + public void zoomChanged() { + Display.getDefault().syncExec(new Runnable() { + public void run() { + ppZoomSlider.setSelection(PixelPerfectModel.getModel().getZoom()); + } + }); + } + + }; + + public static void main(String[] args) { + Display.getDefault().syncExec(new Runnable() { + public void run() { + new HierarchyViewerApplication().run(); + } + }); System.exit(0); } } diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplicationDirector.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplicationDirector.java index 8d77410..f26cc2c 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplicationDirector.java +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplicationDirector.java @@ -30,6 +30,10 @@ public class HierarchyViewerApplicationDirector extends HierarchyViewerDirector private final ExecutorService executor = Executors.newSingleThreadExecutor(); + public static HierarchyViewerDirector createDirector() { + return director = new HierarchyViewerApplicationDirector(); + } + @Override public void terminate() { super.terminate(); @@ -43,9 +47,6 @@ public class HierarchyViewerApplicationDirector extends HierarchyViewerDirector @Override public String getAdbLocation() { String hvParentLocation = System.getProperty("com.android.hierarchyviewer.bindir"); - // TODO REMOVE THIS. - hvParentLocation = "/usr/local/google/android-ext/out/host/linux-x86/bin"; - System.out.println(hvParentLocation); if (hvParentLocation != null && hvParentLocation.length() != 0) { return hvParentLocation + File.separator + SdkConstants.FN_ADB; } @@ -58,12 +59,12 @@ public class HierarchyViewerApplicationDirector extends HierarchyViewerDirector * progress bar to show that we are doing something in the background. */ @Override - public void executeInBackground(final Runnable task) { + public void executeInBackground(final String taskName, final Runnable task) { executor.execute(new Runnable() { public void run() { - System.out.println("STARTING TASK"); + HierarchyViewerApplication.getApp().startTask(taskName); task.run(); - System.out.println("ENDING TASK"); + HierarchyViewerApplication.getApp().endTask(); } }); } diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/UIThread.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/UIThread.java deleted file mode 100644 index 3da9468..0000000 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/UIThread.java +++ /dev/null @@ -1,66 +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.hierarchyviewer; - -import com.android.ddmuilib.ImageLoader; -import com.android.hierarchyviewerlib.ComponentRegistry; -import com.android.hierarchyviewerlib.ui.DeviceSelector; -import com.android.hierarchyviewerlib.ui.LayoutViewer; -import com.android.hierarchyviewerlib.ui.PixelPerfect; -import com.android.hierarchyviewerlib.ui.PixelPerfectLoupe; -import com.android.hierarchyviewerlib.ui.PixelPerfectTree; -import com.android.hierarchyviewerlib.ui.ProfileViewer; -import com.android.hierarchyviewerlib.ui.PropertyViewer; -import com.android.hierarchyviewerlib.ui.TreeView; -import com.android.hierarchyviewerlib.ui.TreeViewOverview; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.events.ShellEvent; -import org.eclipse.swt.events.ShellListener; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Slider; - -public class UIThread { - public static void runUI() { - Display display = new Display(); - - // CODE BELOW IS FOR TESTING. - Shell shell = new Shell(display); - shell.setLayout(new FillLayout()); - DeviceSelector deviceSelector = new DeviceSelector(shell); - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - - // NO LONGER TESTING STUFF. - - ImageLoader.dispose(); - display.dispose(); - } -} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/AboutAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/AboutAction.java new file mode 100644 index 0000000..9c76ae9 --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/AboutAction.java @@ -0,0 +1,63 @@ +/* + * 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.hierarchyviewer.actions; + +import com.android.ddmuilib.ImageLoader; +import com.android.hierarchyviewer.AboutDialog; +import com.android.hierarchyviewerlib.HierarchyViewerDirector; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +public class AboutAction extends Action implements ImageAction { + + private static AboutAction action; + + private Image image; + + private Shell shell; + + private AboutAction(Shell shell) { + super("&About"); + this.shell = shell; + setAccelerator(SWT.MOD1 + 'A'); + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + image = imageLoader.loadImage("about-small.jpg", Display.getDefault()); + setImageDescriptor(ImageDescriptor.createFromImage(image)); + setToolTipText("Shows the about dialog"); + } + + public static AboutAction getAction(Shell shell) { + if (action == null) { + action = new AboutAction(shell); + } + return action; + } + + @Override + public void run() { + new AboutDialog(shell).open(); + } + + public Image getImage() { + return image; + } +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/CapturePSDAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/CapturePSDAction.java new file mode 100644 index 0000000..6ae0d17 --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/CapturePSDAction.java @@ -0,0 +1,62 @@ +/* + * 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.hierarchyviewer.actions; + +import com.android.ddmuilib.ImageLoader; +import com.android.hierarchyviewerlib.HierarchyViewerDirector; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +public class CapturePSDAction extends Action implements ImageAction { + + private static CapturePSDAction action; + + private Image image; + + private Shell shell; + + private CapturePSDAction(Shell shell) { + super("&Capture Layers"); + this.shell = shell; + setAccelerator(SWT.MOD1 + 'C'); + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + image = imageLoader.loadImage("capture-psd.png", Display.getDefault()); + setImageDescriptor(ImageDescriptor.createFromImage(image)); + setToolTipText("Capture the window layers as a photoshop document"); + } + + public static CapturePSDAction getAction(Shell shell) { + if (action == null) { + action = new CapturePSDAction(shell); + } + return action; + } + + @Override + public void run() { + HierarchyViewerDirector.getDirector().capturePSD(shell); + } + + public Image getImage() { + return image; + } +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/DisplayViewAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/DisplayViewAction.java new file mode 100644 index 0000000..a622eb2 --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/DisplayViewAction.java @@ -0,0 +1,62 @@ +/* + * 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.hierarchyviewer.actions; + +import com.android.ddmuilib.ImageLoader; +import com.android.hierarchyviewerlib.HierarchyViewerDirector; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +public class DisplayViewAction extends Action implements ImageAction { + + private static DisplayViewAction action; + + private Image image; + + private Shell shell; + + private DisplayViewAction(Shell shell) { + super("&Display View"); + this.shell = shell; + setAccelerator(SWT.MOD1 + 'D'); + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + image = imageLoader.loadImage("display.png", Display.getDefault()); + setImageDescriptor(ImageDescriptor.createFromImage(image)); + setToolTipText("Display the selected view image in a separate window"); + } + + public static DisplayViewAction getAction(Shell shell) { + if (action == null) { + action = new DisplayViewAction(shell); + } + return action; + } + + @Override + public void run() { + HierarchyViewerDirector.getDirector().showCapture(shell); + } + + public Image getImage() { + return image; + } +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ImageAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ImageAction.java new file mode 100644 index 0000000..11c98a4 --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ImageAction.java @@ -0,0 +1,27 @@ +/* + * 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.hierarchyviewer.actions; + +import org.eclipse.swt.graphics.Image; + +public interface ImageAction { + public Image getImage(); + + public String getText(); + + public String getToolTipText(); +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/InspectScreenshotAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/InspectScreenshotAction.java new file mode 100644 index 0000000..5109ca5 --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/InspectScreenshotAction.java @@ -0,0 +1,58 @@ +/* + * 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.hierarchyviewer.actions; + +import com.android.ddmuilib.ImageLoader; +import com.android.hierarchyviewerlib.HierarchyViewerDirector; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +public class InspectScreenshotAction extends Action implements ImageAction { + + private static InspectScreenshotAction action; + + private Image image; + + private InspectScreenshotAction() { + super("Inspect &Screenshot"); + setAccelerator(SWT.MOD1 + 'S'); + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + image = imageLoader.loadImage("inspect-screenshot.png", Display.getDefault()); + setImageDescriptor(ImageDescriptor.createFromImage(image)); + setToolTipText("Inspect a screenshot in the pixel perfect view"); + } + + public static InspectScreenshotAction getAction() { + if (action == null) { + action = new InspectScreenshotAction(); + } + return action; + } + + @Override + public void run() { + HierarchyViewerDirector.getDirector().inspectScreenshot(); + } + + public Image getImage() { + return image; + } +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/InvalidateAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/InvalidateAction.java new file mode 100644 index 0000000..831a56d --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/InvalidateAction.java @@ -0,0 +1,58 @@ +/* + * 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.hierarchyviewer.actions; + +import com.android.ddmuilib.ImageLoader; +import com.android.hierarchyviewerlib.HierarchyViewerDirector; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +public class InvalidateAction extends Action implements ImageAction { + + private static InvalidateAction action; + + private Image image; + + private InvalidateAction() { + super("&Invalidate Layout"); + setAccelerator(SWT.MOD1 + 'I'); + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + image = imageLoader.loadImage("invalidate.png", Display.getDefault()); + setImageDescriptor(ImageDescriptor.createFromImage(image)); + setToolTipText("Invalidate the layout for the current window"); + } + + public static InvalidateAction getAction() { + if (action == null) { + action = new InvalidateAction(); + } + return action; + } + + @Override + public void run() { + HierarchyViewerDirector.getDirector().invalidateCurrentNode(); + } + + public Image getImage() { + return image; + } +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadAllViewsAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadAllViewsAction.java new file mode 100644 index 0000000..2ea2298 --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadAllViewsAction.java @@ -0,0 +1,58 @@ +/* + * 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.hierarchyviewer.actions; + +import com.android.ddmuilib.ImageLoader; +import com.android.hierarchyviewerlib.HierarchyViewerDirector; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +public class LoadAllViewsAction extends Action implements ImageAction { + + private static LoadAllViewsAction action; + + private Image image; + + private LoadAllViewsAction() { + super("Load All &Views"); + setAccelerator(SWT.MOD1 + 'V'); + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + image = imageLoader.loadImage("load-all-views.png", Display.getDefault()); + setImageDescriptor(ImageDescriptor.createFromImage(image)); + setToolTipText("Load all view images"); + } + + public static LoadAllViewsAction getAction() { + if (action == null) { + action = new LoadAllViewsAction(); + } + return action; + } + + @Override + public void run() { + HierarchyViewerDirector.getDirector().loadAllViews(); + } + + public Image getImage() { + return image; + } +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadOverlayAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadOverlayAction.java new file mode 100644 index 0000000..588b995 --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadOverlayAction.java @@ -0,0 +1,62 @@ +/* + * 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.hierarchyviewer.actions; + +import com.android.ddmuilib.ImageLoader; +import com.android.hierarchyviewerlib.HierarchyViewerDirector; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +public class LoadOverlayAction extends Action implements ImageAction { + + private static LoadOverlayAction action; + + private Image image; + + private Shell shell; + + private LoadOverlayAction(Shell shell) { + super("Load &Overlay"); + this.shell = shell; + setAccelerator(SWT.MOD1 + 'O'); + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + image = imageLoader.loadImage("load-overlay.png", Display.getDefault()); + setImageDescriptor(ImageDescriptor.createFromImage(image)); + setToolTipText("Load an image to overlay the screenshot"); + } + + public static LoadOverlayAction getAction(Shell shell) { + if (action == null) { + action = new LoadOverlayAction(shell); + } + return action; + } + + @Override + public void run() { + HierarchyViewerDirector.getDirector().loadOverlay(shell); + } + + public Image getImage() { + return image; + } +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadViewHierarchyAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadViewHierarchyAction.java new file mode 100644 index 0000000..79fd0b3 --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadViewHierarchyAction.java @@ -0,0 +1,58 @@ +/* + * 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.hierarchyviewer.actions; + +import com.android.ddmuilib.ImageLoader; +import com.android.hierarchyviewerlib.HierarchyViewerDirector; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +public class LoadViewHierarchyAction extends Action implements ImageAction { + + private static LoadViewHierarchyAction action; + + private Image image; + + private LoadViewHierarchyAction() { + super("Load View &Hierarchy"); + setAccelerator(SWT.MOD1 + 'H'); + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + image = imageLoader.loadImage("load-view-hierarchy.png", Display.getDefault()); + setImageDescriptor(ImageDescriptor.createFromImage(image)); + setToolTipText("Load the view hierarchy into the tree view"); + } + + public static LoadViewHierarchyAction getAction() { + if (action == null) { + action = new LoadViewHierarchyAction(); + } + return action; + } + + @Override + public void run() { + HierarchyViewerDirector.getDirector().loadViewHierarchy(); + } + + public Image getImage() { + return image; + } +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/PixelPerfectAutoRefreshAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/PixelPerfectAutoRefreshAction.java new file mode 100644 index 0000000..325eb86 --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/PixelPerfectAutoRefreshAction.java @@ -0,0 +1,59 @@ +/* + * 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.hierarchyviewer.actions; + +import com.android.ddmuilib.ImageLoader; +import com.android.hierarchyviewer.HierarchyViewerApplication; +import com.android.hierarchyviewerlib.HierarchyViewerDirector; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +public class PixelPerfectAutoRefreshAction extends Action implements ImageAction { + + private static PixelPerfectAutoRefreshAction action; + + private Image image; + + private PixelPerfectAutoRefreshAction() { + super("Auto &Refresh", Action.AS_CHECK_BOX); + setAccelerator(SWT.MOD1 + 'R'); + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + image = imageLoader.loadImage("auto-refresh.png", Display.getDefault()); + setImageDescriptor(ImageDescriptor.createFromImage(image)); + setToolTipText("Automatically refresh the screenshot"); + } + + public static PixelPerfectAutoRefreshAction getAction() { + if (action == null) { + action = new PixelPerfectAutoRefreshAction(); + } + return action; + } + + @Override + public void run() { + HierarchyViewerApplication.getApp().setAutoRefresh(action.isChecked()); + } + + public Image getImage() { + return image; + } +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/QuitAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/QuitAction.java new file mode 100644 index 0000000..693d55a --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/QuitAction.java @@ -0,0 +1,44 @@ +/* + * 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.hierarchyviewer.actions; + +import com.android.hierarchyviewer.HierarchyViewerApplication; + +import org.eclipse.jface.action.Action; +import org.eclipse.swt.SWT; + +public class QuitAction extends Action { + + private static QuitAction action; + + private QuitAction() { + super("E&xit"); + setAccelerator(SWT.MOD1 + 'Q'); + } + + public static QuitAction getAction() { + if (action == null) { + action = new QuitAction(); + } + return action; + } + + @Override + public void run() { + HierarchyViewerApplication.getApp().close(); + } +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshPixelPerfectAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshPixelPerfectAction.java new file mode 100644 index 0000000..5d68c37 --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshPixelPerfectAction.java @@ -0,0 +1,58 @@ +/* + * 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.hierarchyviewer.actions; + +import com.android.ddmuilib.ImageLoader; +import com.android.hierarchyviewerlib.HierarchyViewerDirector; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +public class RefreshPixelPerfectAction extends Action implements ImageAction { + + private static RefreshPixelPerfectAction action; + + private Image image; + + private RefreshPixelPerfectAction() { + super("&Refresh Screenshot"); + setAccelerator(SWT.F5); + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + image = imageLoader.loadImage("refresh-windows.png", Display.getDefault()); + setImageDescriptor(ImageDescriptor.createFromImage(image)); + setToolTipText("Refresh the screenshot"); + } + + public static RefreshPixelPerfectAction getAction() { + if (action == null) { + action = new RefreshPixelPerfectAction(); + } + return action; + } + + @Override + public void run() { + HierarchyViewerDirector.getDirector().refreshPixelPerfect(); + } + + public Image getImage() { + return image; + } +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshPixelPerfectTreeAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshPixelPerfectTreeAction.java new file mode 100644 index 0000000..74c577d --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshPixelPerfectTreeAction.java @@ -0,0 +1,58 @@ +/* + * 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.hierarchyviewer.actions; + +import com.android.ddmuilib.ImageLoader; +import com.android.hierarchyviewerlib.HierarchyViewerDirector; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +public class RefreshPixelPerfectTreeAction extends Action implements ImageAction { + + private static RefreshPixelPerfectTreeAction action; + + private Image image; + + private RefreshPixelPerfectTreeAction() { + super("Refresh &Tree"); + setAccelerator(SWT.MOD1 + 'T'); + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + image = imageLoader.loadImage("load-view-hierarchy.png", Display.getDefault()); + setImageDescriptor(ImageDescriptor.createFromImage(image)); + setToolTipText("Refresh the tree"); + } + + public static RefreshPixelPerfectTreeAction getAction() { + if (action == null) { + action = new RefreshPixelPerfectTreeAction(); + } + return action; + } + + @Override + public void run() { + HierarchyViewerDirector.getDirector().refreshPixelPerfectTree(); + } + + public Image getImage() { + return image; + } +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshViewAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshViewAction.java new file mode 100644 index 0000000..36704a7 --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshViewAction.java @@ -0,0 +1,58 @@ +/* + * 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.hierarchyviewer.actions; + +import com.android.ddmuilib.ImageLoader; +import com.android.hierarchyviewerlib.HierarchyViewerDirector; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +public class RefreshViewAction extends Action implements ImageAction { + + private static RefreshViewAction action; + + private Image image; + + private RefreshViewAction() { + super("Load View &Hierarchy"); + setAccelerator(SWT.MOD1 + 'H'); + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + image = imageLoader.loadImage("load-view-hierarchy.png", Display.getDefault()); + setImageDescriptor(ImageDescriptor.createFromImage(image)); + setToolTipText("Reload the view hierarchy"); + } + + public static RefreshViewAction getAction() { + if (action == null) { + action = new RefreshViewAction(); + } + return action; + } + + @Override + public void run() { + HierarchyViewerDirector.getDirector().reloadViewHierarchy(); + } + + public Image getImage() { + return image; + } +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshWindowsAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshWindowsAction.java new file mode 100644 index 0000000..63808ee --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshWindowsAction.java @@ -0,0 +1,58 @@ +/* + * 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.hierarchyviewer.actions; + +import com.android.ddmuilib.ImageLoader; +import com.android.hierarchyviewerlib.HierarchyViewerDirector; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +public class RefreshWindowsAction extends Action implements ImageAction { + + private static RefreshWindowsAction action; + + private Image image; + + private RefreshWindowsAction() { + super("&Refresh"); + setAccelerator(SWT.F5); + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + image = imageLoader.loadImage("refresh-windows.png", Display.getDefault()); + setImageDescriptor(ImageDescriptor.createFromImage(image)); + setToolTipText("Refresh the list of devices"); + } + + public static RefreshWindowsAction getAction() { + if (action == null) { + action = new RefreshWindowsAction(); + } + return action; + } + + @Override + public void run() { + HierarchyViewerDirector.getDirector().refreshWindows(); + } + + public Image getImage() { + return image; + } +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RequestLayoutAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RequestLayoutAction.java new file mode 100644 index 0000000..9255432 --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RequestLayoutAction.java @@ -0,0 +1,58 @@ +/* + * 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.hierarchyviewer.actions; + +import com.android.ddmuilib.ImageLoader; +import com.android.hierarchyviewerlib.HierarchyViewerDirector; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +public class RequestLayoutAction extends Action implements ImageAction { + + private static RequestLayoutAction action; + + private Image image; + + private RequestLayoutAction() { + super("Request &Layout"); + setAccelerator(SWT.MOD1 + 'L'); + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + image = imageLoader.loadImage("request-layout.png", Display.getDefault()); + setImageDescriptor(ImageDescriptor.createFromImage(image)); + setToolTipText("Request the view to lay out"); + } + + public static RequestLayoutAction getAction() { + if (action == null) { + action = new RequestLayoutAction(); + } + return action; + } + + @Override + public void run() { + HierarchyViewerDirector.getDirector().relayoutCurrentNode(); + } + + public Image getImage() { + return image; + } +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/SavePixelPerfectAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/SavePixelPerfectAction.java new file mode 100644 index 0000000..2221ad8 --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/SavePixelPerfectAction.java @@ -0,0 +1,62 @@ +/* + * 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.hierarchyviewer.actions; + +import com.android.ddmuilib.ImageLoader; +import com.android.hierarchyviewerlib.HierarchyViewerDirector; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +public class SavePixelPerfectAction extends Action implements ImageAction { + + private static SavePixelPerfectAction action; + + private Image image; + + private Shell shell; + + private SavePixelPerfectAction(Shell shell) { + super("&Save as PNG"); + this.shell = shell; + setAccelerator(SWT.MOD1 + 'S'); + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + image = imageLoader.loadImage("save.png", Display.getDefault()); + setImageDescriptor(ImageDescriptor.createFromImage(image)); + setToolTipText("Save the screenshot as a PNG image"); + } + + public static SavePixelPerfectAction getAction(Shell shell) { + if (action == null) { + action = new SavePixelPerfectAction(shell); + } + return action; + } + + @Override + public void run() { + HierarchyViewerDirector.getDirector().savePixelPerfect(shell); + } + + public Image getImage() { + return image; + } +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/SaveTreeViewAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/SaveTreeViewAction.java new file mode 100644 index 0000000..c203ace --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/SaveTreeViewAction.java @@ -0,0 +1,62 @@ +/* + * 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.hierarchyviewer.actions; + +import com.android.ddmuilib.ImageLoader; +import com.android.hierarchyviewerlib.HierarchyViewerDirector; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +public class SaveTreeViewAction extends Action implements ImageAction { + + private static SaveTreeViewAction action; + + private Image image; + + private Shell shell; + + private SaveTreeViewAction(Shell shell) { + super("&Save as PNG"); + this.shell = shell; + setAccelerator(SWT.MOD1 + 'S'); + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + image = imageLoader.loadImage("save.png", Display.getDefault()); + setImageDescriptor(ImageDescriptor.createFromImage(image)); + setToolTipText("Save the tree view as a PNG image"); + } + + public static SaveTreeViewAction getAction(Shell shell) { + if (action == null) { + action = new SaveTreeViewAction(shell); + } + return action; + } + + @Override + public void run() { + HierarchyViewerDirector.getDirector().saveTreeView(shell); + } + + public Image getImage() { + return image; + } +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ShowOverlayAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ShowOverlayAction.java new file mode 100644 index 0000000..b0f51ec --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ShowOverlayAction.java @@ -0,0 +1,59 @@ +/* + * 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.hierarchyviewer.actions; + +import com.android.ddmuilib.ImageLoader; +import com.android.hierarchyviewer.HierarchyViewerApplication; +import com.android.hierarchyviewerlib.HierarchyViewerDirector; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +public class ShowOverlayAction extends Action implements ImageAction { + + private static ShowOverlayAction action; + + private Image image; + + private ShowOverlayAction() { + super("Show In &Loupe", Action.AS_CHECK_BOX); + setAccelerator(SWT.MOD1 + 'L'); + ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class); + image = imageLoader.loadImage("show-overlay.png", Display.getDefault()); + setImageDescriptor(ImageDescriptor.createFromImage(image)); + setToolTipText("Show the overlay in the loupe view"); + } + + public static ShowOverlayAction getAction() { + if (action == null) { + action = new ShowOverlayAction(); + } + return action; + } + + @Override + public void run() { + HierarchyViewerApplication.getApp().showOverlayInLoupe(action.isChecked()); + } + + public Image getImage() { + return image; + } +} diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/util/ActionButton.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/util/ActionButton.java new file mode 100644 index 0000000..08fe1ac --- /dev/null +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/util/ActionButton.java @@ -0,0 +1,75 @@ +/* + * 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.hierarchyviewer.util; + +import com.android.hierarchyviewer.actions.ImageAction; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; + +public class ActionButton implements IPropertyChangeListener, SelectionListener { + private Button button; + + private Action action; + + public ActionButton(Composite parent, ImageAction action) { + this.action = (Action) action; + if (this.action.getStyle() == Action.AS_CHECK_BOX) { + button = new Button(parent, SWT.CHECK); + } else { + button = new Button(parent, SWT.PUSH); + } + button.setText(action.getText()); + button.setImage(action.getImage()); + this.action.addPropertyChangeListener(this); + button.addSelectionListener(this); + button.setToolTipText(action.getToolTipText()); + } + + public void propertyChange(PropertyChangeEvent e) { + if (e.getProperty().toUpperCase().equals("ENABLED")) { + button.setEnabled((Boolean) e.getNewValue()); + } else if (e.getProperty().toUpperCase().equals("CHECKED")) { + button.setSelection(action.isChecked()); + } + } + + public void setLayoutData(Object data) { + button.setLayoutData(data); + } + + public void widgetDefaultSelected(SelectionEvent e) { + // pass + } + + public void widgetSelected(SelectionEvent e) { + if (action.getStyle() == Action.AS_CHECK_BOX) { + action.setChecked(button.getSelection()); + } + action.run(); + } + + public void addSelectionListener(SelectionListener listener) { + button.addSelectionListener(listener); + } +} |