~ubuntu-branches/ubuntu/quantal/netbeans/quantal

« back to all changes in this revision

Viewing changes to form/src/org/netbeans/modules/form/layoutsupport/delegates/FlowLayoutSupport.java

  • Committer: Bazaar Package Importer
  • Author(s): Marek Slama
  • Date: 2008-01-29 14:11:22 UTC
  • Revision ID: james.westby@ubuntu.com-20080129141122-fnzjbo11ntghxfu7
Tags: upstream-6.0.1
ImportĀ upstreamĀ versionĀ 6.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 
3
 *
 
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 
5
 *
 
6
 * The contents of this file are subject to the terms of either the GNU
 
7
 * General Public License Version 2 only ("GPL") or the Common
 
8
 * Development and Distribution License("CDDL") (collectively, the
 
9
 * "License"). You may not use this file except in compliance with the
 
10
 * License. You can obtain a copy of the License at
 
11
 * http://www.netbeans.org/cddl-gplv2.html
 
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 
13
 * specific language governing permissions and limitations under the
 
14
 * License.  When distributing the software, include this License Header
 
15
 * Notice in each file and include the License file at
 
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
 
17
 * particular file as subject to the "Classpath" exception as provided
 
18
 * by Sun in the GPL Version 2 section of the License file that
 
19
 * accompanied this code. If applicable, add the following below the
 
20
 * License Header, with the fields enclosed by brackets [] replaced by
 
21
 * your own identifying information:
 
22
 * "Portions Copyrighted [year] [name of copyright owner]"
 
23
 *
 
24
 * Contributor(s):
 
25
 *
 
26
 * The Original Software is NetBeans. The Initial Developer of the Original
 
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
 
28
 * Microsystems, Inc. All Rights Reserved.
 
29
 *
 
30
 * If you wish your version of this file to be governed by only the CDDL
 
31
 * or only the GPL Version 2, indicate your decision by adding
 
32
 * "[Contributor] elects to include this software in this distribution
 
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 
34
 * single choice of license, a recipient has the option to distribute
 
35
 * your version of this file under either the CDDL, the GPL Version 2 or
 
36
 * to extend the choice of license to its licensees as provided above.
 
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 
38
 * Version 2 license, then the option applies only if the new code is
 
39
 * made subject to such option by the copyright holder.
 
40
 */
 
41
 
 
42
package org.netbeans.modules.form.layoutsupport.delegates;
 
43
 
 
44
import java.awt.*;
 
45
import org.netbeans.modules.form.layoutsupport.*;
 
46
 
 
47
/**
 
48
 * Support class for FlowLayout. This is an example of very simple layout
 
49
 * with no constraints; just basic drag & drop is implemented.
 
50
 *
 
51
 * @author Tran Duc Trung, Tomas Pavek
 
52
 */
 
53
 
 
54
public class FlowLayoutSupport extends AbstractLayoutSupport
 
