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.LayoutEditor; 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 LayoutEditor mLayoutEditor; 50 LayoutCanvasViewer(LayoutEditor layoutEditor, RulesEngine rulesEngine, Composite parent, int style)51 public LayoutCanvasViewer(LayoutEditor layoutEditor, 52 RulesEngine rulesEngine, 53 Composite parent, 54 int style) { 55 mLayoutEditor = layoutEditor; 56 mCanvas = new LayoutCanvas(layoutEditor, rulesEngine, parent, style); 57 58 mCanvas.getSelectionManager().addSelectionChangedListener(mSelectionListener); 59 } 60 61 private ISelectionChangedListener mSelectionListener = new ISelectionChangedListener() { 62 public void selectionChanged(SelectionChangedEvent event) { 63 fireSelectionChanged(event); 64 firePostSelectionChanged(event); 65 } 66 }; 67 68 @Override getControl()69 public Control getControl() { 70 return mCanvas; 71 } 72 73 /** 74 * Returns the underlying {@link LayoutCanvas}. 75 * This is the same control as returned by {@link #getControl()} but clients 76 * have it already casted in the right type. 77 * <p/> 78 * This can never be null. 79 * @return The underlying {@link LayoutCanvas}. 80 */ getCanvas()81 public LayoutCanvas getCanvas() { 82 return mCanvas; 83 } 84 85 /** 86 * Returns the current layout editor's input. 87 */ 88 @Override getInput()89 public Object getInput() { 90 return mLayoutEditor.getEditorInput(); 91 } 92 93 /** 94 * Unused. We don't support switching the input. 95 */ 96 @Override setInput(Object input)97 public void setInput(Object input) { 98 } 99 100 /** 101 * Returns a new {@link TreeSelection} where each {@link TreePath} item 102 * is a {@link CanvasViewInfo}. 103 */ 104 @Override getSelection()105 public ISelection getSelection() { 106 return mCanvas.getSelectionManager().getSelection(); 107 } 108 109 /** 110 * Sets a new selection. <code>reveal</code> is ignored right now. 111 * <p/> 112 * The selection can be null, which is interpreted as an empty selection. 113 */ 114 @Override setSelection(ISelection selection, boolean reveal)115 public void setSelection(ISelection selection, boolean reveal) { 116 mCanvas.getSelectionManager().setSelection(selection); 117 } 118 119 /** Unused. Refreshing is done solely by the owning {@link LayoutEditor}. */ 120 @Override refresh()121 public void refresh() { 122 // ignore 123 } 124 dispose()125 public void dispose() { 126 if (mSelectionListener != null) { 127 mCanvas.getSelectionManager().removeSelectionChangedListener(mSelectionListener); 128 } 129 if (mCanvas != null) { 130 mCanvas.dispose(); 131 mCanvas = null; 132 } 133 } 134 135 // ---- Implements IPostSelectionProvider ---- 136 137 private ListenerList mPostChangedListeners = new ListenerList(); 138 addPostSelectionChangedListener(ISelectionChangedListener listener)139 public void addPostSelectionChangedListener(ISelectionChangedListener listener) { 140 mPostChangedListeners.add(listener); 141 } 142 removePostSelectionChangedListener(ISelectionChangedListener listener)143 public void removePostSelectionChangedListener(ISelectionChangedListener listener) { 144 mPostChangedListeners.remove(listener); 145 } 146 firePostSelectionChanged(final SelectionChangedEvent event)147 protected void firePostSelectionChanged(final SelectionChangedEvent event) { 148 Object[] listeners = mPostChangedListeners.getListeners(); 149 for (int i = 0; i < listeners.length; i++) { 150 final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i]; 151 SafeRunnable.run(new SafeRunnable() { 152 public void run() { 153 l.selectionChanged(event); 154 } 155 }); 156 } 157 } 158 } 159