aboutsummaryrefslogtreecommitdiffstats
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/IViewRule.java
blob: 13699b4ef1d33de854a6e11d1141ab0c5165c810 (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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/*
 * Copyright (C) 2009 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.common.api;

import java.util.List;
import java.util.Map;


/**
 * An {@link IViewRule} describes the GLE rules that apply to a given Layout or View object
 * in the Graphical Layout Editor (GLE).
 * <p/>
 * Such a rule is implemented by builtin layout helpers, or 3rd party layout rule implementations
 * provided with or for a given 3rd party widget.
 * <p/>
 * A 3rd party layout rule should use the same fully qualified class name as the layout it
 * represents, plus "Rule" as a suffix. For example, the layout rule for the
 * LinearLayout class is LinearLayoutRule, in the same package.
 * <p/>
 * Rule instances are stateless. They are created once per View class to handle and are shared
 * across platforms or editor instances. As such, rules methods should never cache editor-specific
 * arguments that they might receive.
 * <p/>
 * When rules are instantiated, a property "_rules_engine" is dynamically added which references
 * the {@link IClientRulesEngine} created for this rule.
 * <p>
 * <b>NOTE: This is not a public or final API; if you rely on this be prepared
 * to adjust your code for the next tools release.</b>
 * </p>
 */
public interface IViewRule {

    /**
     * The name of the property that returns a {@link IClientRulesEngine} created for this
     * rules. The instance lets rules use some methods from the rules engine, for example
     * for accessing other rules.
     */
    final static String RULES_ENGINE = "_rules_engine";

    /**
     * This method is called by the rule engine when the script is first loaded.
     * It gives the rule a chance to initialize itself.
     *
     * @param fqcn The fully qualified class name of the Layout or View that will be managed by
     *   this rule. This can be cached as it will never change for the lifetime of this rule
     *   instance. This may or may not match the script's filename as it may be the fqcn of a
     *   class derived from the one this rule can handle.
     * @param engine The engine that is managing the rules. A rule can store a reference to
     *   the engine during initialization and then use it later to invoke some of the
     *   {@link IClientRulesEngine} methods for example to request user input.
     * @return True if this rule can handle the given FQCN. False if the rule can't handle the
     *   given FQCN, in which case the rule engine will find another rule matching a parent clas.
     */
    boolean onInitialize(String fqcn, IClientRulesEngine engine);

    /**
     * This method is called by the rules engine just before the script is unloaded.
     */
    void onDispose();

    /**
     * Returns the class name to display when an element is selected in the GLE.
     * <p/>
     * If null is returned, the GLE will automatically shorten the class name using its
     * own heuristic, which is to keep the first 2 package components and the class name.
     * The class name is the <code>fqcn</code> argument that was given
     * to {@link #onInitialize(String)}.
     *
     * @return Null for the default behavior or a shortened string.
     */
    String getDisplayName();

    /**
     * Invoked by the Rules Engine to retrieve a set of actions to customize
     * the context menu displayed for this view. The result is not cached and the
     * method is invoked every time the context menu is about to be shown.
     * <p/>
     * Most rules should consider returning <code>super.getContextMenu(node)</code>
     * and appending their own custom menu actions, if any.
     * <p/>
     * Menu actions are either toggles or fixed lists with one currently-selected
     * item. It is expected that the rule will need to recreate the actions with
     * different selections when a menu is going to shown, which is why the result
     * is not cached. However rules are encouraged to cache some or all of the result
     * to speed up following calls if it makes sense.
     *
     * @return Null for no context menu, or a new {@link MenuAction} describing one
     *   or more actions to display in the context menu.
     */
    List<MenuAction> getContextMenu(INode node);


    // ==== Selection ====

    /**
     * Called by the canvas when a view is being selected.
     * <p/>
     * Before the method is called, the canvas' Graphic Context is initialized
     * with a foreground color already set to the desired selection color, fully
     * opaque and with the default adequate font.
     *
     * @param gc An {@link IGraphics} instance, to perform drawing operations.
     * @param selectedNode The node selected. Never null.
     * @param displayName The name to display, as returned by {@link #getDisplayName()}.
     * @param isMultipleSelection A boolean set to true if more than one element is selected.
     */
    void onSelected(IGraphics gc,
            INode selectedNode,
            String displayName,
            boolean isMultipleSelection);

    /**
     * Called by the canvas when a single child view is being selected.
     * <p/>
     * Note that this is called only for single selections.
     * <p/>
     * This allows a parent to draw stuff around its children, for example to display
     * layout attributes graphically.
     *
     * @param gc An {@link IGraphics} instance, to perform drawing operations.
     * @param parentNode The parent of the node selected. Never null.
     * @param childNode The child node that was selected. Never null.
     */
    void onChildSelected(IGraphics gc,
            INode parentNode,
            INode childNode);


    // ==== XML Creation ====

    /**
     * Returns the default attributes that a new XML element of this type should have
     * when added to an XML layout file. Note that these defaults can be overridden by the
     * specific code performing the insertion.
     *
     * TODO:
     * - added=>created
     * - list tuple(uri, local name, str: value)
     * - gen id
     *
     * @return A map of attribute:values for a new element of this type. Can be null or empty.
     */
    Map<?, ?> getDefaultAttributes();


    // ==== Drag'n'drop support ====

    /**
     * Called when the d'n'd starts dragging over the target node.
     * If interested, returns a DropFeedback passed to onDrop/Move/Leave/Paint.
     * If not interested in drop, return null.
     * Followed by a paint.
     */
    DropFeedback onDropEnter(INode targetNode,
            IDragElement[] elements);

    /**
     * Called after onDropEnter.
     * Returns a DropFeedback passed to onDrop/Move/Leave/Paint (typically same
     * as input one).
     * Returning null will invalidate the drop workflow.
     */
    DropFeedback onDropMove(INode targetNode,
            IDragElement[] elements,
            DropFeedback feedback,
            Point where);

    /**
     * Called when drop leaves the target without actually dropping.
     * <p/>
     * When switching between views, onDropLeave is called on the old node *after* onDropEnter
     * is called after a new node that returned a non-null feedback. The feedback received here
     * is the one given by the previous onDropEnter on the same target.
     * <p/>
     * E.g. call order is:
     * <pre>
     * - onDropEnter(node1) => feedback1
     * <i>...user moves to new view...</i>
     * - onDropEnter(node2) => feedback2
     * - onDropLeave(node1, feedback1)
     * <i>...user leaves canvas...</i>
     * - onDropLeave(node2, feedback2)
     * </pre>
     */
    void onDropLeave(INode targetNode,
            IDragElement[] elements,
            DropFeedback feedback);

    /**
     * Called when drop is released over the target to perform the actual drop.
     */
    void onDropped(INode targetNode,
            IDragElement[] elements,
            DropFeedback feedback,
            Point where);

    /**
     * Called when pasting elements in an existing document on the selected target.
     *
     * @param targetNode The first node selected.
     * @param pastedElements The elements being pasted.
     */
    void onPaste(INode targetNode, IDragElement[] pastedElements);
}