aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvasViewer.java
blob: e349a1cb04a9af6937237c076926040e6866019a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.eclipse.org/org/documents/epl-v10.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.ide.eclipse.adt.internal.editors.layout.gle2;

import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
import com.android.ide.eclipse.adt.internal.editors.layout.gre.RulesEngine;

import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;


/**
 * JFace {@link Viewer} wrapper around {@link LayoutCanvas}.
 * <p/>
 * The viewer is owned by {@link GraphicalEditorPart}.
 * <p/>
 * The viewer is an {@link ISelectionProvider} instance and is set as the
 * site's main {@link ISelectionProvider} by the editor part. Consequently
 * canvas' selection changes are broadcasted to anyone listening, which includes
 * the part itself as well as the associated outline and property sheet pages.
 */
class LayoutCanvasViewer extends Viewer implements IPostSelectionProvider {

    private LayoutCanvas mCanvas;
    private final LayoutEditorDelegate mEditorDelegate;

    public LayoutCanvasViewer(LayoutEditorDelegate editorDelegate,
            RulesEngine rulesEngine,
            Composite parent,
            int style) {
        mEditorDelegate = editorDelegate;
        mCanvas = new LayoutCanvas(editorDelegate, rulesEngine, parent, style);

        mCanvas.getSelectionManager().addSelectionChangedListener(mSelectionListener);
    }

    private ISelectionChangedListener mSelectionListener = new ISelectionChangedListener() {
        @Override
        public void selectionChanged(SelectionChangedEvent event) {
            fireSelectionChanged(event);
            firePostSelectionChanged(event);
        }
    };

    @Override
    public Control getControl() {
        return mCanvas;
    }

    /**
     * Returns the underlying {@link LayoutCanvas}.
     * This is the same control as returned by {@link #getControl()} but clients
     * have it already casted in the right type.
     * <p/>
     * This can never be null.
     * @return The underlying {@link LayoutCanvas}.
     */
    public LayoutCanvas getCanvas() {
        return mCanvas;
    }

    /**
     * Returns the current layout editor's input.
     */
    @Override
    public Object getInput() {
        return mEditorDelegate.getEditor().getEditorInput();
    }

    /**
     * Unused. We don't support switching the input.
     */
    @Override
    public void setInput(Object input) {
    }

    /**
     * Returns a new {@link TreeSelection} where each {@link TreePath} item
     * is a {@link CanvasViewInfo}.
     */
    @Override
    public ISelection getSelection() {
        return mCanvas.getSelectionManager().getSelection();
    }

    /**
     * Sets a new selection. <code>reveal</code> is ignored right now.
     * <p/>
     * The selection can be null, which is interpreted as an empty selection.
     */
    @Override
    public void setSelection(ISelection selection, boolean reveal) {
        if (mEditorDelegate.getEditor().getIgnoreXmlUpdate()) {
            return;
        }
        mCanvas.getSelectionManager().setSelection(selection);
    }

    /** Unused. Refreshing is done solely by the owning {@link LayoutEditorDelegate}. */
    @Override
    public void refresh() {
        // ignore
    }

    public void dispose() {
        if (mSelectionListener != null) {
            mCanvas.getSelectionManager().removeSelectionChangedListener(mSelectionListener);
        }
        if (mCanvas != null) {
            mCanvas.dispose();
            mCanvas = null;
        }
    }

    // ---- Implements IPostSelectionProvider ----

    private ListenerList mPostChangedListeners = new ListenerList();

    @Override
    public void addPostSelectionChangedListener(ISelectionChangedListener listener) {
        mPostChangedListeners.add(listener);
    }

    @Override
    public void removePostSelectionChangedListener(ISelectionChangedListener listener) {
        mPostChangedListeners.remove(listener);
    }

    protected void firePostSelectionChanged(final SelectionChangedEvent event) {
        Object[] listeners = mPostChangedListeners.getListeners();
        for (int i = 0; i < listeners.length; i++) {
            final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i];
            SafeRunnable.run(new SafeRunnable() {
                @Override
                public void run() {
                    l.selectionChanged(event);
                }
            });
        }
    }
}