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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* View.java --
2
   Copyright (C) 2002, 2004, 2005, 2006  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
 
39
package javax.swing.text;
40
 
41
import java.awt.Container;
42
import java.awt.Graphics;
43
import java.awt.Rectangle;
44
import java.awt.Shape;
45
 
46
import javax.swing.SwingConstants;
47
import javax.swing.SwingUtilities;
48
import javax.swing.event.DocumentEvent;
49
 
50
public abstract class View implements SwingConstants
51
{
52
  public static final int BadBreakWeight = 0;
53
  public static final int ExcellentBreakWeight = 2000;
54
  public static final int ForcedBreakWeight = 3000;
55
  public static final int GoodBreakWeight = 1000;
56
 
57
  public static final int X_AXIS = 0;
58
  public static final int Y_AXIS = 1;
59
 
60
  private Element elt;
61
  private View parent;
62
 
63
  /**
64
   * Creates a new <code>View</code> instance.
65
   *
66
   * @param elem an <code>Element</code> value
67
   */
68
  public View(Element elem)
69
  {
70
    elt = elem;
71
  }
72
 
73
  public abstract void paint(Graphics g, Shape s);
74
 
75
  /**
76
   * Sets the parent for this view. This is the first method that is beeing
77
   * called on a view to setup the view hierarchy. This is also the last method
78
   * beeing called when the view is disconnected from the view hierarchy, in
79
   * this case <code>parent</code> is null.
80
   *
81
   * If <code>parent</code> is <code>null</code>, a call to this method also
82
   * calls <code>setParent</code> on the children, thus disconnecting them from
83
   * the view hierarchy. That means that super must be called when this method
84
   * is overridden.
85
   *
86
   * @param parent the parent to set, <code>null</code> when this view is
87
   *        beeing disconnected from the view hierarchy
88
   */
89
  public void setParent(View parent)
90
  {
91
    if (parent == null)
92
      {
93
        int numChildren = getViewCount();
94
        for (int i = 0; i < numChildren; i++)
95
          {
96
            View child = getView(i);
97
            // It is important that we only reset the parent on views that
98
            // actually belong to us. In FlowView the child may already be
99
            // reparented.
100
            if (child.getParent() == this)
101
              child.setParent(null);
102
          }
103
      }
104
 
105
    this.parent = parent;
106
  }
107
 
108
  public View getParent()
109
  {
110
    return parent;
111
  }
112
 
113
  public Container getContainer()
114
  {
115
    View parent = getParent();
116
    if (parent == null)
117
      return null;
118
    else
119
      return parent.getContainer();
120
  }
121
 
122
  public Document getDocument()
123
  {
124
    return getElement().getDocument();
125
  }
126
 
127
  public Element getElement()
128
  {
129
    return elt;
130
  }
131
 
132
  /**
133
   * Returns the preferred span along the specified axis. Normally the view is
134
   * rendered with the span returned here if that is possible.
135
   *
136
   * @param axis the axis
137
   *
138
   * @return the preferred span along the specified axis
139
   */
140
  public abstract float getPreferredSpan(int axis);
141
 
142
  /**
143
   * Returns the resize weight of this view. A value of <code>0</code> or less
144
   * means this view is not resizeable. Positive values make the view
145
   * resizeable. The default implementation returns <code>0</code>
146
   * unconditionally.
147
   *
148
   * @param axis the axis
149
   *
150
   * @return the resizability of this view along the specified axis
151
   */
152
  public int getResizeWeight(int axis)
153
  {
154
    return 0;
155
  }
156
 
157
  /**
158
   * Returns the maximum span along the specified axis. The default
159
   * implementation will forward to
160
   * {@link #getPreferredSpan(int)} unless {@link #getResizeWeight(int)}
161
   * returns a value > 0, in which case this returns {@link Integer#MIN_VALUE}.
162
   *
163
   * @param axis the axis
164
   *
165
   * @return the maximum span along the specified axis
166
   */
167
  public float getMaximumSpan(int axis)
168
  {
169
    float max = Integer.MAX_VALUE;
170
    if (getResizeWeight(axis) <= 0)
171
      max = getPreferredSpan(axis);
172
    return max;
173
  }
174
 
175
  /**
176
   * Returns the minimum span along the specified axis. The default
177
   * implementation will forward to
178
   * {@link #getPreferredSpan(int)} unless {@link #getResizeWeight(int)}
179
   * returns a value > 0, in which case this returns <code>0</code>.
180
   *
181
   * @param axis the axis
182
   *
183
   * @return the minimum span along the specified axis
184
   */
185
  public float getMinimumSpan(int axis)
186
  {
187
    float min = 0;
188
    if (getResizeWeight(axis) <= 0)
189
      min = getPreferredSpan(axis);
190
    return min;
191
  }
192
 
193
  public void setSize(float width, float height)
194
  {
195
    // The default implementation does nothing.
196
  }
197
 
198
  /**
199
   * Returns the alignment of this view along the baseline of the parent view.
200
   * An alignment of <code>0.0</code> will align this view with the left edge
201
   * along the baseline, an alignment of <code>0.5</code> will align it
202
   * centered to the baseline, an alignment of <code>1.0</code> will align
203
   * the right edge along the baseline.
204
   *
205
   * The default implementation returns 0.5 unconditionally.
206
   *
207
   * @param axis the axis
208
   *
209
   * @return the alignment of this view along the parents baseline for the
210
   *         specified axis
211
   */
212
  public float getAlignment(int axis)
213
  {
214
    return 0.5f;
215
  }
216
 
217
  public AttributeSet getAttributes()
218
  {
219
    return getElement().getAttributes();
220
  }
221
 
222
  public boolean isVisible()
223
  {
224
    return true;
225
  }
226
 
227
  public int getViewCount()
228
  {
229
    return 0;
230
  }
231
 
232
  public View getView(int index)
233
  {
234
    return null;
235
  }
236
 
237
  public ViewFactory getViewFactory()
238
  {
239
    View parent = getParent();
240
    return parent != null ? parent.getViewFactory() : null;
241
  }
242
 
243
  /**
244
   * Replaces a couple of child views with new child views. If
245
   * <code>length == 0</code> then this is a simple insertion, if
246
   * <code>views == null</code> this only removes some child views.
247
   *
248
   * @param offset the offset at which to replace
249
   * @param length the number of child views to be removed
250
   * @param views the new views to be inserted, may be <code>null</code>
251
   */
252
  public void replace(int offset, int length, View[] views)
253
  {
254
    // Default implementation does nothing.
255
  }
256
 
257
  public void insert(int offset, View view)
258
  {
259
    View[] array = { view };
260
    replace(offset, 1, array);
261
  }
262
 
263
  public void append(View view)
264
  {
265
    View[] array = { view };
266
    int offset = getViewCount();
267
    replace(offset, 0, array);
268
  }
269
 
270
  public void removeAll()
271
  {
272
    replace(0, getViewCount(), null);
273
  }
274
 
275
  public void remove(int index)
276
  {
277
    replace(index, 1, null);
278
  }
279
 
280
  public View createFragment(int p0, int p1)
281
  {
282
    // The default implementation doesn't support fragmentation.
283
    return this;
284
  }
285
 
286
  public int getStartOffset()
287
  {
288
    return getElement().getStartOffset();
289
  }
290
 
291
  public int getEndOffset()
292
  {
293
    return getElement().getEndOffset();
294
  }
295
 
296
  public Shape getChildAllocation(int index, Shape a)
297
  {
298
    return null;
299
  }
300
 
301
  /**
302
   * @since 1.4
303
   */
304
  public int getViewIndex(float x, float y, Shape allocation)
305
  {
306
    return -1;
307
  }
308
 
309
  /**
310
   * @since 1.4
311
   */
312
  public String getToolTipText(float x, float y, Shape allocation)
313
  {
314
    int index = getViewIndex(x, y, allocation);
315
 
316
    String text = null;
317
    if (index >= 0)
318
      {
319
        allocation = getChildAllocation(index, allocation);
320
        Rectangle r = allocation instanceof Rectangle ? (Rectangle) allocation
321
                                                      : allocation.getBounds();
322
        if (r.contains(x, y))
323
          text = getView(index).getToolTipText(x, y, allocation);
324
      }
325
    return text;
326
  }
327
 
328
  /**
329
   * @since 1.3
330
   */
331
  public Graphics getGraphics()
332
  {
333
    return getContainer().getGraphics();
334
  }
335
 
336
  public void preferenceChanged(View child, boolean width, boolean height)
337
  {
338
    View p = getParent();
339
    if (p != null)
340
      p.preferenceChanged(this, width, height);
341
  }
342
 
343
  public int getBreakWeight(int axis, float pos, float len)
344
  {
345
    int weight = BadBreakWeight;
346
    if (len > getPreferredSpan(axis))
347
      weight = GoodBreakWeight;
348
    return weight;
349
  }
350
 
351
  public View breakView(int axis, int offset, float pos, float len)
352
  {
353
    return this;
354
  }
355
 
356
  /**
357
   * @since 1.3
358
   */
359
  public int getViewIndex(int pos, Position.Bias b)
360
  {
361
    return -1;
362
  }
363
 
364
  /**
365
   * Receive notification about an insert update to the text model.
366
   *
367
   * The default implementation of this method does the following:
368
   * <ul>
369
   * <li>Call {@link #updateChildren} if the element that this view is
370
   * responsible for has changed. This makes sure that the children can
371
   * correctly represent the model.<li>
372
   * <li>Call {@link #forwardUpdate}. This forwards the DocumentEvent to
373
   * the child views.<li>
374
   * <li>Call {@link #updateLayout}. Gives the view a chance to either
375
   * repair its layout, reschedule layout or do nothing at all.</li>
376
   * </ul>
377
   *
378
   * @param ev the DocumentEvent that describes the change
379
   * @param shape the shape of the view
380
   * @param vf the ViewFactory for creating child views
381
   */
382
  public void insertUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
383
  {
384
    if (getViewCount() > 0)
385
      {
386
        Element el = getElement();
387
        DocumentEvent.ElementChange ec = ev.getChange(el);
388
        if (ec != null)
389
          {
390
            if (! updateChildren(ec, ev, vf))
391
              ec = null;
392
          }
393
        forwardUpdate(ec, ev, shape, vf);
394
        updateLayout(ec, ev, shape);
395
      }
396
  }
397
 
398
  /**
399
   * Receive notification about a remove update to the text model.
400
   *
401
   * The default implementation of this method does the following:
402
   * <ul>
403
   * <li>Call {@link #updateChildren} if the element that this view is
404
   * responsible for has changed. This makes sure that the children can
405
   * correctly represent the model.<li>
406
   * <li>Call {@link #forwardUpdate}. This forwards the DocumentEvent to
407
   * the child views.<li>
408
   * <li>Call {@link #updateLayout}. Gives the view a chance to either
409
   * repair its layout, reschedule layout or do nothing at all.</li>
410
   * </ul>
411
   *
412
   * @param ev the DocumentEvent that describes the change
413
   * @param shape the shape of the view
414
   * @param vf the ViewFactory for creating child views
415
   */
416
  public void removeUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
417
  {
418
    Element el = getElement();
419
    DocumentEvent.ElementChange ec = ev.getChange(el);
420
    if (ec != null)
421
      {
422
        if (! updateChildren(ec, ev, vf))
423
          ec = null;
424
      }
425
    forwardUpdate(ec, ev, shape, vf);
426
    updateLayout(ec, ev, shape);
427
  }
428
 
429
  /**
430
   * Receive notification about a change update to the text model.
431
   *
432
   * The default implementation of this method does the following:
433
   * <ul>
434
   * <li>Call {@link #updateChildren} if the element that this view is
435
   * responsible for has changed. This makes sure that the children can
436
   * correctly represent the model.<li>
437
   * <li>Call {@link #forwardUpdate}. This forwards the DocumentEvent to
438
   * the child views.<li>
439
   * <li>Call {@link #updateLayout}. Gives the view a chance to either
440
   * repair its layout, reschedule layout or do nothing at all.</li>
441
   * </ul>
442
   *
443
   * @param ev the DocumentEvent that describes the change
444
   * @param shape the shape of the view
445
   * @param vf the ViewFactory for creating child views
446
   */
447
  public void changedUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
448
  {
449
    if (getViewCount() > 0)
450
      {
451
        Element el = getElement();
452
        DocumentEvent.ElementChange ec = ev.getChange(el);
453
        if (ec != null)
454
          {
455
            if (! updateChildren(ec, ev, vf))
456
              ec = null;
457
          }
458
        forwardUpdate(ec, ev, shape, vf);
459
        updateLayout(ec, ev, shape);
460
      }
461
  }
462
 
463
  /**
464
   * Updates the list of children that is returned by {@link #getView}
465
   * and {@link #getViewCount}.
466
   *
467
   * Element that are specified as beeing added in the ElementChange record are
468
   * assigned a view for using the ViewFactory. Views of Elements that
469
   * are specified as beeing removed are removed from the list.
470
   *
471
   * @param ec the ElementChange record that describes the change of the
472
   *           element
473
   * @param ev the DocumentEvent describing the change of the document model
474
   * @param vf the ViewFactory to use for creating new views
475
   *
476
   * @return whether or not the child views represent the child elements of
477
   *         the element that this view is responsible for. Some views may
478
   *         create views that are responsible only for parts of the element
479
   *         that they are responsible for and should then return false.
480
   *
481
   * @since 1.3
482
   */
483
  protected boolean updateChildren(DocumentEvent.ElementChange ec,
484
                                   DocumentEvent ev,
485
                                   ViewFactory vf)
486
  {
487
    Element[] added = ec.getChildrenAdded();
488
    Element[] removed = ec.getChildrenRemoved();
489
    int index = ec.getIndex();
490
 
491
    View[] newChildren = null;
492
    if (added != null)
493
      {
494
        newChildren = new View[added.length];
495
        for (int i = 0; i < added.length; ++i)
496
          newChildren[i] = vf.create(added[i]);
497
      }
498
    int numRemoved = removed != null ? removed.length : 0;
499
    replace(index, numRemoved, newChildren);
500
 
501
    return true;
502
  }
503
 
504
  /**
505
   * Forwards the DocumentEvent to child views that need to get notified
506
   * of the change to the model. This calles {@link #forwardUpdateToView}
507
   * for each View that must be forwarded to.
508
   *
509
   * If <code>ec</code> is not <code>null</code> (this means there have been
510
   * structural changes to the element that this view is responsible for) this
511
   * method should recognize this and don't notify newly added child views.
512
   *
513
   * @param ec the ElementChange describing the element changes (may be
514
   *           <code>null</code> if there were no changes)
515
   * @param ev the DocumentEvent describing the changes to the model
516
   * @param shape the current allocation of the view
517
   * @param vf the ViewFactory used to create new Views
518
   *
519
   * @since 1.3
520
   */
521
  protected void forwardUpdate(DocumentEvent.ElementChange ec,
522
                               DocumentEvent ev, Shape shape, ViewFactory vf)
523
  {
524
    int count = getViewCount();
525
    if (count > 0)
526
      {
527
        // Determine start index.
528
        int startOffset = ev.getOffset();
529
        int startIndex = getViewIndex(startOffset, Position.Bias.Backward);
530
 
531
        // For REMOVE events we have to forward the event to the last element,
532
        // for the case that an Element has been removed that represente
533
        // the offset.
534
        if (startIndex == -1 && ev.getType() == DocumentEvent.EventType.REMOVE
535
            && startOffset >= getEndOffset())
536
          {
537
            startIndex = getViewCount() - 1;
538
          }
539
 
540
        // When startIndex is on a view boundary, forward event to the
541
        // previous view too.
542
        if (startIndex >= 0)
543
          {
544
            View v = getView(startIndex);
545
            if (v != null)
546
              {
547
                if (v.getStartOffset() == startOffset && startOffset > 0)
548
                  startIndex = Math.max(0, startIndex - 1);
549
              }
550
          }
551
        startIndex = Math.max(0, startIndex);
552
 
553
        // Determine end index.
554
        int endIndex = startIndex;
555
        if (ev.getType() != DocumentEvent.EventType.REMOVE)
556
          {
557
            endIndex = getViewIndex(startOffset + ev.getLength(),
558
                                    Position.Bias.Forward);
559
            if (endIndex < 0)
560
              endIndex = getViewCount() - 1;
561
          }
562
 
563
        // Determine hole that comes from added elements (we don't forward
564
        // the event to newly added views.
565
        int startAdded = endIndex + 1;
566
        int endAdded = startAdded;
567
        Element[] added = (ec != null) ? ec.getChildrenAdded() : null;
568
        if (added != null && added.length > 0)
569
          {
570
            startAdded = ec.getIndex();
571
            endAdded = startAdded + added.length - 1;
572
          }
573
 
574
        // Forward event to all views between startIndex and endIndex,
575
        // and leave out all views in the hole.
576
        for (int i = startIndex; i <= endIndex; i++)
577
          {
578
            // Skip newly added child views.
579
            if (! (i >= startAdded && i <= endAdded))
580
              {
581
                View child = getView(i);
582
                if (child != null)
583
                  {
584
                    Shape childAlloc = getChildAllocation(i, shape);
585
                    forwardUpdateToView(child, ev, childAlloc, vf);
586
                  }
587
              }
588
          }
589
      }
590
  }
591
 
592
  /**
593
   * Forwards an update event to the given child view. This calls
594
   * {@link #insertUpdate}, {@link #removeUpdate} or {@link #changedUpdate},
595
   * depending on the type of document event.
596
   *
597
   * @param view the View to forward the event to
598
   * @param ev the DocumentEvent to forward
599
   * @param shape the current allocation of the View
600
   * @param vf the ViewFactory used to create new Views
601
   *
602
   * @since 1.3
603
   */
604
  protected void forwardUpdateToView(View view, DocumentEvent ev, Shape shape,
605
                                     ViewFactory vf)
606
  {
607
    DocumentEvent.EventType type = ev.getType();
608
    if (type == DocumentEvent.EventType.INSERT)
609
      view.insertUpdate(ev, shape, vf);
610
    else if (type == DocumentEvent.EventType.REMOVE)
611
      view.removeUpdate(ev, shape, vf);
612
    else if (type == DocumentEvent.EventType.CHANGE)
613
      view.changedUpdate(ev, shape, vf);
614
  }
615
 
616
  /**
617
   * Updates the layout.
618
   *
619
   * @param ec the ElementChange that describes the changes to the element
620
   * @param ev the DocumentEvent that describes the changes to the model
621
   * @param shape the current allocation for this view
622
   *
623
   * @since 1.3
624
   */
625
  protected void updateLayout(DocumentEvent.ElementChange ec,
626
                              DocumentEvent ev, Shape shape)
627
  {
628
    if (ec != null && shape != null)
629
      {
630
        preferenceChanged(null, true, true);
631
        Container c = getContainer();
632
        if (c != null)
633
          c.repaint();
634
      }
635
  }
636
 
637
  /**
638
   * Maps a position in the document into the coordinate space of the View.
639
   * The output rectangle usually reflects the font height but has a width
640
   * of zero.
641
   *
642
   * @param pos the position of the character in the model
643
   * @param a the area that is occupied by the view
644
   * @param b either {@link Position.Bias#Forward} or
645
   *        {@link Position.Bias#Backward} depending on the preferred
646
   *        direction bias. If <code>null</code> this defaults to
647
   *        <code>Position.Bias.Forward</code>
648
   *
649
   * @return a rectangle that gives the location of the document position
650
   *         inside the view coordinate space
651
   *
652
   * @throws BadLocationException if <code>pos</code> is invalid
653
   * @throws IllegalArgumentException if b is not one of the above listed
654
   *         valid values
655
   */
656
  public abstract Shape modelToView(int pos, Shape a, Position.Bias b)
657
    throws BadLocationException;
658
 
659
  /**
660
   * Maps a region in the document into the coordinate space of the View.
661
   *
662
   * @param p1 the beginning position inside the document
663
   * @param b1 the direction bias for the beginning position
664
   * @param p2 the end position inside the document
665
   * @param b2 the direction bias for the end position
666
   * @param a the area that is occupied by the view
667
   *
668
   * @return a rectangle that gives the span of the document region
669
   *         inside the view coordinate space
670
   *
671
   * @throws BadLocationException if <code>p1</code> or <code>p2</code> are
672
   *         invalid
673
   * @throws IllegalArgumentException if b1 or b2 is not one of the above
674
   *         listed valid values
675
   */
676
  public Shape modelToView(int p1, Position.Bias b1,
677
                           int p2, Position.Bias b2, Shape a)
678
    throws BadLocationException
679
  {
680
    if (b1 != Position.Bias.Forward && b1 != Position.Bias.Backward)
681
      throw new IllegalArgumentException
682
        ("b1 must be either Position.Bias.Forward or Position.Bias.Backward");
683
    if (b2 != Position.Bias.Forward && b2 != Position.Bias.Backward)
684
      throw new IllegalArgumentException
685
        ("b2 must be either Position.Bias.Forward or Position.Bias.Backward");
686
 
687
    Shape s1 = modelToView(p1, a, b1);
688
    // Special case for p2 == end index.
689
    Shape s2;
690
    if (p2 != getEndOffset())
691
      {
692
        s2 = modelToView(p2, a, b2);
693
      }
694
    else
695
      {
696
        try
697
          {
698
            s2 = modelToView(p2, a, b2);
699
          }
700
        catch (BadLocationException ex)
701
          {
702
            // Assume the end rectangle to be at the right edge of the
703
            // view.
704
            Rectangle aRect = a instanceof Rectangle ? (Rectangle) a
705
                                                     : a.getBounds();
706
            s2 = new Rectangle(aRect.x + aRect.width - 1, aRect.y, 1,
707
                               aRect.height);
708
          }
709
      }
710
 
711
    // Need to modify the rectangle, so we create a copy in all cases.
712
    Rectangle r1 = s1.getBounds();
713
    Rectangle r2 = s2 instanceof Rectangle ? (Rectangle) s2
714
                                           : s2.getBounds();
715
 
716
    // For multiline view, let the resulting rectangle span the whole view.
717
    if (r1.y != r2.y)
718
      {
719
        Rectangle aRect = a instanceof Rectangle ? (Rectangle) a
720
                                                 : a.getBounds();
721
        r1.x = aRect.x;
722
        r1.width = aRect.width;
723
      }
724
 
725
    return SwingUtilities.computeUnion(r2.x, r2.y, r2.width, r2.height, r1);
726
  }
727
 
728
  /**
729
   * Maps a position in the document into the coordinate space of the View.
730
   * The output rectangle usually reflects the font height but has a width
731
   * of zero.
732
   *
733
   * This method is deprecated and calls
734
   * {@link #modelToView(int, Position.Bias, int, Position.Bias, Shape)} with
735
   * a bias of {@link Position.Bias#Forward}.
736
   *
737
   * @param pos the position of the character in the model
738
   * @param a the area that is occupied by the view
739
   *
740
   * @return a rectangle that gives the location of the document position
741
   *         inside the view coordinate space
742
   *
743
   * @throws BadLocationException if <code>pos</code> is invalid
744
   *
745
   * @deprecated Use {@link #modelToView(int, Shape, Position.Bias)} instead.
746
   */
747
  public Shape modelToView(int pos, Shape a) throws BadLocationException
748
  {
749
    return modelToView(pos, a, Position.Bias.Forward);
750
  }
751
 
752
  /**
753
   * Maps coordinates from the <code>View</code>'s space into a position
754
   * in the document model.
755
   *
756
   * @param x the x coordinate in the view space
757
   * @param y the y coordinate in the view space
758
   * @param a the allocation of this <code>View</code>
759
   * @param b the bias to use
760
   *
761
   * @return the position in the document that corresponds to the screen
762
   *         coordinates <code>x, y</code>
763
   */
764
  public abstract int viewToModel(float x, float y, Shape a, Position.Bias[] b);
765
 
766
  /**
767
   * Maps coordinates from the <code>View</code>'s space into a position
768
   * in the document model. This method is deprecated and only there for
769
   * compatibility.
770
   *
771
   * @param x the x coordinate in the view space
772
   * @param y the y coordinate in the view space
773
   * @param a the allocation of this <code>View</code>
774
   *
775
   * @return the position in the document that corresponds to the screen
776
   *         coordinates <code>x, y</code>
777
   *
778
   * @deprecated Use {@link #viewToModel(float, float, Shape, Position.Bias[])}
779
   *             instead.
780
   */
781
  public int viewToModel(float x, float y, Shape a)
782
  {
783
    Position.Bias[] biasRet = new Position.Bias[1];
784
    biasRet[0] = Position.Bias.Forward;
785
    return viewToModel(x, y, a, biasRet);
786
  }
787
 
788
  /**
789
   * Dumps the complete View hierarchy. This method can be used for debugging
790
   * purposes.
791
   */
792
  protected void dump()
793
  {
794
    // Climb up the hierarchy to the parent.
795
    View parent = getParent();
796
    if (parent != null)
797
      parent.dump();
798
    else
799
      dump(0);
800
  }
801
 
802
  /**
803
   * Dumps the view hierarchy below this View with the specified indentation
804
   * level.
805
   *
806
   * @param indent the indentation level to be used for this view
807
   */
808
  void dump(int indent)
809
  {
810
    for (int i = 0; i < indent; ++i)
811
      System.out.print('.');
812
    System.out.println(this + "(" + getStartOffset() + "," + getEndOffset() + ": " + getElement());
813
 
814
    int count = getViewCount();
815
    for (int i = 0; i < count; ++i)
816
      getView(i).dump(indent + 1);
817
  }
818
 
819
  /**
820
   * Returns the document position that is (visually) nearest to the given
821
   * document position <code>pos</code> in the given direction <code>d</code>.
822
   *
823
   * @param pos the document position
824
   * @param b the bias for <code>pos</code>
825
   * @param a the allocation for this view
826
   * @param d the direction, must be either {@link SwingConstants#NORTH},
827
   *        {@link SwingConstants#SOUTH}, {@link SwingConstants#WEST} or
828
   *        {@link SwingConstants#EAST}
829
   * @param biasRet an array of {@link Position.Bias} that can hold at least
830
   *        one element, which is filled with the bias of the return position
831
   *        on method exit
832
   *
833
   * @return the document position that is (visually) nearest to the given
834
   *         document position <code>pos</code> in the given direction
835
   *         <code>d</code>
836
   *
837
   * @throws BadLocationException if <code>pos</code> is not a valid offset in
838
   *         the document model
839
   * @throws IllegalArgumentException if <code>d</code> is not a valid direction
840
   */
841
  public int getNextVisualPositionFrom(int pos, Position.Bias b,
842
                                       Shape a, int d,
843
                                       Position.Bias[] biasRet)
844
    throws BadLocationException
845
  {
846
    int ret = pos;
847
    Rectangle r;
848
    View parent;
849
 
850
    switch (d)
851
    {
852
      case EAST:
853
        // TODO: take component orientation into account?
854
        // Note: If pos is below zero the implementation will return
855
        // pos + 1 regardless of whether that value is a correct offset
856
        // in the document model. However this is what the RI does.
857
        ret = Math.min(pos + 1, getEndOffset());
858
        break;
859
      case WEST:
860
        // TODO: take component orientation into account?
861
        ret = Math.max(pos - 1, getStartOffset());
862
        break;
863
      case NORTH:
864
        // Try to find a suitable offset by examining the area above.
865
        parent = getParent();
866
        r =  parent.modelToView(pos, a, b).getBounds();
867
        ret = parent.viewToModel(r.x, r.y - 1, a, biasRet);
868
        break;
869
      case SOUTH:
870
        // Try to find a suitable offset by examining the area below.
871
        parent = getParent();
872
        r =  parent.modelToView(pos, a, b).getBounds();
873
        ret = parent.viewToModel(r.x + r.width, r.y + r.height, a, biasRet);
874
        break;
875
      default:
876
        throw new IllegalArgumentException("Illegal value for d");
877
    }
878
 
879
    return ret;
880
  }
881
}

powered by: WebSVN 2.1.0

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