OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [javax/] [swing/] [SizeRequirements.java] - Blame information for rev 772

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* SizeRequirements.java --
2
   Copyright (C) 2002, 2005 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
package javax.swing;
39
 
40
import java.io.Serializable;
41
 
42
/**
43
 * This class calculates information about the size and position requirements
44
 * of components.
45
 *
46
 * Two types of layout are supported:
47
 * <ul>
48
 * <li>Tiled: the components are placed at position top-left or bottom-right
49
 *    position within their allocated space</li>
50
 * <li>Aligned: the components are placed aligned in their allocated space
51
 *    according to their alignment value</li>
52
 * </ul>
53
 *
54
 * @author Andrew Selkirk
55
 * @author Roman Kennke (roman@kennke.org)
56
 */
57
public class SizeRequirements implements Serializable
58
{
59
  /**
60
   * The serialVersionUID.
61
   */
62
  private static final long serialVersionUID = 9217749429906736553L;
63
 
64
  /**
65
   * The minimum reasonable width or height of a component.
66
   */
67
  public int minimum;
68
 
69
  /**
70
   * The preferred width or height of a component.
71
   */
72
  public int preferred;
73
 
74
  /**
75
   * The maximum reasonable width or height of a component.
76
   */
77
  public int maximum;
78
 
79
  /**
80
   * The horizontal or vertical alignment of a component.
81
   */
82
  public float alignment;
83
 
84
  /**
85
   * Creates a SizeRequirements object with minimum, preferred and
86
   * maximum size set to zero, and an alignment value of 0.5.
87
   */
88
  public SizeRequirements()
89
  {
90
    this (0, 0, 0, 0.5F);
91
  }
92
 
93
  /**
94
   * Creates a SizeRequirements object with the specified minimum,
95
   * preferred, maximum and alignment values.
96
   *
97
   * @param min the minimum reasonable size of the component
98
   * @param pref the preferred size of the component
99
   * @param max the maximum size of the component
100
   * @param align the alignment of the component
101
   */
102
  public SizeRequirements(int min, int pref, int max, float align)
103
  {
104
    minimum = min;
105
    preferred = pref;
106
    maximum = max;
107
    alignment = align;
108
  }
109
 
110
  /**
111
   * Returns a String representation of this SizeRequirements object,
112
   * containing information about the minimum, preferred, maximum and
113
   * alignment value.
114
   *
115
   * @return a String representation of this SizeRequirements object
116
   */
117
  public String toString()
118
  {
119
    StringBuilder b = new StringBuilder();
120
    b.append("<[");
121
    b.append(minimum);
122
    b.append(',');
123
    b.append(preferred);
124
    b.append(',');
125
    b.append(maximum);
126
    b.append("]@");
127
    b.append(alignment);
128
    b.append('>');
129
    return b.toString();
130
  }
131
 
132
  /**
133
   * Calculates how much space is nessecary to place a set of components
134
   * end-to-end. The size requirements of the components is specified
135
   * in <code>children</code>.
136
   *
137
   * @param children the SizeRequirements of each of the components
138
   *
139
   * @return the SizeRequirements that describe how much space is needed
140
   *     to place the components end-to-end
141
   */
142
  public static SizeRequirements
143
  getTiledSizeRequirements(SizeRequirements[] children)
144
  {
145
    long minimum = 0;
146
    long preferred = 0;
147
    long maximum = 0;
148
    for (int i = 0; i < children.length; i++)
149
      {
150
        minimum += children[i].minimum;
151
        preferred += children[i].preferred;
152
        maximum += children[i].maximum;
153
      }
154
    // Overflow check.
155
    if (minimum > Integer.MAX_VALUE)
156
      minimum = Integer.MAX_VALUE;
157
    if (preferred > Integer.MAX_VALUE)
158
      preferred = Integer.MAX_VALUE;
159
    if (maximum > Integer.MAX_VALUE)
160
      maximum = Integer.MAX_VALUE;
161
    SizeRequirements result = new SizeRequirements((int) minimum,
162
                                                   (int) preferred,
163
                                                   (int) maximum,
164
                                                   0.5F);
165
    return result;
166
  }
167
 
168
  /**
169
   * Calculates how much space is nessecary to place a set of components
170
   * aligned according to their alignment value.
171
   * The size requirements of the components is specified in
172
   * <code>children</code>.
173
   *
174
   * @param children the SizeRequirements of each of the components
175
   *
176
   * @return the SizeRequirements that describe how much space is needed
177
   *     to place the components aligned
178
   */
179
  public static SizeRequirements
180
  getAlignedSizeRequirements(SizeRequirements[] children)
181
  {
182
    float minLeft = 0;
183
    float minRight = 0;
184
    float prefLeft = 0;
185
    float prefRight = 0;
186
    float maxLeft = 0;
187
    float maxRight = 0;
188
    for (int i = 0; i < children.length; i++)
189
      {
190
        float myMinLeft = children[i].minimum * children[i].alignment;
191
        float myMinRight = children[i].minimum - myMinLeft;
192
        minLeft = Math.max(myMinLeft, minLeft);
193
        minRight = Math.max(myMinRight, minRight);
194
        float myPrefLeft = children[i].preferred * children[i].alignment;
195
        float myPrefRight = children[i].preferred - myPrefLeft;
196
        prefLeft = Math.max(myPrefLeft, prefLeft);
197
        prefRight = Math.max(myPrefRight, prefRight);
198
        float myMaxLeft = children[i].maximum * children[i].alignment;
199
        float myMaxRight = children[i].maximum - myMaxLeft;
200
        maxLeft = Math.max(myMaxLeft, maxLeft);
201
        maxRight = Math.max(myMaxRight, maxRight);
202
      }
203
    int minSize = (int) (minLeft + minRight);
204
    int prefSize = (int) (prefLeft + prefRight);
205
    int maxSize = (int) (maxLeft + maxRight);
206
    float align = prefLeft / (prefRight + prefLeft);
207
    if (Float.isNaN(align))
208
      align = 0;
209
    return new SizeRequirements(minSize, prefSize, maxSize, align);
210
  }
211
 
212
  /**
213
   * Calculate the offsets and spans of the components, when they should
214
   * be placed end-to-end.
215
   *
216
   * You must specify the amount of allocated space in
217
   * <code>allocated</code>, the total size requirements of the set of
218
   * components in <code>total</code> (this can be calculated using
219
   * {@link #getTiledSizeRequirements} and the size requirements of the
220
   * components in <code>children</code>.
221
   *
222
   * The calculated offset and span values for each component are then
223
   * stored in the arrays <code>offsets</code> and <code>spans</code>.
224
   *
225
   * The components are placed in the forward direction, beginning with
226
   * an offset of 0.
227
   *
228
   * @param allocated the amount of allocated space
229
   * @param total the total size requirements of the components
230
   * @param children the size requirement of each component
231
   * @param offsets will hold the offset values for each component
232
   * @param spans will hold the span values for each component
233
   */
234
  public static void calculateTiledPositions(int allocated,
235
                                             SizeRequirements total,
236
                                             SizeRequirements[] children,
237
                                             int[] offsets, int[] spans)
238
  {
239
    calculateTiledPositions(allocated, total, children, offsets, spans, true);
240
  }
241
 
242
  /**
243
   * Calculate the offsets and spans of the components, when they should
244
   * be placed end-to-end.
245
   *
246
   * You must specify the amount of allocated space in
247
   * <code>allocated</code>, the total size requirements of the set of
248
   * components in <code>total</code> (this can be calculated using
249
   * {@link #getTiledSizeRequirements} and the size requirements of the
250
   * components in <code>children</code>.
251
   *
252
   * The calculated offset and span values for each component are then
253
   * stored in the arrays <code>offsets</code> and <code>spans</code>.
254
   *
255
   * Depending on the value of <code>forward</code> the components are
256
   * placed in the forward direction (left-right or top-bottom), where
257
   * the offsets begin with 0, or in the reverse direction
258
   * (right-left or bottom-top).
259
   *
260
   * @param allocated the amount of allocated space
261
   * @param total the total size requirements of the components
262
   * @param children the size requirement of each component
263
   * @param offsets will hold the offset values for each component
264
   * @param spans will hold the span values for each component
265
   * @param forward whether the components should be placed in the forward
266
   *     direction (left-right or top-bottom) or reverse direction
267
   *     (right-left or bottom-top)
268
   */
269
  public static void calculateTiledPositions(int allocated,
270
                                             SizeRequirements total,
271
                                             SizeRequirements[] children,
272
                                             int[] offsets, int[] spans,
273
                                             boolean forward)
274
  {
275
    int span = 0;
276
    if (forward)
277
      {
278
        int offset = 0;
279
        for (int i = 0; i < children.length; i++)
280
          {
281
            offsets[i] = offset;
282
            spans[i] = children[i].preferred;
283
            span += spans[i];
284
            offset += children[i].preferred;
285
          }
286
      }
287
    else
288
      {
289
        int offset = allocated;
290
        for (int i = 0; i < children.length; i++)
291
          {
292
            offset -= children[i].preferred;
293
            offsets[i] = offset;
294
            span += spans[i];
295
            spans[i] = children[i].preferred;
296
          }
297
      }
298
    // Adjust spans so that we exactly fill the allocated region. If
299
    if (span > allocated)
300
      adjustSmaller(allocated, children, spans, span);
301
    else if (span < allocated)
302
      adjustGreater(allocated, children, spans, span);
303
 
304
    // Adjust offsets.
305
    if (forward)
306
      {
307
        int offset = 0;
308
        for (int i = 0; i < children.length; i++)
309
          {
310
            offsets[i] = offset;
311
            offset += spans[i];
312
          }
313
      }
314
    else
315
      {
316
        int offset = allocated;
317
        for (int i = 0; i < children.length; i++)
318
          {
319
            offset -= spans[i];
320
            offsets[i] = offset;
321
          }
322
      }
323
  }
324
 
325
  private static void adjustSmaller(int allocated, SizeRequirements[] children,
326
                                    int[] spans, int span)
327
  {
328
    // Sum up (prefSize - minSize) over all children
329
    int sumDelta = 0;
330
    for (int i = 0; i < children.length; i++)
331
      sumDelta += children[i].preferred - children[i].minimum;
332
 
333
    // If we have sumDelta == 0, then all components have prefSize == maxSize
334
    // and we can't do anything about it.
335
    if (sumDelta == 0)
336
      return;
337
 
338
    // Adjust all sizes according to their preferred and minimum sizes.
339
    for (int i = 0; i < children.length; i++)
340
      {
341
        double factor = ((double) (children[i].preferred - children[i].minimum))
342
                        / ((double) sumDelta);
343
        // In case we have a sumDelta of 0, the factor should also be 0.
344
        if (Double.isNaN(factor))
345
          factor = 0;
346
        spans[i] -= factor * (span - allocated);
347
      }
348
  }
349
 
350
  private static void adjustGreater(int allocated, SizeRequirements[] children,
351
                                    int[] spans, int span)
352
  {
353
    // Sum up (maxSize - prefSize) over all children
354
    long sumDelta = 0;
355
    for (int i = 0; i < children.length; i++)
356
      {
357
        sumDelta += children[i].maximum - children[i].preferred;
358
      }
359
 
360
    // If we have sumDelta == 0, then all components have prefSize == maxSize
361
    // and we can't do anything about it.
362
    if (sumDelta == 0)
363
      return;
364
 
365
    // Adjust all sizes according to their preferred and minimum sizes.
366
    for (int i = 0; i < children.length; i++)
367
      {
368
        double factor = ((double) (children[i].maximum - children[i].preferred))
369
                        / ((double) sumDelta);
370
        spans[i] += factor * (allocated - span);
371
      }
372
  }
373
 
374
  /**
375
   * Calculate the offsets and spans of the components, when they should
376
   * be placed end-to-end.
377
   *
378
   * You must specify the amount of allocated space in
379
   * <code>allocated</code>, the total size requirements of the set of
380
   * components in <code>total</code> (this can be calculated using
381
   * {@link #getTiledSizeRequirements} and the size requirements of the
382
   * components in <code>children</code>.
383
   *
384
   * The calculated offset and span values for each component are then
385
   * stored in the arrays <code>offsets</code> and <code>spans</code>.
386
   *
387
   * The components are tiled in the forward direction, beginning with
388
   * an offset of 0.
389
   *
390
   * @param allocated the amount of allocated space
391
   * @param total the total size requirements of the components
392
   * @param children the size requirement of each component
393
   * @param offsets will hold the offset values for each component
394
   * @param spans will hold the span values for each component
395
   */
396
  public static void calculateAlignedPositions(int allocated,
397
                                               SizeRequirements total,
398
                                               SizeRequirements[] children,
399
                                               int[] offsets, int[] spans)
400
  {
401
    calculateAlignedPositions(allocated, total, children, offsets, spans,
402
                              true);
403
  }
404
 
405
  /**
406
   * Calculate the offsets and spans of the components, when they should
407
   * be placed end-to-end.
408
   *
409
   * You must specify the amount of allocated space in
410
   * <code>allocated</code>, the total size requirements of the set of
411
   * components in <code>total</code> (this can be calculated using
412
   * {@link #getTiledSizeRequirements} and the size requirements of the
413
   * components in <code>children</code>.
414
   *
415
   * The calculated offset and span values for each component are then
416
   * stored in the arrays <code>offsets</code> and <code>spans</code>.
417
   *
418
   * Depending on the value of <code>forward</code> the components are
419
   * placed in the forward direction (left-right or top-bottom), where
420
   * the offsets begin with 0, or in the reverse direction
421
   * (right-left or bottom-top).
422
   *
423
   * @param allocated the amount of allocated space
424
   * @param total the total size requirements of the components
425
   * @param children the size requirement of each component
426
   * @param spans will hold the span values for each component
427
   * @param forward whether the components should be placed in the forward
428
   *     direction (left-right or top-bottom) or reverse direction
429
   *     (right-left or bottom-top)
430
   */
431
  public static void calculateAlignedPositions(int allocated,
432
                                               SizeRequirements total,
433
                                               SizeRequirements[] children,
434
                                               int[] offset, int[] spans,
435
                                               boolean forward)
436
  {
437
    // First we compute the position of the baseline.
438
    float baseline = allocated * total.alignment;
439
 
440
    // Now we can layout the components along the baseline.
441
    for (int i = 0; i < children.length; i++)
442
      {
443
        float align = children[i].alignment;
444
        // Try to fit the component into the available space.
445
        int[] spanAndOffset = new int[2];
446
        if (align < .5F || baseline == 0)
447
          adjustFromRight(children[i], baseline, allocated, spanAndOffset);
448
        else
449
          adjustFromLeft(children[i], baseline, allocated, spanAndOffset);
450
        spans[i] = spanAndOffset[0];
451
        offset[i] = spanAndOffset[1];
452
      }
453
  }
454
 
455
  /**
456
   * Adjusts the span and offset of a component for the aligned layout.
457
   *
458
   * @param reqs
459
   * @param baseline
460
   * @param allocated
461
   * @param spanAndOffset
462
   */
463
  private static void adjustFromRight(SizeRequirements reqs, float baseline,
464
                                      int allocated, int[] spanAndOffset)
465
  {
466
    float right = allocated - baseline;
467
    // If the resulting span exceeds the maximum of the component, then adjust
468
    // accordingly.
469
    float maxRight = ((float) reqs.maximum) * (1.F - reqs.alignment);
470
    if (right / (1.F - reqs.alignment) > reqs.maximum)
471
      right = maxRight;
472
    // If we have not enough space on the left side, then adjust accordingly.
473
    if (right / (1.F - reqs.alignment) * reqs.alignment > allocated - baseline)
474
      right = ((float) (allocated - baseline))
475
             / reqs.alignment * (1.F - reqs.alignment);
476
 
477
    spanAndOffset[0] = (int) (right / (1.F - reqs.alignment));
478
    spanAndOffset[1] = (int) (baseline - spanAndOffset[0] * reqs.alignment);
479
  }
480
 
481
  /**
482
   * Adjusts the span and offset of a component for the aligned layout.
483
   *
484
   * @param reqs
485
   * @param baseline
486
   * @param allocated
487
   * @param spanAndOffset
488
   */
489
  private static void adjustFromLeft(SizeRequirements reqs, float baseline,
490
                                     int allocated, int[] spanAndOffset)
491
  {
492
    float left = baseline;
493
    // If the resulting span exceeds the maximum of the component, then adjust
494
    // accordingly.
495
    float maxLeft = ((float) reqs.maximum) * reqs.alignment;
496
    if (left / reqs.alignment > reqs.maximum)
497
      left = maxLeft;
498
    // If we have not enough space on the right side, then adjust accordingly.
499
    if (left / reqs.alignment * (1.F - reqs.alignment) > allocated - baseline)
500
      left = ((float) (allocated - baseline))
501
             / (1.F - reqs.alignment) * reqs.alignment;
502
 
503
    spanAndOffset[0] = (int) (left / reqs.alignment);
504
    spanAndOffset[1] = (int) (baseline - spanAndOffset[0] * reqs.alignment);
505
  }
506
 
507
  /**
508
   * Returns an array of new preferred sizes for the children based on
509
   * <code>delta</code>. <code>delta</code> specifies a change in the
510
   * allocated space. The sizes of the children will be shortened or
511
   * lengthened to accomodate the new allocation.
512
   *
513
   * @param delta the change of the size of the total allocation for
514
   *     the components
515
   * @param children the size requirements of each component
516
   *
517
   * @return the new preferred sizes for each component
518
   */
519
  public static int[] adjustSizes(int delta, SizeRequirements[] children)
520
  {
521
    return null; // TODO
522
  }
523
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.