10f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrev/*
20f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrev * Copyright (C) 2010 The Android Open Source Project
30f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrev *
40f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrev * Licensed under the Apache License, Version 2.0 (the "License");
50f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrev * you may not use this file except in compliance with the License.
60f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrev * You may obtain a copy of the License at
70f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrev *
80f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrev *      http://www.apache.org/licenses/LICENSE-2.0
90f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrev *
100f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrev * Unless required by applicable law or agreed to in writing, software
110f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrev * distributed under the License is distributed on an "AS IS" BASIS,
120f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrev * See the License for the specific language governing permissions and
140f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrev * limitations under the License.
150f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrev */
160f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrev
170f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrevpackage com.android.hierarchyviewer;
180f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrev
190a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohetimport com.android.ddmlib.Log;
2097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport com.android.ddmuilib.ImageLoader;
2197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport com.android.hierarchyviewer.actions.AboutAction;
2297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport com.android.hierarchyviewer.actions.LoadAllViewsAction;
2397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport com.android.hierarchyviewer.actions.QuitAction;
2497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport com.android.hierarchyviewer.actions.ShowOverlayAction;
2597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport com.android.hierarchyviewer.util.ActionButton;
26506d3f2ab9f2ec561a0b3ccd48fa017c24b9cefdKonstantin Lopyrevimport com.android.hierarchyviewerlib.HierarchyViewerDirector;
2799bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrevimport com.android.hierarchyviewerlib.actions.CapturePSDAction;
2899bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrevimport com.android.hierarchyviewerlib.actions.DisplayViewAction;
293fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haaseimport com.android.hierarchyviewerlib.actions.DumpDisplayListAction;
3099bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrevimport com.android.hierarchyviewerlib.actions.InspectScreenshotAction;
3199bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrevimport com.android.hierarchyviewerlib.actions.InvalidateAction;
3299bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrevimport com.android.hierarchyviewerlib.actions.LoadOverlayAction;
3399bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrevimport com.android.hierarchyviewerlib.actions.LoadViewHierarchyAction;
3499bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrevimport com.android.hierarchyviewerlib.actions.PixelPerfectAutoRefreshAction;
3599bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrevimport com.android.hierarchyviewerlib.actions.RefreshPixelPerfectAction;
3699bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrevimport com.android.hierarchyviewerlib.actions.RefreshPixelPerfectTreeAction;
3799bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrevimport com.android.hierarchyviewerlib.actions.RefreshViewAction;
3899bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrevimport com.android.hierarchyviewerlib.actions.RefreshWindowsAction;
3999bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrevimport com.android.hierarchyviewerlib.actions.RequestLayoutAction;
4099bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrevimport com.android.hierarchyviewerlib.actions.SavePixelPerfectAction;
4199bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrevimport com.android.hierarchyviewerlib.actions.SaveTreeViewAction;
423fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haaseimport com.android.hierarchyviewerlib.device.DeviceBridge.ViewServerInfo;
433fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haaseimport com.android.hierarchyviewerlib.models.DeviceSelectionModel;
44bc494ce06410728bef8a6fa25f3da361cb66df79Konstantin Lopyrevimport com.android.hierarchyviewerlib.models.PixelPerfectModel;
45901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrevimport com.android.hierarchyviewerlib.models.PixelPerfectModel.IImageChangeListener;
46f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohetimport com.android.hierarchyviewerlib.models.TreeViewModel;
47901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrevimport com.android.hierarchyviewerlib.models.TreeViewModel.ITreeChangeListener;
4897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport com.android.hierarchyviewerlib.ui.DeviceSelector;
4997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport com.android.hierarchyviewerlib.ui.LayoutViewer;
5097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport com.android.hierarchyviewerlib.ui.PixelPerfect;
5199bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrevimport com.android.hierarchyviewerlib.ui.PixelPerfectControls;
5297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport com.android.hierarchyviewerlib.ui.PixelPerfectLoupe;
5397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport com.android.hierarchyviewerlib.ui.PixelPerfectPixelPanel;
5497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport com.android.hierarchyviewerlib.ui.PixelPerfectTree;
5597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport com.android.hierarchyviewerlib.ui.PropertyViewer;
5697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport com.android.hierarchyviewerlib.ui.TreeView;
5799bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrevimport com.android.hierarchyviewerlib.ui.TreeViewControls;
5897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport com.android.hierarchyviewerlib.ui.TreeViewOverview;
599e1748f533f9d25dcedb50f9464b36588eec686bRaphael Mollimport com.android.menubar.IMenuBarEnhancer;
609e1748f533f9d25dcedb50f9464b36588eec686bRaphael Mollimport com.android.menubar.IMenuBarEnhancer.MenuBarMode;
61f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohetimport com.android.menubar.MenuBarEnhancer;
62506d3f2ab9f2ec561a0b3ccd48fa017c24b9cefdKonstantin Lopyrev
6397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.jface.action.MenuManager;
6497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.jface.action.Separator;
6597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.jface.window.ApplicationWindow;
6697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.SWT;
679e1748f533f9d25dcedb50f9464b36588eec686bRaphael Mollimport org.eclipse.swt.SWTException;
6897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.custom.SashForm;
6997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.custom.StackLayout;
7097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.events.SelectionEvent;
7197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.events.SelectionListener;
7297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.graphics.Image;
7397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.graphics.Rectangle;
7497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.layout.FillLayout;
7597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.layout.FormAttachment;
7697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.layout.FormData;
7797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.layout.FormLayout;
7897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.layout.GridData;
7997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.layout.GridLayout;
8097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.layout.RowLayout;
8197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.widgets.Button;
8297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.widgets.Composite;
8397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.widgets.Control;
8497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.widgets.Display;
8597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.widgets.Label;
8697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.widgets.ProgressBar;
8797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevimport org.eclipse.swt.widgets.Shell;
8897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
8997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrevpublic class HierarchyViewerApplication extends ApplicationWindow {
9097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
919e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll    private static final String APP_NAME = "Hierarchy Viewer";
923fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haase    private static final int INITIAL_WIDTH = 1280;
933fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haase    private static final int INITIAL_HEIGHT = 800;
9497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
950a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet    private static HierarchyViewerApplication sMainWindow;
9697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
97285f39916682c0f70a8dc9ccd930affa37365b97Konstantin Lopyrev    // Images for moving between the 3 main windows.
98901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Image mDeviceViewImage;
99901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Image mPixelPerfectImage;
100901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Image mTreeViewImage;
101901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Image mDeviceViewSelectedImage;
102901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Image mPixelPerfectSelectedImage;
103901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Image mTreeViewSelectedImage;
10497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
105285f39916682c0f70a8dc9ccd930affa37365b97Konstantin Lopyrev    // And their buttons
106901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Button mTreeViewButton;
107901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Button mPixelPerfectButton;
108901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Button mDeviceViewButton;
10997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
110901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Label mProgressLabel;
111901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private ProgressBar mProgressBar;
112901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private String mProgressString;
11397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
114901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Composite mDeviceSelectorPanel;
115901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Composite mTreeViewPanel;
116901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Composite mPixelPerfectPanel;
117901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private StackLayout mMainWindowStackLayout;
118901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private DeviceSelector mDeviceSelector;
119901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Composite mStatusBar;
120901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private TreeView mTreeView;
121901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Composite mMainWindow;
122901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Image mOnBlackImage;
123901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Image mOnWhiteImage;
124901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Button mOnBlackWhiteButton;
125901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Button mShowExtras;
126901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private LayoutViewer mLayoutViewer;
127901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private PixelPerfectLoupe mPixelPerfectLoupe;
128901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev    private Composite mTreeViewControls;
12997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
1303fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haase    private ActionButton dumpDisplayList;
1313fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haase
1320a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet    private HierarchyViewerDirector mDirector;
1330a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet
1340a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet    /*
1350a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet     * If a thread bails with an uncaught exception, bring the whole
1360a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet     * thing down.
1370a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet     */
1380a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet    private static class UncaughtHandler implements Thread.UncaughtExceptionHandler {
139f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
1400a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        public void uncaughtException(Thread t, Throwable e) {
1410a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet            Log.e("HierarchyViewer", "shutting down due to uncaught exception");
1420a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet            Log.e("HierarchyViewer", e);
1430a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet            System.exit(1);
1440a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        }
1450a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet    }
1460a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet
1470a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet    public static final HierarchyViewerApplication getMainWindow() {
1480a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        return sMainWindow;
14997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    }
15097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
15197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    public HierarchyViewerApplication() {
1520a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        super(null /*shell*/);
15397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
1540a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        sMainWindow = this;
15597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
15697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        addMenuBar();
15797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    }
15897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
15997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    @Override
16097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    protected void configureShell(Shell shell) {
16197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        super.configureShell(shell);
1629e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll        shell.setText(APP_NAME);
16397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
164b57b86a86ebecd02614a71b781a1cc128d8ee960Tor Norbye        Image image = imageLoader.loadImage("sdk-hierarchyviewer-128.png", Display.getDefault()); //$NON-NLS-1$
16597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        shell.setImage(image);
16697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    }
16797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
16897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    @Override
16997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    public MenuManager createMenuManager() {
17097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        return new MenuManager();
17197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    }
17297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
17397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    public void run() {
17497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        setBlockOnOpen(true);
17597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
1769e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll        try {
1779e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll            open();
1789e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll        } catch (SWTException e) {
1799e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll         // Ignore "widget disposed" errors after we closed.
1809e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll            if (!getShell().isDisposed()) {
1819e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll                throw e;
1829e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll            }
1839e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll        }
18497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
1850a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        TreeViewModel.getModel().removeTreeChangeListener(mTreeChangeListener);
1860a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        PixelPerfectModel.getModel().removeImageChangeListener(mImageChangeListener);
18797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
18897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        ImageLoader.dispose();
1890a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        mDirector.stopListenForDevices();
1900a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        mDirector.stopDebugBridge();
1910a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        mDirector.terminate();
19297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    }
19397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
19497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    @Override
19597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    protected void initializeBounds() {
19697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        Rectangle monitorArea = Display.getDefault().getPrimaryMonitor().getBounds();
19797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        getShell().setSize(Math.min(monitorArea.width, INITIAL_WIDTH),
19897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                Math.min(monitorArea.height, INITIAL_HEIGHT));
19997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        getShell().setLocation(monitorArea.x + (monitorArea.width - INITIAL_WIDTH) / 2,
20097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                monitorArea.y + (monitorArea.height - INITIAL_HEIGHT) / 2);
20197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    }
20297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
20397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    private void loadResources() {
20497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
205901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewImage = imageLoader.loadImage("tree-view.png", Display.getDefault()); //$NON-NLS-1$
206901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewSelectedImage =
207901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev                imageLoader.loadImage("tree-view-selected.png", Display.getDefault()); //$NON-NLS-1$
208901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectImage = imageLoader.loadImage("pixel-perfect-view.png", Display.getDefault()); //$NON-NLS-1$
209901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectSelectedImage =
210901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev                imageLoader.loadImage("pixel-perfect-view-selected.png", Display.getDefault()); //$NON-NLS-1$
211901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mDeviceViewImage = imageLoader.loadImage("device-view.png", Display.getDefault()); //$NON-NLS-1$
212901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mDeviceViewSelectedImage =
213901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev                imageLoader.loadImage("device-view-selected.png", Display.getDefault()); //$NON-NLS-1$
214901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mOnBlackImage = imageLoader.loadImage("on-black.png", Display.getDefault()); //$NON-NLS-1$
215901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mOnWhiteImage = imageLoader.loadImage("on-white.png", Display.getDefault()); //$NON-NLS-1$
21697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    }
21797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
21897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    @Override
21997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    protected Control createContents(Composite parent) {
2200a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        // create this only once the window is opened to please SWT on Mac
2210a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        mDirector = HierarchyViewerApplicationDirector.createDirector();
2220a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        mDirector.initDebugBridge();
2230a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        mDirector.startListenForDevices();
2240a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        mDirector.populateDeviceSelectionModel();
2250a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet
2260a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        TreeViewModel.getModel().addTreeChangeListener(mTreeChangeListener);
2270a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        PixelPerfectModel.getModel().addImageChangeListener(mImageChangeListener);
2280a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet
22997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        loadResources();
23097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
23197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        Composite control = new Composite(parent, SWT.NONE);
23297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        GridLayout mainLayout = new GridLayout();
23397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        mainLayout.marginHeight = mainLayout.marginWidth = 0;
23497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        mainLayout.verticalSpacing = mainLayout.horizontalSpacing = 0;
23597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        control.setLayout(mainLayout);
236901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mMainWindow = new Composite(control, SWT.NONE);
237901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mMainWindow.setLayoutData(new GridData(GridData.FILL_BOTH));
238901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mMainWindowStackLayout = new StackLayout();
239901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mMainWindow.setLayout(mMainWindowStackLayout);
24097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
241901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        buildDeviceSelectorPanel(mMainWindow);
242901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        buildTreeViewPanel(mMainWindow);
243901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        buildPixelPerfectPanel(mMainWindow);
24497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
24597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        buildStatusBar(control);
24697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
24797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        showDeviceSelector();
24897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
24997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        return control;
25097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    }
25197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
252285f39916682c0f70a8dc9ccd930affa37365b97Konstantin Lopyrev
25397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    private void buildStatusBar(Composite parent) {
254901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mStatusBar = new Composite(parent, SWT.NONE);
255901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mStatusBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
25697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
25797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        FormLayout statusBarLayout = new FormLayout();
25897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        statusBarLayout.marginHeight = statusBarLayout.marginWidth = 2;
25997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
260901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mStatusBar.setLayout(statusBarLayout);
26197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
262901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mDeviceViewButton = new Button(mStatusBar, SWT.TOGGLE);
263901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mDeviceViewButton.setImage(mDeviceViewImage);
264901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mDeviceViewButton.setToolTipText("Switch to the window selection view");
265901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mDeviceViewButton.addSelectionListener(deviceViewButtonSelectionListener);
26697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        FormData deviceViewButtonFormData = new FormData();
26797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        deviceViewButtonFormData.left = new FormAttachment();
268901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mDeviceViewButton.setLayoutData(deviceViewButtonFormData);
26997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
270901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewButton = new Button(mStatusBar, SWT.TOGGLE);
271901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewButton.setImage(mTreeViewImage);
272901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewButton.setEnabled(false);
273901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewButton.setToolTipText("Switch to the tree view");
274901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewButton.addSelectionListener(treeViewButtonSelectionListener);
27597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        FormData treeViewButtonFormData = new FormData();
276901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        treeViewButtonFormData.left = new FormAttachment(mDeviceViewButton, 2);
277901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewButton.setLayoutData(treeViewButtonFormData);
278901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev
279901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectButton = new Button(mStatusBar, SWT.TOGGLE);
280901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectButton.setImage(mPixelPerfectImage);
281901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectButton.setEnabled(false);
282901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectButton.setToolTipText("Switch to the pixel perfect view");
283901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectButton.addSelectionListener(pixelPerfectButtonSelectionListener);
28497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        FormData pixelPerfectButtonFormData = new FormData();
285901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        pixelPerfectButtonFormData.left = new FormAttachment(mTreeViewButton, 2);
286901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectButton.setLayoutData(pixelPerfectButtonFormData);
28797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
288285f39916682c0f70a8dc9ccd930affa37365b97Konstantin Lopyrev        // Tree View control panel...
289901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewControls = new TreeViewControls(mStatusBar);
29099bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrev        FormData treeViewControlsFormData = new FormData();
291901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        treeViewControlsFormData.left = new FormAttachment(mPixelPerfectButton, 2);
292901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        treeViewControlsFormData.top = new FormAttachment(mTreeViewButton, 0, SWT.CENTER);
29399bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrev        treeViewControlsFormData.width = 552;
294901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewControls.setLayoutData(treeViewControlsFormData);
295285f39916682c0f70a8dc9ccd930affa37365b97Konstantin Lopyrev
296285f39916682c0f70a8dc9ccd930affa37365b97Konstantin Lopyrev        // Progress stuff
297901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mProgressLabel = new Label(mStatusBar, SWT.RIGHT);
298285f39916682c0f70a8dc9ccd930affa37365b97Konstantin Lopyrev
299901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mProgressBar = new ProgressBar(mStatusBar, SWT.HORIZONTAL | SWT.INDETERMINATE | SWT.SMOOTH);
300285f39916682c0f70a8dc9ccd930affa37365b97Konstantin Lopyrev        FormData progressBarFormData = new FormData();
301285f39916682c0f70a8dc9ccd930affa37365b97Konstantin Lopyrev        progressBarFormData.right = new FormAttachment(100, 0);
302901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        progressBarFormData.top = new FormAttachment(mTreeViewButton, 0, SWT.CENTER);
303901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mProgressBar.setLayoutData(progressBarFormData);
304285f39916682c0f70a8dc9ccd930affa37365b97Konstantin Lopyrev
305285f39916682c0f70a8dc9ccd930affa37365b97Konstantin Lopyrev        FormData progressLabelFormData = new FormData();
306901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        progressLabelFormData.right = new FormAttachment(mProgressBar, -2);
307901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        progressLabelFormData.top = new FormAttachment(mTreeViewButton, 0, SWT.CENTER);
308901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mProgressLabel.setLayoutData(progressLabelFormData);
309285f39916682c0f70a8dc9ccd930affa37365b97Konstantin Lopyrev
310901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        if (mProgressString == null) {
311901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev            mProgressLabel.setVisible(false);
312901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev            mProgressBar.setVisible(false);
313285f39916682c0f70a8dc9ccd930affa37365b97Konstantin Lopyrev        } else {
314901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev            mProgressLabel.setText(mProgressString);
315285f39916682c0f70a8dc9ccd930affa37365b97Konstantin Lopyrev        }
31697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    }
31797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
31897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    private void buildDeviceSelectorPanel(Composite parent) {
319901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mDeviceSelectorPanel = new Composite(parent, SWT.NONE);
32097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        GridLayout gridLayout = new GridLayout();
32197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        gridLayout.marginWidth = gridLayout.marginHeight = 0;
32297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0;
323901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mDeviceSelectorPanel.setLayout(gridLayout);
32497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
325901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        Composite buttonPanel = new Composite(mDeviceSelectorPanel, SWT.NONE);
32697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        buttonPanel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
32797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
32897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        GridLayout buttonLayout = new GridLayout();
32997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        buttonLayout.marginWidth = buttonLayout.marginHeight = 0;
33097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        buttonLayout.horizontalSpacing = buttonLayout.verticalSpacing = 0;
33197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        buttonPanel.setLayout(buttonLayout);
33297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
33397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        Composite innerButtonPanel = new Composite(buttonPanel, SWT.NONE);
33497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        innerButtonPanel.setLayoutData(new GridData(GridData.FILL_VERTICAL));
33597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        GridLayout innerButtonPanelLayout = new GridLayout(3, true);
33697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        innerButtonPanelLayout.marginWidth = innerButtonPanelLayout.marginHeight = 2;
33797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        innerButtonPanelLayout.horizontalSpacing = innerButtonPanelLayout.verticalSpacing = 2;
33897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        innerButtonPanel.setLayout(innerButtonPanelLayout);
33997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
34097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        ActionButton refreshWindows =
34197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                new ActionButton(innerButtonPanel, RefreshWindowsAction.getAction());
34297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        refreshWindows.setLayoutData(new GridData(GridData.FILL_BOTH));
34397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
34497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        ActionButton loadViewHierarchyButton =
34597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                new ActionButton(innerButtonPanel, LoadViewHierarchyAction.getAction());
34697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        loadViewHierarchyButton.setLayoutData(new GridData(GridData.FILL_BOTH));
34797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
34897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        ActionButton inspectScreenshotButton =
34997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                new ActionButton(innerButtonPanel, InspectScreenshotAction.getAction());
35097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        inspectScreenshotButton.setLayoutData(new GridData(GridData.FILL_BOTH));
35197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
352901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        Composite deviceSelectorContainer = new Composite(mDeviceSelectorPanel, SWT.BORDER);
35397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        deviceSelectorContainer.setLayoutData(new GridData(GridData.FILL_BOTH));
35497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        deviceSelectorContainer.setLayout(new FillLayout());
355901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mDeviceSelector = new DeviceSelector(deviceSelectorContainer, true, true);
35697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    }
35797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
35897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    public void buildTreeViewPanel(Composite parent) {
359901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewPanel = new Composite(parent, SWT.NONE);
36097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        GridLayout gridLayout = new GridLayout();
36197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        gridLayout.marginWidth = gridLayout.marginHeight = 0;
36297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0;
363901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewPanel.setLayout(gridLayout);
36497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
365901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        Composite buttonPanel = new Composite(mTreeViewPanel, SWT.NONE);
36697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        buttonPanel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
36797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
36897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        GridLayout buttonLayout = new GridLayout();
36997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        buttonLayout.marginWidth = buttonLayout.marginHeight = 0;
37097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        buttonLayout.horizontalSpacing = buttonLayout.verticalSpacing = 0;
37197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        buttonPanel.setLayout(buttonLayout);
37297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
37397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        Composite innerButtonPanel = new Composite(buttonPanel, SWT.NONE);
37497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        innerButtonPanel.setLayoutData(new GridData(GridData.FILL_VERTICAL));
3753fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haase        GridLayout innerButtonPanelLayout = new GridLayout(7, true);
37697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        innerButtonPanelLayout.marginWidth = innerButtonPanelLayout.marginHeight = 2;
37797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        innerButtonPanelLayout.horizontalSpacing = innerButtonPanelLayout.verticalSpacing = 2;
37897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        innerButtonPanel.setLayout(innerButtonPanelLayout);
37997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
38097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        ActionButton saveTreeView =
38197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                new ActionButton(innerButtonPanel, SaveTreeViewAction.getAction(getShell()));
38297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        saveTreeView.setLayoutData(new GridData(GridData.FILL_BOTH));
38397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
38497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        ActionButton capturePSD =
38597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                new ActionButton(innerButtonPanel, CapturePSDAction.getAction(getShell()));
38697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        capturePSD.setLayoutData(new GridData(GridData.FILL_BOTH));
38797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
38897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        ActionButton refreshViewAction =
38997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                new ActionButton(innerButtonPanel, RefreshViewAction.getAction());
39097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        refreshViewAction.setLayoutData(new GridData(GridData.FILL_BOTH));
39197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
39297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        ActionButton displayView =
39397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                new ActionButton(innerButtonPanel, DisplayViewAction.getAction(getShell()));
39497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        displayView.setLayoutData(new GridData(GridData.FILL_BOTH));
39597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
39697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        ActionButton invalidate = new ActionButton(innerButtonPanel, InvalidateAction.getAction());
39797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        invalidate.setLayoutData(new GridData(GridData.FILL_BOTH));
39897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
39997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        ActionButton requestLayout =
40097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                new ActionButton(innerButtonPanel, RequestLayoutAction.getAction());
40197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        requestLayout.setLayoutData(new GridData(GridData.FILL_BOTH));
40297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
4033fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haase        dumpDisplayList =
4043fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haase                new ActionButton(innerButtonPanel, DumpDisplayListAction.getAction());
4053fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haase        dumpDisplayList.setLayoutData(new GridData(GridData.FILL_BOTH));
4063fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haase
407901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        SashForm mainSash = new SashForm(mTreeViewPanel, SWT.HORIZONTAL | SWT.SMOOTH);
40897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        mainSash.setLayoutData(new GridData(GridData.FILL_BOTH));
40997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        Composite treeViewContainer = new Composite(mainSash, SWT.BORDER);
41097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        treeViewContainer.setLayout(new FillLayout());
411901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeView = new TreeView(treeViewContainer);
41297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
41397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        SashForm sideSash = new SashForm(mainSash, SWT.VERTICAL | SWT.SMOOTH);
41497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
41597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        mainSash.SASH_WIDTH = 4;
41697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        mainSash.setWeights(new int[] {
41797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                7, 3
41897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        });
41997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
42097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        Composite treeViewOverviewContainer = new Composite(sideSash, SWT.BORDER);
42197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        treeViewOverviewContainer.setLayout(new FillLayout());
42299bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrev        new TreeViewOverview(treeViewOverviewContainer);
42397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
42497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        Composite propertyViewerContainer = new Composite(sideSash, SWT.BORDER);
42597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        propertyViewerContainer.setLayout(new FillLayout());
42699bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrev        new PropertyViewer(propertyViewerContainer);
42797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
42897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        Composite layoutViewerContainer = new Composite(sideSash, SWT.NONE);
42997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        GridLayout layoutViewerLayout = new GridLayout();
43097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        layoutViewerLayout.marginWidth = layoutViewerLayout.marginHeight = 0;
43197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        layoutViewerLayout.horizontalSpacing = layoutViewerLayout.verticalSpacing = 1;
43297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        layoutViewerContainer.setLayout(layoutViewerLayout);
43397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
43497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        Composite fullButtonBar = new Composite(layoutViewerContainer, SWT.NONE);
43597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        fullButtonBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
43697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        GridLayout fullButtonBarLayout = new GridLayout(2, false);
43797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        fullButtonBarLayout.marginWidth = fullButtonBarLayout.marginHeight = 0;
43897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        fullButtonBarLayout.marginRight = 2;
43997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        fullButtonBarLayout.horizontalSpacing = fullButtonBarLayout.verticalSpacing = 0;
44097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        fullButtonBar.setLayout(fullButtonBarLayout);
44197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
44297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        Composite buttonBar = new Composite(fullButtonBar, SWT.NONE);
44397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        buttonBar.setLayoutData(new GridData(GridData.FILL_VERTICAL));
44497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        RowLayout rowLayout = new RowLayout(SWT.HORIZONTAL);
44597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        rowLayout.marginLeft =
44697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                rowLayout.marginRight = rowLayout.marginTop = rowLayout.marginBottom = 0;
44797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        rowLayout.pack = true;
44897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        rowLayout.center = true;
44997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        buttonBar.setLayout(rowLayout);
45097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
451901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mOnBlackWhiteButton = new Button(buttonBar, SWT.PUSH);
452901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mOnBlackWhiteButton.setImage(mOnWhiteImage);
453901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mOnBlackWhiteButton.addSelectionListener(onBlackWhiteSelectionListener);
454901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mOnBlackWhiteButton.setToolTipText("Change layout viewer background color");
45597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
456901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mShowExtras = new Button(buttonBar, SWT.CHECK);
457901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mShowExtras.setText("Show Extras");
458901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mShowExtras.addSelectionListener(showExtrasSelectionListener);
459901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mShowExtras.setToolTipText("Show images");
46097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
46197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        ActionButton loadAllViewsButton =
46297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                new ActionButton(fullButtonBar, LoadAllViewsAction.getAction());
46397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        loadAllViewsButton.setLayoutData(new GridData(GridData.END, GridData.CENTER, true, true));
46497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        loadAllViewsButton.addSelectionListener(loadAllViewsSelectionListener);
46597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
46697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        Composite layoutViewerMainContainer = new Composite(layoutViewerContainer, SWT.BORDER);
46797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        layoutViewerMainContainer.setLayoutData(new GridData(GridData.FILL_BOTH));
46897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        layoutViewerMainContainer.setLayout(new FillLayout());
469901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mLayoutViewer = new LayoutViewer(layoutViewerMainContainer);
47097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
47197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        sideSash.SASH_WIDTH = 4;
47297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        sideSash.setWeights(new int[] {
47397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                238, 332, 416
47497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        });
47597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
47697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    }
47797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
47897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    private void buildPixelPerfectPanel(Composite parent) {
479901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectPanel = new Composite(parent, SWT.NONE);
48097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        GridLayout gridLayout = new GridLayout();
48197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        gridLayout.marginWidth = gridLayout.marginHeight = 0;
48297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0;
483901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectPanel.setLayout(gridLayout);
48497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
485901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        Composite buttonPanel = new Composite(mPixelPerfectPanel, SWT.NONE);
48697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        buttonPanel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
48797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
48897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        GridLayout buttonLayout = new GridLayout();
48997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        buttonLayout.marginWidth = buttonLayout.marginHeight = 0;
49097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        buttonLayout.horizontalSpacing = buttonLayout.verticalSpacing = 0;
49197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        buttonPanel.setLayout(buttonLayout);
49297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
49397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        Composite innerButtonPanel = new Composite(buttonPanel, SWT.NONE);
49497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        innerButtonPanel.setLayoutData(new GridData(GridData.FILL_VERTICAL));
49597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        GridLayout innerButtonPanelLayout = new GridLayout(6, true);
49697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        innerButtonPanelLayout.marginWidth = innerButtonPanelLayout.marginHeight = 2;
49797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        innerButtonPanelLayout.horizontalSpacing = innerButtonPanelLayout.verticalSpacing = 2;
49897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        innerButtonPanel.setLayout(innerButtonPanelLayout);
49997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
50097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        ActionButton saveTreeView =
50197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                new ActionButton(innerButtonPanel, SavePixelPerfectAction.getAction(getShell()));
50297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        saveTreeView.setLayoutData(new GridData(GridData.FILL_BOTH));
50397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
50497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        ActionButton refreshPixelPerfect =
50597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                new ActionButton(innerButtonPanel, RefreshPixelPerfectAction.getAction());
50697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        refreshPixelPerfect.setLayoutData(new GridData(GridData.FILL_BOTH));
50797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
50897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        ActionButton refreshPixelPerfectTree =
50997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                new ActionButton(innerButtonPanel, RefreshPixelPerfectTreeAction.getAction());
51097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        refreshPixelPerfectTree.setLayoutData(new GridData(GridData.FILL_BOTH));
51197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
51297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        ActionButton loadOverlay =
51397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                new ActionButton(innerButtonPanel, LoadOverlayAction.getAction(getShell()));
51497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        loadOverlay.setLayoutData(new GridData(GridData.FILL_BOTH));
51597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
51697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        ActionButton showInLoupe =
51797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                new ActionButton(innerButtonPanel, ShowOverlayAction.getAction());
51897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        showInLoupe.setLayoutData(new GridData(GridData.FILL_BOTH));
51997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
52097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        ActionButton autoRefresh =
52197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                new ActionButton(innerButtonPanel, PixelPerfectAutoRefreshAction.getAction());
52297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        autoRefresh.setLayoutData(new GridData(GridData.FILL_BOTH));
52397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
524901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        SashForm mainSash = new SashForm(mPixelPerfectPanel, SWT.HORIZONTAL | SWT.SMOOTH);
52597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        mainSash.setLayoutData(new GridData(GridData.FILL_BOTH));
52697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        mainSash.SASH_WIDTH = 4;
52797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
52897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        Composite pixelPerfectTreeContainer = new Composite(mainSash, SWT.BORDER);
52997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        pixelPerfectTreeContainer.setLayout(new FillLayout());
53099bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrev        new PixelPerfectTree(pixelPerfectTreeContainer);
53197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
53297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        Composite pixelPerfectLoupeContainer = new Composite(mainSash, SWT.NONE);
53397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        GridLayout loupeLayout = new GridLayout();
53497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        loupeLayout.marginWidth = loupeLayout.marginHeight = 0;
53597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        loupeLayout.horizontalSpacing = loupeLayout.verticalSpacing = 0;
53697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        pixelPerfectLoupeContainer.setLayout(loupeLayout);
53797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
53897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        Composite pixelPerfectLoupeBorder = new Composite(pixelPerfectLoupeContainer, SWT.BORDER);
53997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        pixelPerfectLoupeBorder.setLayoutData(new GridData(GridData.FILL_BOTH));
54097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        GridLayout pixelPerfectLoupeBorderGridLayout = new GridLayout();
54197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        pixelPerfectLoupeBorderGridLayout.marginWidth =
54297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                pixelPerfectLoupeBorderGridLayout.marginHeight = 0;
54397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        pixelPerfectLoupeBorderGridLayout.horizontalSpacing =
54497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                pixelPerfectLoupeBorderGridLayout.verticalSpacing = 0;
54597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        pixelPerfectLoupeBorder.setLayout(pixelPerfectLoupeBorderGridLayout);
54697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
547901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectLoupe = new PixelPerfectLoupe(pixelPerfectLoupeBorder);
548901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectLoupe.setLayoutData(new GridData(GridData.FILL_BOTH));
54997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
55097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        PixelPerfectPixelPanel pixelPerfectPixelPanel =
55197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                new PixelPerfectPixelPanel(pixelPerfectLoupeBorder);
55297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        pixelPerfectPixelPanel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
55397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
55499bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrev        PixelPerfectControls pixelPerfectControls =
55599bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrev                new PixelPerfectControls(pixelPerfectLoupeContainer);
55697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        pixelPerfectControls.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
55799bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrev
55897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
55997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        Composite pixelPerfectContainer = new Composite(mainSash, SWT.BORDER);
56097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        pixelPerfectContainer.setLayout(new FillLayout());
56199bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrev        new PixelPerfect(pixelPerfectContainer);
56297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
56397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        mainSash.setWeights(new int[] {
56497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                272, 376, 346
56597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        });
56697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
56797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    }
56897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
56997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    public void showOverlayInLoupe(boolean value) {
570901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectLoupe.setShowOverlay(value);
57197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    }
57297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
573285f39916682c0f70a8dc9ccd930affa37365b97Konstantin Lopyrev    // Shows the progress notification...
57497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    public void startTask(final String taskName) {
575901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mProgressString = taskName;
57697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        Display.getDefault().syncExec(new Runnable() {
577f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet            @Override
57897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            public void run() {
579901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev                if (mProgressLabel != null && mProgressBar != null) {
580901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev                    mProgressLabel.setText(taskName);
581901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev                    mProgressLabel.setVisible(true);
582901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev                    mProgressBar.setVisible(true);
583901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev                    mStatusBar.layout();
58497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                }
58597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            }
58697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        });
58797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    }
58897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
589285f39916682c0f70a8dc9ccd930affa37365b97Konstantin Lopyrev    // And hides it!
59097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    public void endTask() {
591901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mProgressString = null;
59297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        Display.getDefault().syncExec(new Runnable() {
593f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet            @Override
59497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            public void run() {
595901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev                if (mProgressLabel != null && mProgressBar != null) {
596901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev                    mProgressLabel.setVisible(false);
597901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev                    mProgressBar.setVisible(false);
59897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                }
59997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            }
60097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        });
60197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    }
60297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
60397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    public void showDeviceSelector() {
60497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        // Show the menus.
60597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        MenuManager mm = getMenuBarManager();
60697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        mm.removeAll();
60797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
6089e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll        MenuManager file = new MenuManager("&File");
6099e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll        IMenuBarEnhancer enhancer = MenuBarEnhancer.setupMenuManager(
6109e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll                APP_NAME,
6119e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll                getShell().getDisplay(),
6129e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll                file,
6139e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll                AboutAction.getAction(getShell()),
6149e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll                null /*preferencesAction*/,
6159e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll                QuitAction.getAction());
6169e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll        if (enhancer.getMenuBarMode() == MenuBarMode.GENERIC) {
6170a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet            mm.add(file);
6180a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        }
61997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
62097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        MenuManager device = new MenuManager("&Devices");
62197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        mm.add(device);
62297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
62397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        device.add(RefreshWindowsAction.getAction());
62497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        device.add(LoadViewHierarchyAction.getAction());
62597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        device.add(InspectScreenshotAction.getAction());
62697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
62797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        mm.updateAll(true);
62897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
629901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mDeviceViewButton.setSelection(true);
630901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mDeviceViewButton.setImage(mDeviceViewSelectedImage);
63197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
632901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewButton.setSelection(false);
633901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewButton.setImage(mTreeViewImage);
63497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
635901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectButton.setSelection(false);
636901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectButton.setImage(mPixelPerfectImage);
63797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
638901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mMainWindowStackLayout.topControl = mDeviceSelectorPanel;
63997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
640901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mMainWindow.layout();
64197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
642901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mDeviceSelector.setFocus();
64397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
644901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewControls.setVisible(false);
64597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    }
64697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
64797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    public void showTreeView() {
64897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        // Show the menus.
64997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        MenuManager mm = getMenuBarManager();
65097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        mm.removeAll();
65197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
6529e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll        MenuManager file = new MenuManager("&File");
6539e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll        IMenuBarEnhancer enhancer = MenuBarEnhancer.setupMenuManager(
6549e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll                APP_NAME,
6559e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll                getShell().getDisplay(),
6569e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll                file,
6579e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll                AboutAction.getAction(getShell()),
6589e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll                null /*preferencesAction*/,
6599e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll                QuitAction.getAction());
6609e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll        if (enhancer.getMenuBarMode() == MenuBarMode.GENERIC) {
6610a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet            mm.add(file);
6620a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        }
66397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
66497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        MenuManager treeViewMenu = new MenuManager("&Tree View");
66597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        mm.add(treeViewMenu);
66697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
66797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        treeViewMenu.add(SaveTreeViewAction.getAction(getShell()));
66897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        treeViewMenu.add(CapturePSDAction.getAction(getShell()));
66997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        treeViewMenu.add(new Separator());
67097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        treeViewMenu.add(RefreshViewAction.getAction());
67197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        treeViewMenu.add(DisplayViewAction.getAction(getShell()));
6723fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haase        // Only make the DumpDisplayList action visible if the protocol supports it.
6733fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haase        ViewServerInfo info = DeviceSelectionModel.getModel().getSelectedDeviceInfo();
6743fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haase        if (info != null && info.protocolVersion >= 4) {
6753fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haase            treeViewMenu.add(DumpDisplayListAction.getAction());
6763fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haase            dumpDisplayList.setVisible(true);
6773fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haase        } else {
6783fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haase            dumpDisplayList.setVisible(false);
6793fe16ced4294bdeeab31008e93b5e2d004da7437Chet Haase        }
68097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        treeViewMenu.add(new Separator());
68197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        treeViewMenu.add(InvalidateAction.getAction());
68297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        treeViewMenu.add(RequestLayoutAction.getAction());
68397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
68497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        mm.updateAll(true);
68597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
686901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mDeviceViewButton.setSelection(false);
687901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mDeviceViewButton.setImage(mDeviceViewImage);
68897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
689901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewButton.setSelection(true);
690901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewButton.setImage(mTreeViewSelectedImage);
69197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
692901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectButton.setSelection(false);
693901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectButton.setImage(mPixelPerfectImage);
69497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
695901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mMainWindowStackLayout.topControl = mTreeViewPanel;
69697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
697901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mMainWindow.layout();
69897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
699901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeView.setFocus();
70097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
701901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewControls.setVisible(true);
70297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    }
70397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
70497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    public void showPixelPerfect() {
70597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        // Show the menus.
70697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        MenuManager mm = getMenuBarManager();
70797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        mm.removeAll();
70897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
7099e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll        MenuManager file = new MenuManager("&File");
7109e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll        IMenuBarEnhancer enhancer = MenuBarEnhancer.setupMenuManager(
7119e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll                APP_NAME,
7129e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll                getShell().getDisplay(),
7139e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll                file,
7149e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll                AboutAction.getAction(getShell()),
7159e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll                null /*preferencesAction*/,
7169e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll                QuitAction.getAction());
7179e1748f533f9d25dcedb50f9464b36588eec686bRaphael Moll        if (enhancer.getMenuBarMode() == MenuBarMode.GENERIC) {
7180a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet            mm.add(file);
7190a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        }
72097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
72197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        MenuManager pixelPerfect = new MenuManager("&Pixel Perfect");
72297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        pixelPerfect.add(SavePixelPerfectAction.getAction(getShell()));
72397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        pixelPerfect.add(RefreshPixelPerfectAction.getAction());
72497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        pixelPerfect.add(RefreshPixelPerfectTreeAction.getAction());
72597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        pixelPerfect.add(PixelPerfectAutoRefreshAction.getAction());
72697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        pixelPerfect.add(new Separator());
72797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        pixelPerfect.add(LoadOverlayAction.getAction(getShell()));
72897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        pixelPerfect.add(ShowOverlayAction.getAction());
72997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
73097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        mm.add(pixelPerfect);
73197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
73297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        mm.updateAll(true);
73397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
734901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mDeviceViewButton.setSelection(false);
735901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mDeviceViewButton.setImage(mDeviceViewImage);
73697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
737901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewButton.setSelection(false);
738901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewButton.setImage(mTreeViewImage);
73997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
740901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectButton.setSelection(true);
741901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectButton.setImage(mPixelPerfectSelectedImage);
74297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
743901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mMainWindowStackLayout.topControl = mPixelPerfectPanel;
74497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
745901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mMainWindow.layout();
74697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
747901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mPixelPerfectLoupe.setFocus();
74897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
749901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev        mTreeViewControls.setVisible(false);
75097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    }
75197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
75297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    private SelectionListener deviceViewButtonSelectionListener = new SelectionListener() {
753f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
75497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void widgetDefaultSelected(SelectionEvent e) {
75597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            // pass
75697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
75797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
758f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
75997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void widgetSelected(SelectionEvent e) {
760901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev            mDeviceViewButton.setSelection(true);
76197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            showDeviceSelector();
76297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
76397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    };
76497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
76597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    private SelectionListener treeViewButtonSelectionListener = new SelectionListener() {
766f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
76797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void widgetDefaultSelected(SelectionEvent e) {
76897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            // pass
76997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
77097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
771f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
77297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void widgetSelected(SelectionEvent e) {
773901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev            mTreeViewButton.setSelection(true);
77497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            showTreeView();
77597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
77697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    };
77797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
77897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    private SelectionListener pixelPerfectButtonSelectionListener = new SelectionListener() {
779f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
78097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void widgetDefaultSelected(SelectionEvent e) {
78197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            // pass
78297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
78397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
784f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
78597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void widgetSelected(SelectionEvent e) {
786901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev            mPixelPerfectButton.setSelection(true);
78797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            showPixelPerfect();
78897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
78997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    };
79097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
79197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    private SelectionListener onBlackWhiteSelectionListener = new SelectionListener() {
792f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
79397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void widgetDefaultSelected(SelectionEvent e) {
79497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            // pass
79597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
79697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
797f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
79897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void widgetSelected(SelectionEvent e) {
799901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev            if (mLayoutViewer.getOnBlack()) {
800901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev                mLayoutViewer.setOnBlack(false);
801901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev                mOnBlackWhiteButton.setImage(mOnBlackImage);
80297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            } else {
803901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev                mLayoutViewer.setOnBlack(true);
804901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev                mOnBlackWhiteButton.setImage(mOnWhiteImage);
80597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            }
80697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
80797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    };
80897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
80997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    private SelectionListener showExtrasSelectionListener = new SelectionListener() {
810f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
81197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void widgetDefaultSelected(SelectionEvent e) {
81297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            // pass
81397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
81497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
815f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
81697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void widgetSelected(SelectionEvent e) {
817901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev            mLayoutViewer.setShowExtras(mShowExtras.getSelection());
81897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
81997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    };
82097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
82197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    private SelectionListener loadAllViewsSelectionListener = new SelectionListener() {
822f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
82397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void widgetDefaultSelected(SelectionEvent e) {
82497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            // pass
82597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
82697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
827f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
82897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void widgetSelected(SelectionEvent e) {
829901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev            mShowExtras.setSelection(true);
83097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            showExtrasSelectionListener.widgetSelected(null);
83197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
83297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    };
83397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
8340a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet    private ITreeChangeListener mTreeChangeListener = new ITreeChangeListener() {
835f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
83697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void selectionChanged() {
83797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            // pass
83897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
83997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
840f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
84197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void treeChanged() {
84297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            Display.getDefault().syncExec(new Runnable() {
843f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet                @Override
84497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                public void run() {
84597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                    if (TreeViewModel.getModel().getTree() == null) {
84697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                        showDeviceSelector();
847901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev                        mTreeViewButton.setEnabled(false);
84897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                    } else {
84997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                        showTreeView();
850901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev                        mTreeViewButton.setEnabled(true);
85197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                    }
85297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                }
85397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            });
85497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
85597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
856f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
85797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void viewportChanged() {
85897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            // pass
85997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
86097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
861f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
86297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void zoomChanged() {
86397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            // pass
86497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
86597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    };
86697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
8670a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet    private IImageChangeListener mImageChangeListener = new IImageChangeListener() {
86897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
869f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
87097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void crosshairMoved() {
87197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            // pass
87297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
87397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
874f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
87597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void treeChanged() {
87697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            // pass
87797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
87897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
879f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
88097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void imageChanged() {
88197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            // pass
88297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
88397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
884f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
88597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void imageLoaded() {
88697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            Display.getDefault().syncExec(new Runnable() {
887f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet                @Override
88897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                public void run() {
88997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                    if (PixelPerfectModel.getModel().getImage() == null) {
890901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev                        mPixelPerfectButton.setEnabled(false);
89197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                        showDeviceSelector();
89297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                    } else {
893901803a3b2aaeafb4074974ec5bf9b08cc39d1c8Konstantin Lopyrev                        mPixelPerfectButton.setEnabled(true);
89497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                        showPixelPerfect();
89597b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                    }
89697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev                }
89797b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            });
89897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
89997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
900f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
90197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void overlayChanged() {
90299bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrev            // pass
90397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
90497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
905f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
90697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void overlayTransparencyChanged() {
90799bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrev            // pass
90897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
90997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
910f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
91197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void selectionChanged() {
91297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev            // pass
91397b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
91497b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
915f526dc3bb658b07c5a96d0372b17ffa2fbbe6079Xavier Ducrohet        @Override
91697b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        public void zoomChanged() {
91799bd6912e7b5b97fc6d4bb787e76b2d9dfffd7aeKonstantin Lopyrev            // pass
91897b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev        }
91997b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
92097b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    };
92197b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev
92297b0639645d9c387cdd9884272e053c467a240daKonstantin Lopyrev    public static void main(String[] args) {
9230a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());
9240a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet
9250a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        Display.setAppName("HierarchyViewer");
9260a0569e3fe943aeed5845eed67ff4cfe8fc0b903Xavier Ducrohet        new HierarchyViewerApplication().run();
9270f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrev    }
9280f317518ceb4687a14b97c813682b78654033aa8Konstantin Lopyrev}
929