1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.ide.eclipse.adt.internal.editors.layout.gle2; 18 19 import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate; 20 import com.android.ide.eclipse.adt.internal.editors.layout.gre.RulesEngine; 21 22 import org.eclipse.core.runtime.ListenerList; 23 import org.eclipse.jface.util.SafeRunnable; 24 import org.eclipse.jface.viewers.IPostSelectionProvider; 25 import org.eclipse.jface.viewers.ISelection; 26 import org.eclipse.jface.viewers.ISelectionChangedListener; 27 import org.eclipse.jface.viewers.ISelectionProvider; 28 import org.eclipse.jface.viewers.SelectionChangedEvent; 29 import org.eclipse.jface.viewers.TreePath; 30 import org.eclipse.jface.viewers.TreeSelection; 31 import org.eclipse.jface.viewers.Viewer; 32 import org.eclipse.swt.widgets.Composite; 33 import org.eclipse.swt.widgets.Control; 34 35 36 /** 37 * JFace {@link Viewer} wrapper around {@link LayoutCanvas}. 38 * <p/> 39 * The viewer is owned by {@link GraphicalEditorPart}. 40 * <p/> 41 * The viewer is an {@link ISelectionProvider} instance and is set as the 42 * site's main {@link ISelectionProvider} by the editor part. Consequently 43 * canvas' selection changes are broadcasted to anyone listening, which includes 44 * the part itself as well as the associated outline and property sheet pages. 45 */ 46 class LayoutCanvasViewer extends Viewer implements IPostSelectionProvider { 47 48 private LayoutCanvas mCanvas; 49 private final LayoutEditorDelegate mEditorDelegate; 50 51 public LayoutCanvasViewer(LayoutEditorDelegate editorDelegate, 52 RulesEngine rulesEngine, 53 Composite parent, 54 int style) { 55 mEditorDelegate = editorDelegate; 56 mCanvas = new LayoutCanvas(editorDelegate, rulesEngine, parent, style); 57 58 mCanvas.getSelectionManager().addSelectionChangedListener(mSelectionListener); 59 } 60 61 private ISelectionChangedListener mSelectionListener = new ISelectionChangedListener() { 62 @Override 63 public void selectionChanged(SelectionChangedEvent event) { 64 fireSelectionChanged(event); 65 firePostSelectionChanged(event); 66 } 67 }; 68 69 @Override 70 public Control getControl() { 71 return mCanvas; 72 } 73 74 /** 75 * Returns the underlying {@link LayoutCanvas}. 76 * This is the same control as returned by {@link #getControl()} but clients 77 * have it already casted in the right type. 78 * <p/> 79 * This can never be null. 80 * @return The underlying {@link LayoutCanvas}. 81 */ 82 public LayoutCanvas getCanvas() { 83 return mCanvas; 84 } 85 86 /** 87 * Returns the current layout editor's input. 88 */ 89 @Override 90 public Object getInput() { 91 return mEditorDelegate.getEditor().getEditorInput(); 92 } 93 94 /** 95 * Unused. We don't support switching the input. 96 */ 97 @Override 98 public void setInput(Object input) { 99 } 100 101 /** 102 * Returns a new {@link TreeSelection} where each {@link TreePath} item 103 * is a {@link CanvasViewInfo}. 104 */ 105 @Override 106 public ISelection getSelection() { 107 return mCanvas.getSelectionManager().getSelection(); 108 } 109 110 /** 111 * Sets a new selection. <code>reveal</code> is ignored right now. 112 * <p/> 113 * The selection can be null, which is interpreted as an empty selection. 114 */ 115 @Override 116 public void setSelection(ISelection selection, boolean reveal) { 117 if (mEditorDelegate.getEditor().getIgnoreXmlUpdate()) { 118 return; 119 } 120 mCanvas.getSelectionManager().setSelection(selection); 121 } 122 123 /** Unused. Refreshing is done solely by the owning {@link LayoutEditorDelegate}. */ 124 @Override 125 public void refresh() { 126 // ignore 127 } 128 129 public void dispose() { 130 if (mSelectionListener != null) { 131 mCanvas.getSelectionManager().removeSelectionChangedListener(mSelectionListener); 132 } 133 if (mCanvas != null) { 134 mCanvas.dispose(); 135 mCanvas = null; 136 } 137 } 138 139 // ---- Implements IPostSelectionProvider ---- 140 141 private ListenerList mPostChangedListeners = new ListenerList(); 142 143 @Override 144 public void addPostSelectionChangedListener(ISelectionChangedListener listener) { 145 mPostChangedListeners.add(listener); 146 } 147 148 @Override 149 public void removePostSelectionChangedListener(ISelectionChangedListener listener) { 150 mPostChangedListeners.remove(listener); 151 } 152 153 protected void firePostSelectionChanged(final SelectionChangedEvent event) { 154 Object[] listeners = mPostChangedListeners.getListeners(); 155 for (int i = 0; i < listeners.length; i++) { 156 final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i]; 157 SafeRunnable.run(new SafeRunnable() { 158 @Override 159 public void run() { 160 l.selectionChanged(event); 161 } 162 }); 163 } 164 } 165 } 166