• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
17package com.android.adt.gscripts;
18
19/**
20 * An {@link IViewRule} for android.widget.FrameLayout and all its derived classes.
21 */
22public class AndroidWidgetFrameLayoutRule extends BaseLayout {
23
24    // ==== Drag'n'drop support ====
25    // The FrameLayout accepts any drag'n'drop anywhere on its surface.
26
27    DropFeedback onDropEnter(INode targetNode, IDragElement[] elements) {
28        if (elements.length == 0) {
29            return null;
30        }
31
32        return new DropFeedback(
33            [ "p": null ],      // Point: last cursor position
34            {
35                gc, node, feedback ->
36                // Paint closure for the FrameLayout.
37
38            drawFeedback(gc, node, elements, feedback);
39        });
40    }
41
42    void drawFeedback(IGraphics gc,
43                      INode targetNode,
44                      IDragElement[] elements,
45                      DropFeedback feedback) {
46        Rect b = targetNode.getBounds();
47        if (!b.isValid()) {
48            return;
49        }
50
51        gc.setForeground(gc.registerColor(0x00FFFF00));
52        gc.setLineStyle(IGraphics.LineStyle.LINE_SOLID);
53        gc.setLineWidth(2);
54        gc.drawRect(b);
55
56        // Get the drop point
57        Point p = feedback.userData.p;
58
59        if (p == null) {
60            return;
61        }
62
63        int x = p.x;
64        int y = p.y;
65
66        Rect be = elements[0].getBounds();
67
68        if (be.isValid()) {
69            // At least the first element has a bound. Draw rectangles
70            // for all dropped elements with valid bounds, offset at
71            // the drop point.
72            int offsetX = x - be.x;
73            int offsetY = y - be.y;
74            elements.each {
75                drawElement(gc, it, offsetX, offsetY);
76            }
77        } else {
78            // We don't have bounds for new elements. In this case
79            // just draw a mark at the drop point.
80            gc.drawLine(x - 10, y - 10, x + 10, y + 10);
81            gc.drawLine(x + 10, y - 10, x - 10, y + 10);
82            gc.drawOval(x - 10, y - 10, x + 10, y + 10);
83        }
84    }
85
86    DropFeedback onDropMove(INode targetNode,
87                            IDragElement[] elements,
88                            DropFeedback feedback,
89                            Point p) {
90        feedback.userData.p = p;
91        feedback.requestPaint = true;
92        return feedback;
93    }
94
95    void onDropLeave(INode targetNode, IDragElement[] elements, DropFeedback feedback) {
96                // ignore
97    }
98
99    void onDropped(INode targetNode,
100                   IDragElement[] elements,
101                   DropFeedback feedback,
102                   Point p) {
103        Rect b = targetNode.getBounds();
104        if (!b.isValid()) {
105            return;
106        }
107
108        // Collect IDs from dropped elements and remap them to new IDs
109        // if this is a copy or from a different canvas.
110        def idMap = getDropIdMap(targetNode, elements, feedback.isCopy || !feedback.sameCanvas);
111
112        targetNode.editXml("Add elements to FrameLayout") {
113
114            // Now write the new elements.
115            for (element in elements) {
116                String fqcn = element.getFqcn();
117                Rect be = element.getBounds();
118
119                INode newChild = targetNode.appendChild(fqcn);
120
121                // Copy all the attributes, modifying them as needed.
122                def attrFilter = getLayoutAttrFilter();
123                addAttributes(newChild, element, idMap) {
124                    uri, name, value ->
125                    // TODO need a better way to exclude other layout attributes dynamically
126                    if (uri == ANDROID_URI && name in attrFilter) {
127                        return false; // don't set these attributes
128                    } else {
129                        return value;
130                    }
131                };
132
133                addInnerElements(newChild, element, idMap);
134            }
135        }
136    }
137}
138