55
{
 
56
    /** Gets the supported layout manager class - FlowLayout.
 
57
     * @return the class supported by this delegate
 
58
     */
 
59
    public Class getSupportedClass() {
 
60
        return FlowLayout.class;
 
61
    }
 
62
 
 
63
    /** This method calculates position (index) for a component dragged
 
64
     * over a container (or just for mouse cursor being moved over container,
 
65
     * without any component).
 
66
     * @param container instance of a real container over/in which the
 
67
     *        component is dragged
 
68
     * @param containerDelegate effective container delegate of the container
 
69
     *        (for layout managers we always use container delegate instead of
 
70
     *        the container)
 
71
     * @param component the real component being dragged; not needed here
 
72
     * @param index position (index) of the component in its current container;
 
73
     *        not needed here
 
74
     * @param posInCont position of mouse in the container delegate
 
75
     * @param posInComp position of mouse in the dragged component;
 
76
     *        not needed here
 
77
     * @return index corresponding to the position of the component in the
 
78
     *         container
 
79
     */
 
80
    @Override
 
81
    public int getNewIndex(Container container,
 
82
                           Container containerDelegate,
 
83
                           Component component,
 
84
                           int index,
 
85
                           Point posInCont,
 
86
                           Point posInComp)
 
87
    {
 
88
        if (!(containerDelegate.getLayout() instanceof FlowLayout))
 
89
            return -1;
 
90
 
 
91
        int vgap = ((FlowLayout) containerDelegate.getLayout()).getVgap();
 
92
        Component[] components = containerDelegate.getComponents();
 
93
        int[] rowStarts = new int[components.length + 1];
 
94
        int[] rowTops = new int[components.length + 1];
 
95
        for (int i = 0; i < rowStarts.length; i++) {
 
96
            rowStarts[i] = -1;
 
97
        }
 
98
 
 
99
        // rowStarts keeps indices of the first components on each row
 
100
        // rowTops keeps y-position of each row
 
101
        
 
102
        int lastX = Integer.MAX_VALUE;
 
103
        int rowHeight = - vgap;
 
104
        int r = 0;
 
105
        int i = 0;
 
106
 
 
107
        int compIndex = -1;
 
108
        assistantParams = 0;
 
109
        if ((components.length > 1) || (component.getParent() != containerDelegate)) {
 
110
            for (int j = 0; j < components.length; j++) {
 
111
                Component comp = components[j];
 
112
                if (comp == component) {
 
113
                    compIndex = j;
 
114
                    comp = components[(j == 0) ? 1 : j-1];
 
115
                }
 
116
                int posX = comp.getBounds().x;
 
117
                if (posX < lastX) {
 
118
                    rowStarts[r] = j;
 
119
                    rowTops[r] = rowHeight + vgap;
 
120
                    rowTops[r] += r > 0 ? rowTops[r-1] :
 
121
                                          containerDelegate.getInsets().top;
 
122
                    r++;
 
123
                    rowHeight = 0;
 
124
                }
 
125
                rowHeight = Math.max(rowHeight, comp.getSize().height);
 
126
                lastX = posX;
 
127
            }
 
128
            if (r > 0) {
 
129
                rowTops[r] = rowTops[r-1] + rowHeight + vgap;
 
130
            }
 
131
 
 
132
            // find which row the pointer falls in
 
133
 
 
134
            r = 0;
 
135
            while (rowStarts[i] >= 0) {
 
136
                if (posInCont.y < rowTops[i]) {
 
137
                    r = i - 1;
 
138
                    break;
 
139
                }
 
140
                i++;
 
141
            }
 
142
 
 
143
            if (rowStarts[i] < 0) {
 
144
                if (posInCont.y >= rowTops[i]) {
 
145
                    if (component.getParent() == containerDelegate) assistantParams--;
 
146
                    assistantParams += components.length;
 
147
                    return components.length;
 
148
                }
 
149
                else {
 
150
                    r = i - 1;
 
151
                }
 
152
            }
 
153
 
 
154
            int m = (r <= 0) ? 0 : rowStarts[r];
 
155
            if ((compIndex > -1) && (compIndex < m)) assistantParams--;
 
156
            int n = rowStarts[r + 1];
 
157
 
 
158
            if (n > components.length || n < 0)
 
159
                n = components.length;
 
160
 
 
161
            for (i = m; i < n; i++) {
 
162
                Component comp = components[i];
 
163
                if (comp == component) {
 
164
                    assistantParams--;
 
165
                    comp = components[(i == 0) ? 1 : i-1];
 
166
                }
 
167
                Rectangle bounds = comp.getBounds();
 
168
                int centerX = bounds.x + bounds.width / 2;
 
169
                if (posInCont.x < centerX)
 
170
                    break;
 
171
            }
 
172
 
 
173
            i = i < n ? i : n;
 
174
        }
 
175
        assistantParams += i;
 
176
        return i;
 
177
    }
 
178
 
 
179
    private int assistantParams;
 
180
    @Override
 
181
    public String getAssistantContext() {
 
182
        return "flowLayout"; // NOI18N
 
183
    }
 
184
 
 
185
    @Override
 
186
    public Object[] getAssistantParams() {
 
187
        return new Object[] {Integer.valueOf(assistantParams+1)};
 
188
    }
 
189
 
 
190
    /** This method paints a dragging feedback for a component dragged over
 
191
     * a container (or just for mouse cursor being moved over container,
 
192
     * without any component).
 
193
     * @param container instance of a real container over/in which the
 
194
     *        component is dragged
 
195
     * @param containerDelegate effective container delegate of the container
 
196
     *        (for layout managers we always use container delegate instead of
 
197
     *        the container)
 
198
     * @param component the real component being dragged, not needed here
 
199
     * @param newConstraints component layout constraints to be presented;
 
200
     *        not used for FlowLayout
 
201
     * @param newIndex component's index position to be presented
 
202
     * @param g Graphics object for painting (with color and line style set)
 
203
     * @return whether any feedback was painted (true in this case)
 
204
     */
 
205
    @Override
 
206
    public boolean paintDragFeedback(Container container, 
 
207
                                     Container containerDelegate,
 
208
                                     Component component,
 
209
                                     LayoutConstraints newConstraints,
 
210
                                     int newIndex,
 
211
                                     Graphics g)
 
212
    {
 
213
        if (!(containerDelegate.getLayout() instanceof FlowLayout))
 
214
            return false;
 
215
        
 
216
        Component[] components = containerDelegate.getComponents();
 
217
        int alignment = ((FlowLayout) containerDelegate.getLayout()).getAlignment();
 
218
        int hgap = ((FlowLayout) containerDelegate.getLayout()).getHgap();
 
219
        int draggedIndex = -1;
 
220
        if (component.getParent() == containerDelegate) {
 
221
            for (int i=0; i<components.length; i++) {
 
222
                if (component == components[i]) {
 
223
                    draggedIndex = i;
 
224
                }
 
225
            }
 
226
        }
 
227
 
 
228
        int x = 0, y1 = 0, y2 = 0;
 
229
 
 
230
        if ((newIndex <= 0) || ((components.length == 1) && (draggedIndex != -1))) {
 
231
            if ((components.length == 0) || ((components.length == 1) && (draggedIndex != -1))) {
 
232
                if (alignment == FlowLayout.RIGHT) {
 
233
                    x = containerDelegate.getSize().width;
 
234
                }
 
235
                else if (alignment == FlowLayout.LEFT) {
 
236
                    x = 0;
 
237
                }
 
238
                else {
 
239
                    x = containerDelegate.getSize().width / 2 - 5;
 
240
                }
 
241
                y1 = 0;
 
242
                y2 = component.getHeight();
 
243
            }
 
244
            else {
 
245
                Rectangle b = components[(draggedIndex == 0) ? 1 : 0].getBounds();
 
246
                x = b.x;
 
247
                y1 = b.y;
 
248
                y2 = b.y + component.getHeight();
 
249
            }
 
250
        }
 
251
        else if ((newIndex >= components.length) ||
 
252
            ((newIndex == components.length - 1) && (newIndex == draggedIndex))) {
 
253
            int last = components.length - 1;
 
254
            Rectangle b = components[(last == draggedIndex) ? last-1 : last].getBounds();
 
255
            x = b.x + b.width;
 
256
            y1 = b.y;
 
257
            y2 = b.y + component.getHeight();
 
258
        }
 
259
        else {
 
260
            Rectangle b = components[(newIndex == draggedIndex) ? newIndex+1 : newIndex].getBounds();
 
261
            x = b.x;
 
262
            y1 = b.y;
 
263
            y2 = b.y + component.getHeight();
 
264
        }
 
265
        g.drawRect(x - 10 - hgap / 2, y1, 20, y2 - y1);
 
266
        return true;
 
267
    }
 
268
}