KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > lib > editor > view > GapLineViewChildren


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.lib.editor.view;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.List JavaDoc;
24 import javax.swing.text.View JavaDoc;
25 import org.netbeans.editor.view.spi.ViewLayoutState;
26
27 /**
28  * Implementation of children for {@link GapLineView}.
29  *
30  * <p>
31  *
32  * @author Miloslav Metelka
33  * @version 1.00
34  */

35
36 class GapLineViewChildren extends GapBoxViewChildren {
37
38     /**
39      * Value of maximal preferred ascent along the minor axis.
40      */

41     private float maxMinorAxisPrefAscent; // 52
42

43     /**
44      * Index of the child wrapping the view that has a maximal descent
45      * along the minor axis among all the children.
46      */

47     private int maxMinorAxisPrefDescentChildIndex = -1; // 56
48

49     /**
50      * Value of maximal preferred descent along the minor axis.
51      */

52     private float maxMinorAxisPrefDescent; // 60
53

54
55     /** List of rows that is non-null in case the line has to be wrapped */
56     private RowList rowList; // 64
57

58
59     GapLineViewChildren(GapBoxView view) {
60         super(view);
61     }
62     
63     /**
64      * Compute layout information of the children along the minor axis.
65      * This implementation does wrapped-line layout
66      */

67     public void minorAxisLayout() {
68         // Find child states with maximal prefered and minimum spans
69
// along the minor axis
70

71         int childCount = getChildCount();
72         int maxMinorPrefAscentIndex = -1;
73         int maxMinorPrefDescentIndex = -1;
74         float maxMinorPrefAscentValue = 0f;
75         float maxMinorPrefDescentValue = 0f;
76
77         for (int i = 0; i < childCount; i++) {
78             ViewLayoutState child = getChild(i);
79             float span = child.getLayoutMinorAxisPreferredSpan();
80             float alignment = child.getLayoutMinorAxisAlignment();
81             float ascent = span * alignment;
82             float descent = span - ascent;
83
84             if (ascent > maxMinorPrefAscentValue) {
85                 maxMinorPrefAscentIndex = i;
86                 maxMinorPrefAscentValue = ascent;
87             }
88
89             if (descent > maxMinorPrefDescentValue) {
90                 maxMinorPrefDescentIndex = i;
91                 maxMinorPrefDescentValue = descent;
92             }
93
94         }
95
96         float maxMinorPrefSpanValue = maxMinorPrefAscentValue + maxMinorPrefDescentValue;
97         setMinorAxisPreferredSpan(maxMinorPrefSpanValue);
98         setMaxMinorAxisPrefAscent(maxMinorPrefAscentValue);
99         setMaxMinorAxisPrefDescent(maxMinorPrefDescentValue);
100         setMaxMinorAxisPrefAscentChildIndex(maxMinorPrefAscentIndex);
101         setMaxMinorAxisPrefDescentChildIndex(maxMinorPrefDescentIndex);
102     }
103     
104     private float getPrefAscent(ViewLayoutState child) {
105         float span = child.getLayoutMinorAxisPreferredSpan();
106         float alignment = child.getLayoutMinorAxisAlignment();
107         return span * alignment;
108     }
109     
110     private float getMaxMinorAxisPrefAscent() {
111         return maxMinorAxisPrefAscent;
112     }
113     
114     private void setMaxMinorAxisPrefAscent(float maxMinorAxisPrefAscent) {
115         this.maxMinorAxisPrefAscent = maxMinorAxisPrefAscent;
116     }
117
118     private int getMaxMinorAxisPrefAscentChildIndex() {
119         // reuse variable for preferred span
120
return super.getMaxMinorAxisPreferredSpanChildIndex();
121     }
122     
123     private void setMaxMinorAxisPrefAscentChildIndex(int maxMinorAxisPrefAscentChildIndex) {
124         // reuse variable for preferred span
125
super.setMaxMinorAxisPreferredSpanChildIndex(maxMinorAxisPrefAscentChildIndex);
126     }
127     
128     private float getPrefDescent(ViewLayoutState child) {
129         float span = child.getLayoutMinorAxisPreferredSpan();
130         float alignment = child.getLayoutMinorAxisAlignment();
131         return span * (1 - alignment);
132     }
133     
134     private float getMaxMinorAxisPrefDescent() {
135         return maxMinorAxisPrefDescent;
136     }
137     
138     private void setMaxMinorAxisPrefDescent(float maxMinorAxisPrefDescent) {
139         this.maxMinorAxisPrefDescent = maxMinorAxisPrefDescent;
140     }
141
142     private int getMaxMinorAxisPrefDescentChildIndex() {
143         return maxMinorAxisPrefDescentChildIndex;
144     }
145     
146     private void setMaxMinorAxisPrefDescentChildIndex(int maxMinorAxisPrefDescentChildIndex) {
147         this.maxMinorAxisPrefDescentChildIndex = maxMinorAxisPrefDescentChildIndex;
148     }
149
150     int getMaxMinorAxisPrefSpanChildIndex() {
151         throw new IllegalStateException JavaDoc("Should never be called"); // NOI18N
152
}
153     
154     void setMaxMinorAxisPrefSpanChildIndex(int maxMinorAxisPrefSpanChildIndex) {
155         throw new IllegalStateException JavaDoc("Should never be called"); // NOI18N
156
}
157
158     protected void replaceUpdateIndexes(int index, int removeLength, int insertLength,
159     int neighborIndex, int neighborIndexAfterReplace, ViewLayoutState neighbor) {
160         
161         boolean minorAxisChanged = false;
162         int endRemoveIndex = index + removeLength;
163         /* Check whether any of the removed children
164          * are either maxPref, maxMin.
165          * If so replace them by the neighbor where appropriate.
166          * Set parent of each remove child to null.
167          */

168 /* int ind = getMaxMinorAxisPrefSpanChildIndex();
169         if (ind >= endRemoveIndex) { // must update by diff
170             setMaxMinorAxisPrefSpanChildIndex(ind + insertLength - removeLength);
171         } else if (ind >= index) { // in removed area -> need to change to neighbor
172             if (neighbor == null || neighbor.getLayoutMinorAxisPreferredSpan()
173                 < view.getMinorAxisPreferredSpan()
174             ) {
175                 minorAxisChanged = true; // minor axis spans must be recomputed
176             }
177             setMaxMinorAxisPrefSpanChildIndex(neighborIndexAfterReplace);
178         }
179   */

180             
181
182         int ind = getMaxMinorAxisPrefAscentChildIndex();
183         if (ind >= endRemoveIndex) {
184             setMaxMinorAxisPrefAscentChildIndex(ind + insertLength - removeLength);
185         } else if (ind >= index) {
186             float neighborAscent = getPrefAscent(neighbor);
187             if (neighbor == null || neighborAscent < getMaxMinorAxisPrefAscent()) {
188                 minorAxisChanged = true;
189             }
190             setMaxMinorAxisPrefAscentChildIndex(neighborIndexAfterReplace);
191         }
192         
193         ind = getMaxMinorAxisPrefDescentChildIndex();
194         if (ind >= endRemoveIndex) {
195             setMaxMinorAxisPrefDescentChildIndex(ind + insertLength - removeLength);
196         } else if (ind >= index) {
197             float neighborDescent = getPrefDescent(neighbor);
198             if (neighbor == null || neighborDescent < getMaxMinorAxisPrefDescent()) {
199                 minorAxisChanged = true;
200             }
201             setMaxMinorAxisPrefDescentChildIndex(neighborIndexAfterReplace);
202         }
203
204         if (minorAxisChanged) {
205             view.markMinorAxisPreferenceChanged();
206         }
207     }
208
209     protected void minorAxisPreferenceChanged(ViewLayoutState child, int childIndex) {
210         boolean minorAxisChanged = false;
211
212         float span = child.getLayoutMinorAxisPreferredSpan();
213         float alignment = child.getLayoutMinorAxisAlignment();
214         float ascent = span * alignment;
215         float descent = span - ascent;
216
217         if (getMaxMinorAxisPrefAscentChildIndex() == -1
218             || ascent > getMaxMinorAxisPrefAscent()
219         ) {
220             setMaxMinorAxisPrefAscent(ascent);
221             setMaxMinorAxisPrefAscentChildIndex(childIndex);
222             minorAxisChanged = true;
223         }
224
225         if (getMaxMinorAxisPrefDescentChildIndex() == -1
226             || descent > getMaxMinorAxisPrefDescent()
227         ) {
228             setMaxMinorAxisPrefDescent(descent);
229             setMaxMinorAxisPrefDescentChildIndex(childIndex);
230             minorAxisChanged = true;
231         }
232         
233         
234         if (minorAxisChanged) {
235             setMinorAxisPreferredSpan(getMaxMinorAxisPrefAscent()
236                 + getMaxMinorAxisPrefDescent());
237
238             view.markMinorAxisPreferenceChanged();
239         }
240     }
241     
242     public float getChildMinorAxisOffset(int childIndex) {
243         ViewLayoutState child = getChild(childIndex);
244         float minorAxisSpan = view.getMinorAxisAssignedSpan();
245         float childMinorMaxSpan = child.getLayoutMinorAxisMaximumSpan();
246         if (childMinorMaxSpan < minorAxisSpan) {
247             // can't make the child to fill the whole span, so align it
248
float align = child.getLayoutMinorAxisAlignment();
249             // Use baseline layout
250
float baseline = getMaxMinorAxisPrefAscent();
251             float span = child.getLayoutMinorAxisPreferredSpan();
252             float alignment = child.getLayoutMinorAxisAlignment();
253             float ascent = span * alignment;
254             return baseline - ascent;
255         }
256
257         return 0f;
258     }
259     
260     private int getRowCount() {
261         return (rowList != null) ? rowList.size() : 0;
262     }
263     
264     private Row getRow(int rowIndex) {
265         return (Row)rowList.get(rowIndex);
266     }
267
268     /**
269      * Return row index that corresponds to the child index.
270      * <br>
271      * Search in valid rows only.
272      * @return &gt;=0 and &lt;<code>lastValidRowIndex</code>
273      * or <code>lastValidRowIndex + 1</code> in case the searched
274      * child is above the valid area.
275      */

276     private int getRowIndex(int childIndex) {
277         // binary search
278
int low = 0;
279         /* can only search up to last valid row index
280          * because the indexes of invalid lines have unpredictable values
281          * which could confuse the binary search
282          * and in worst case make infinite loop.
283          */

284         int high = rowList.lastValidRowIndex;
285         
286         while (low <= high) {
287             int mid = (low + high) / 2;
288             Row midRow = getRow(mid);
289             
290             if (midRow.endChildIndex <= childIndex) { // above the mid row
291
low = mid + 1;
292             } else if (midRow.startChildIndex > childIndex) { // below the mid row
293
high = mid - 1;
294             } else {
295                 // child index inside the row
296
return mid;
297             }
298         }
299         
300         return low; // will be lastValidRowIndex
301
}
302
303     /**
304      * Data of one visual row when line-wrapping is used.
305      *
306      * <p>
307      * The views that have to be split are logically included
308      * into the row where they start.
309      */

310     class Row {
311         
312         /**
313          * Index of the first child that starts
314          * on this row. If the whole row is covered
315          * with Possible presence of fragment
316          * of the view starting at previous row stored
317          * in <code>rowStartFragment</code> has no effect on this value.
318          */

319         int startChildIndex;
320         
321         /**
322          * Index of the last child included fully or partly included on this row.
323          * In case the view has to be split
324          */

325         int endChildIndex;
326         
327         /**
328          * If there is a part of the view starting at one of the previous lines
329          * continuing to this line then this is absolute offset along major axis
330          * at which the part at the begining
331          * of this line starts with.
332          */

333         float beforeStartChildMajorOffset;
334         
335         /**
336          * Layout offset along the minor axis at which this row
337           * is located.
338          */

339         float minorAxisOffset;
340         
341         /**
342          * Span of this row along the minor axis.
343          */

344         float minorAxisSpan;
345         
346     }
347     
348     class RowList extends ArrayList JavaDoc {
349         
350         int lastValidRowIndex;
351         
352     }
353     
354 }
355
Popular Tags