2 * (C) Copyright IBM Corp. 1998-2004. All Rights Reserved.
\r
4 * The program is provided "as is" without any warranty express or
\r
5 * implied, including the warranty of non-infringement and the implied
\r
6 * warranties of merchantibility and fitness for a particular purpose.
\r
7 * IBM will not be liable for any damages suffered by you as a result
\r
8 * of using the Program. In no event will IBM be liable for any
\r
9 * special, indirect or consequential damages or lost profits even if
\r
10 * IBM has been advised of the possibility of their occurrence. IBM
\r
11 * will not be liable for any third party claims against you.
\r
13 package com.ibm.richtext.uiimpl;
\r
15 import java.awt.Color;
\r
16 import java.awt.Component;
\r
17 import java.awt.Dimension;
\r
18 import java.awt.FontMetrics;
\r
19 import java.awt.Graphics;
\r
20 import java.awt.Image;
\r
22 import java.awt.event.MouseMotionListener;
\r
23 import java.awt.event.MouseListener;
\r
24 import java.awt.event.MouseEvent;
\r
26 import com.ibm.richtext.textlayout.attributes.AttributeMap;
\r
27 import com.ibm.richtext.textlayout.attributes.TextAttribute;
\r
29 import com.ibm.richtext.styledtext.MTabRuler;
\r
30 import com.ibm.richtext.styledtext.StandardTabRuler;
\r
31 import com.ibm.richtext.styledtext.TabStop;
\r
32 import com.ibm.richtext.styledtext.StyleModifier;
\r
34 import com.ibm.richtext.textpanel.TextPanelListener;
\r
35 import com.ibm.richtext.textpanel.MTextPanel;
\r
36 import com.ibm.richtext.textpanel.TextPanel;
\r
37 import com.ibm.richtext.textpanel.TextPanelEvent;
\r
40 * TabRuler is a Component which presents a user interface for
\r
41 * setting the leading margin, trailing margin, first line indent,
\r
42 * and tab types and positions.
\r
44 * TabRuler does not implement TextPanelListener directly; however,
\r
45 * it can receive updates from a MTextPanel. To have a TabRuler listen
\r
46 * to a panel, call <code>listenToPanel</code>. TabRuler responds to
\r
47 * user manipulation by modifying the paragraph styles on its MTextPanel
\r
50 public final class TabRulerImpl implements MouseListener, MouseMotionListener
\r
52 static final String COPYRIGHT =
\r
53 "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
\r
54 private static final class TabStopBuffer {
\r
55 public int fPosition;
\r
58 TabStopBuffer(int position, byte type) {
\r
59 fPosition = position;
\r
63 TabStopBuffer(TabStop tab) {
\r
64 this(tab.getPosition(), tab.getType());
\r
67 TabStop getTabStop() {
\r
68 return new TabStop(fPosition, fType);
\r
72 private static final class TabRulerModifier extends StyleModifier {
\r
74 private TabStop fOldTab; // tab to remove
\r
75 private TabStop fNewTab; // tab to add
\r
76 private AttributeMap fPanelDefaults;
\r
78 TabRulerModifier(TabStop oldTab,
\r
80 AttributeMap panelDefaults) {
\r
83 fPanelDefaults = panelDefaults;
\r
86 public AttributeMap modifyStyle(AttributeMap oldStyle) {
\r
88 MTabRuler oldRuler = (MTabRuler) getWithDefault(TextAttribute.TAB_RULER,
\r
91 MTabRuler ruler = oldRuler;
\r
93 if (fOldTab != null) {
\r
94 if (ruler.containsTab(fOldTab)) {
\r
95 ruler = ruler.removeTab(fOldTab.getPosition());
\r
98 if (fNewTab != null) {
\r
99 ruler = ruler.addTab(fNewTab);
\r
102 if (ruler != oldRuler) {
\r
103 return oldStyle.addAttribute(TextAttribute.TAB_RULER, ruler);
\r
111 private static final class ImageCache {
\r
113 static final String COPYRIGHT =
\r
114 "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
\r
115 private Image fImage = null;
\r
116 private boolean fIsValid = false;
\r
117 private Component fComponent; // workaround for compiler bug,
\r
118 // should just be able to say Component.this
\r
119 // if this were not a static class
\r
121 ImageCache(Component component) {
\r
123 fComponent = component;
\r
126 Graphics getGraphics(int width, int height) {
\r
128 if (width <= 0 || height <= 0) {
\r
132 Image image = fImage;
\r
133 if (image == null || image.getWidth(fComponent) < width
\r
134 || image.getHeight(fComponent) < height) {
\r
135 if (!fComponent.isVisible()) { // fix race condition if component not fully initialized
\r
138 image = fComponent.createImage(width, height);
\r
140 Graphics g = image.getGraphics();
\r
145 void drawImage(Graphics g, int x, int y, Color color) {
\r
148 throw new Error("Drawing image when not valid");
\r
150 g.drawImage(fImage, x, y, color, fComponent);
\r
153 boolean isValid() {
\r
158 void setValid(boolean isValid) {
\r
160 fIsValid = isValid;
\r
165 * This class listens to a MTextPanel for changes which
\r
166 * affect a TabRuler's appearance, and updates the TabRuler
\r
169 * @see com.ibm.richtext.textpanel.MTextPanel
\r
171 private static final class Updater implements TextPanelListener {
\r
173 static final String COPYRIGHT =
\r
174 "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
\r
175 private TabRulerImpl fTabRuler;
\r
176 private MTextPanel fTextPanel;
\r
179 * Create a new TabRulerUpdater.
\r
180 * @param tabRuler the TabRuler to update when a change occurs
\r
181 * in the MTextPanel
\r
183 Updater(TabRulerImpl tabRuler) {
\r
185 fTabRuler = tabRuler;
\r
189 * Remove self as listener from previous MTextPanel,
\r
190 * set current MTextPanel and listen to it (if not null).
\r
192 void setTextPanel(MTextPanel textPanel) {
\r
194 if (fTextPanel != null) {
\r
195 fTextPanel.removeListener(this);
\r
198 fTextPanel = textPanel;
\r
200 if (fTextPanel != null) {
\r
201 fTextPanel.addListener(this);
\r
206 private void setAll() {
\r
208 int offset = fTextPanel.getSelectionStart();
\r
209 boolean leftToRight = fTextPanel.paragraphIsLeftToRight(offset);
\r
210 AttributeMap style = fTextPanel.getText().paragraphStyleAt(offset);
\r
211 fTabRuler.set(style, false);
\r
212 fTabRuler.setFormatWidth(fTextPanel.getFormatWidth(), false);
\r
213 fTabRuler.setLeftToRight(leftToRight, true);
\r
217 * TextPanelListener method. This class responds to text
\r
218 * changes by updating its TabRuler.
\r
220 public void textEventOccurred(TextPanelEvent event) {
\r
222 int changeCode = event.getID();
\r
224 if (changeCode == TextPanelEvent.SELECTION_STYLES_CHANGED ||
\r
225 changeCode == TextPanelEvent.TEXT_CHANGED) {
\r
227 int offset = fTextPanel.getSelectionStart();
\r
228 AttributeMap style = fTextPanel.getText().paragraphStyleAt(offset);
\r
229 boolean leftToRight = fTextPanel.paragraphIsLeftToRight(offset);
\r
230 fTabRuler.set(style, false);
\r
231 fTabRuler.setLeftToRight(leftToRight, true);
\r
233 else if (changeCode == TextPanelEvent.FORMAT_WIDTH_CHANGED) {
\r
235 fTabRuler.setFormatWidth(fTextPanel.getFormatWidth(), true);
\r
240 * TextPanelListener method.
\r
242 public boolean respondsToEventType(int type) {
\r
244 return type == TextPanelEvent.SELECTION_STYLES_CHANGED ||
\r
245 type == TextPanelEvent.TEXT_CHANGED ||
\r
246 type == TextPanelEvent.FORMAT_WIDTH_CHANGED;
\r
251 * The default background color for TabRulers.
\r
252 * @see #setBackColor
\r
254 public static final Color DEFAULT_BACK_COLOR = Color.lightGray;
\r
256 private static final int kTrackNone = 0;
\r
257 private static final int kTrackTab = 1;
\r
258 private static final int kTrackLM = 2;
\r
259 private static final int kTrackFLI = 3;
\r
260 private static final int kTrackTM = 4;
\r
262 private Component fHost;
\r
263 private MTabRuler fRuler;
\r
264 private int fLeadingMargin;
\r
265 private int fFirstLineIndent;
\r
266 private int fFormatWidth;
\r
267 private int fTrailingMarginPosition; // opposite of actual trailing margin
\r
268 private boolean fLeftToRight;
\r
269 private int fBaseline;
\r
270 private int fOrigin;
\r
271 private Color fBackColor = DEFAULT_BACK_COLOR;
\r
273 private int fTrackItem; // 0 - none, 1 - tab, 2 - lm, 3 - fli, 4 - tm
\r
274 private TabStopBuffer fTrackTab;
\r
275 private TabStop fOldTab;
\r
276 private int fTrackDelta;
\r
277 private boolean fTrackVisible;
\r
278 private Updater fUpdater;
\r
279 private MTextPanel fTextPanel = null;
\r
281 private ImageCache fImageCache;
\r
284 * Create a new TabRuler.
\r
285 * @param baseline the y-coordinate of the ruler's baseline
\r
286 * @param origin the x-coordinate in this Component where
\r
287 * the left margin appears
\r
288 * @param textPanel the MTextPanel to listen to. This TabRuler
\r
289 * will reflect the MTextPanel's paragraph styles, and update
\r
290 * the paragraph styles when manipulated.
\r
292 public TabRulerImpl(int baseline,
\r
294 MTextPanel textPanel,
\r
298 fImageCache = new ImageCache(host);
\r
299 fUpdater = new Updater(this);
\r
300 fBaseline = baseline;
\r
302 host.addMouseListener(this);
\r
303 host.addMouseMotionListener(this);
\r
304 if (textPanel != null) {
\r
305 listenToTextPanel(textPanel);
\r
308 fRuler = new StandardTabRuler();
\r
313 * Listen to the given MTextPanel and reflect its changes,
\r
314 * and update its paragraph styles when TabRuler is
\r
316 * @param textPanel the MTextPanel to listen to
\r
318 public void listenToTextPanel(MTextPanel textPanel) {
\r
320 fTextPanel = textPanel;
\r
321 fUpdater.setTextPanel(textPanel);
\r
325 * Return the background color of this TabRuler.
\r
326 * @return the background color of this TabRuler
\r
328 public Color getBackColor() {
\r
334 * Set the background color of this TabRuler.
\r
335 * @param backColor the new background color of this TabRuler
\r
337 public void setBackColor(Color backColor) {
\r
339 if (!backColor.equals(fBackColor)) {
\r
340 fBackColor = backColor;
\r
341 Graphics g = fHost.getGraphics();
\r
348 private static Object getWithDefault(Object key,
\r
349 AttributeMap style,
\r
350 AttributeMap defaults) {
\r
351 Object value = style.get(key);
\r
352 if (value == null) {
\r
353 value = defaults.get(key);
\r
358 private static float getFloatWithDefault(Object key,
\r
359 AttributeMap style,
\r
360 AttributeMap defaults) {
\r
361 Object value = getWithDefault(key, style, defaults);
\r
362 return ((Float)value).floatValue();
\r
365 private void setLeftToRight(boolean leftToRight, boolean update) {
\r
367 if (fLeftToRight != leftToRight) {
\r
369 fLeftToRight = leftToRight;
\r
370 redrawSelf(update);
\r
374 private void setFormatWidth(int formatWidth, boolean update) {
\r
376 if (fFormatWidth != formatWidth) {
\r
378 fTrailingMarginPosition += (formatWidth - fFormatWidth);
\r
379 fFormatWidth = formatWidth;
\r
380 redrawSelf(update);
\r
385 * Set TabRuler from values in paragraphStyle. Only TabRulerUpdater
\r
386 * should call this method.
\r
387 * @param paragraphStyle the paragraph style which the TabRuler will
\r
390 private void set(AttributeMap paragraphStyle, boolean update) {
\r
392 AttributeMap panelDefaults;
\r
394 if (fTextPanel==null) {
\r
395 panelDefaults = TextPanel.getDefaultSettings().getDefaultValues();
\r
398 panelDefaults = fTextPanel.getDefaultValues();
\r
401 int leadingMargin = (int) getFloatWithDefault(TextAttribute.LEADING_MARGIN,
\r
404 int firstLineIndent = (int) getFloatWithDefault(TextAttribute.FIRST_LINE_INDENT,
\r
407 int trailingMargin = (int) getFloatWithDefault(TextAttribute.TRAILING_MARGIN,
\r
411 MTabRuler ruler = (MTabRuler) getWithDefault(TextAttribute.TAB_RULER,
\r
415 int ourFli = leadingMargin + firstLineIndent;
\r
416 int ourTmp = fFormatWidth - trailingMargin;
\r
418 if (leadingMargin == fLeadingMargin &&
\r
419 fFirstLineIndent == ourFli &&
\r
420 fTrailingMarginPosition == ourTmp &&
\r
421 ruler.equals(fRuler)) {
\r
425 fLeadingMargin = leadingMargin;
\r
426 fFirstLineIndent = ourFli;
\r
427 fTrailingMarginPosition = ourTmp;
\r
430 redrawSelf(update);
\r
433 private void redrawSelf(boolean drawNow) {
\r
435 fImageCache.setValid(false);
\r
437 Graphics g = fHost.getGraphics();
\r
443 * Return debugging info.
\r
445 public String toString() {
\r
447 return "TabRuler{fLeadingMargin="+fLeadingMargin+
\r
448 "}{fFirstLineIndent="+fFirstLineIndent+
\r
449 "}{fFormatWidth="+fFormatWidth+
\r
450 "}{fTrailingMarginPosition="+fTrailingMarginPosition+
\r
451 "}{fRuler="+fRuler+
\r
456 * Return the MTabRuler represented by this TabRuler.
\r
457 * @return the MTabRuler represented by this TabRuler
\r
459 public MTabRuler getRuler()
\r
465 * Return the leading margin of this TabRuler.
\r
466 * @return the leading margin of this TabRuler
\r
468 public int getLeadingMargin()
\r
470 return fLeadingMargin;
\r
474 * Return the first line indent of this TabRuler.
\r
475 * @return the first line indent of this TabRuler
\r
477 public int getFirstLineIndent()
\r
479 return fFirstLineIndent - fLeadingMargin;
\r
483 * Return the trailing margin of this TabRuler.
\r
484 * @return the trailing margin of this TabRuler
\r
486 public final int getTrailingMargin()
\r
488 return fFormatWidth - fTrailingMarginPosition;
\r
491 private int visualToRulerPos(int visPos) {
\r
493 if (fLeftToRight) {
\r
494 return visPos - fOrigin;
\r
497 return fOrigin + fFormatWidth - visPos;
\r
501 private int rulerToVisualPos(int rulerPos) {
\r
503 if (fLeftToRight) {
\r
504 return fOrigin + rulerPos;
\r
507 return fOrigin + fFormatWidth - rulerPos;
\r
511 private int dirMult() {
\r
513 return fLeftToRight? 1 : -1;
\r
517 * @param tabPosition the logical (ruler) position of the tab
\r
519 private void drawTab(Graphics g, int tabPosition, byte tabType, int tabTop, int tabBottom)
\r
521 int pos = rulerToVisualPos(tabPosition);
\r
524 case TabStop.kLeading: wid = 3; break;
\r
525 case TabStop.kCenter: wid = 0; break;
\r
526 case TabStop.kTrailing: wid = -3; break;
\r
527 case TabStop.kDecimal: wid = 0; break;
\r
532 if (tabType != TabStop.kAuto) {
\r
533 g.drawLine(pos, tabTop, pos, tabBottom);
\r
535 g.drawLine(pos, tabBottom, pos + wid, tabBottom);
\r
537 g.drawLine(pos-2, tabTop+2, pos, tabTop);
\r
538 g.drawLine(pos, tabTop, pos+2, tabTop+2);
\r
539 if (tabType == TabStop.kDecimal) {
\r
540 g.drawLine(pos + 3, tabBottom, pos + 4, tabBottom);
\r
544 private void drawLM(Graphics g)
\r
546 int pos = rulerToVisualPos(fLeadingMargin);
\r
547 int[] xpts = { pos, pos, pos + (4*dirMult()), pos };
\r
548 int[] ypts = { fBaseline + 12, fBaseline + 7, fBaseline + 7, fBaseline + 12 };
\r
549 g.fillPolygon(xpts, ypts, 3);
\r
550 g.drawPolygon(xpts, ypts, 4);
\r
553 private void drawFLI(Graphics g)
\r
555 int pos = rulerToVisualPos(fFirstLineIndent);
\r
556 int[] xpts = { pos, pos, pos + (4*dirMult()), pos };
\r
557 int[] ypts = { fBaseline, fBaseline + 5, fBaseline + 5, fBaseline };
\r
558 g.fillPolygon(xpts, ypts, 3);
\r
559 g.drawPolygon(xpts, ypts, 4);
\r
562 private void drawRM(Graphics g)
\r
564 int pos = rulerToVisualPos(fTrailingMarginPosition);
\r
565 int[] xpts = { pos, pos, pos - (6*dirMult()), pos };
\r
566 int[] ypts = { fBaseline, fBaseline + 12, fBaseline + 6, fBaseline };
\r
567 g.fillPolygon(xpts, ypts, 3);
\r
568 g.drawPolygon(xpts, ypts, 4);
\r
571 private static int alignInt(int value) {
\r
573 return (int)((int)(value / 4.5) * 4.5);
\r
576 private static final int[] fgLengths = { 10, 2, 4, 2, 6, 2, 4, 2 };
\r
579 * Component method override.
\r
581 public void paint(Graphics g)
\r
583 Dimension size = fHost.getSize();
\r
585 int width = size.width;
\r
586 int baseline = fBaseline;
\r
587 int baseline2 = baseline + 2;
\r
588 int baseline10 = baseline + 10;
\r
589 int baseline12 = baseline + 12;
\r
591 if (!fImageCache.isValid()) {
\r
593 Graphics gCache = fImageCache.getGraphics(width, baseline12 + 1);
\r
594 if (gCache == null) {
\r
598 // set background color
\r
600 gCache.setColor(fBackColor);
\r
601 gCache.setPaintMode();
\r
602 gCache.fillRect(0, 0, width, baseline12 + 1);
\r
606 gCache.setColor(Color.black);
\r
607 gCache.drawLine(0, 0, width, 0);
\r
608 gCache.drawLine(0, baseline, width, baseline);
\r
610 int[] lengths = fgLengths;
\r
614 FontMetrics fm = null;
\r
615 if (!fLeftToRight) {
\r
616 fm = gCache.getFontMetrics();
\r
619 for (int i = 0; i < fFormatWidth; i += 9) {
\r
620 int len = lengths[index];
\r
621 int pos = rulerToVisualPos(i);
\r
622 gCache.drawLine(pos, baseline, pos, baseline - len);
\r
625 String str = Integer.toString(inchnum++);
\r
627 if (fLeftToRight) {
\r
631 drawX = pos - fm.stringWidth(str) - 2;
\r
634 gCache.drawString(str, drawX, baseline - 2);
\r
637 if (++index == lengths.length)
\r
642 TabStop tab = fRuler.firstTab();
\r
643 while (tab != null && tab.getPosition() < fTrailingMarginPosition) {
\r
644 boolean dodraw = true;
\r
645 if (tab.getType() == TabStop.kAuto) {
\r
646 if (tab.getPosition() <= Math.max(fLeadingMargin, fFirstLineIndent))
\r
648 else if (tab.getPosition() >= fTrailingMarginPosition)
\r
653 drawTab(gCache, tab.getPosition(), tab.getType(), baseline2, baseline10);
\r
655 tab = fRuler.nextTab(tab.getPosition());
\r
658 gCache.drawLine(0, baseline12, width, baseline12);
\r
660 // paint others except for tracked item
\r
661 if (fTrackItem != kTrackLM) drawLM(gCache);
\r
662 if (fTrackItem != kTrackTM) drawRM(gCache);
\r
663 if (fTrackItem != kTrackFLI && fTrackItem != kTrackLM) drawFLI(gCache);
\r
664 fImageCache.setValid(true);
\r
667 fImageCache.drawImage(g, 0, 0, Color.lightGray);
\r
669 switch (fTrackItem) {
\r
670 case kTrackTab: if (fTrackVisible) drawTab(g, fTrackTab.fPosition, fTrackTab.fType, baseline2, baseline10); break;
\r
671 case kTrackLM: drawLM(g); drawFLI(g); break;
\r
672 case kTrackTM: drawRM(g); break;
\r
673 case kTrackFLI: drawFLI(g); break;
\r
679 * MouseListener method.
\r
681 public void mouseClicked(MouseEvent e) {}
\r
683 * MouseListener method.
\r
685 public void mouseEntered(MouseEvent e) {}
\r
687 * MouseListener method.
\r
689 public void mouseExited(MouseEvent e) {}
\r
692 * MouseListener method.
\r
694 public void mousePressed(MouseEvent e)
\r
696 // find out if we hit a tabstop
\r
697 int x = visualToRulerPos(e.getX());
\r
700 if (y > fBaseline && y < fBaseline + 12) {
\r
701 if (y >= fBaseline + 7 && x >= fLeadingMargin - 3 && x <= fLeadingMargin + 3) {
\r
702 fTrackItem = kTrackLM;
\r
703 fTrackDelta = fLeadingMargin - x;
\r
704 } else if (y < fBaseline + 7 && x >= fFirstLineIndent - 3 && x <= fFirstLineIndent + 3) {
\r
705 fTrackItem = kTrackFLI;
\r
706 fTrackDelta = fFirstLineIndent - x;
\r
707 } else if (x >= fTrailingMarginPosition - 3 && x <= fTrailingMarginPosition + 3) {
\r
708 fTrackItem = kTrackTM;
\r
709 fTrackDelta = fTrailingMarginPosition - x;
\r
710 } else if (e.isControlDown()) {
\r
711 fTrackItem = kTrackTab;
\r
712 fTrackTab = new TabStopBuffer(alignInt(x), TabStop.kLeading);
\r
713 fTrackDelta = fTrackTab.fPosition - x;
\r
714 fTrackVisible = true;
\r
716 TabStop tab = fRuler.firstTab();
\r
717 while (tab.getType() != TabStop.kAuto) {
\r
718 if (x < tab.getPosition() - 3)
\r
720 if (x < tab.getPosition() + 3) {
\r
722 fTrackTab = new TabStopBuffer(tab);
\r
723 fRuler = fRuler.removeTab(fOldTab.getPosition());
\r
725 if (e.getClickCount() > 1) {
\r
726 switch (fTrackTab.fType) {
\r
727 case TabStop.kLeading: fTrackTab.fType = TabStop.kCenter; break;
\r
728 case TabStop.kCenter: fTrackTab.fType = TabStop.kTrailing; break;
\r
729 case TabStop.kTrailing: fTrackTab.fType = TabStop.kDecimal; break;
\r
730 case TabStop.kDecimal: fTrackTab.fType = TabStop.kLeading; break;
\r
734 fTrackItem = kTrackTab;
\r
735 fTrackDelta = tab.getPosition() - x;
\r
736 fTrackVisible = true;
\r
740 tab = fRuler.nextTab(tab.getPosition());
\r
744 if (fTrackItem != kTrackNone) {
\r
745 fImageCache.setValid(false);
\r
746 paint(fHost.getGraphics());
\r
753 * MouseListener method.
\r
755 public void mouseDragged(MouseEvent e)
\r
757 int x = visualToRulerPos(e.getX());
\r
760 if (fTrackItem != kTrackNone) {
\r
761 boolean repaint = false;
\r
762 boolean inrange = y > fBaseline && y < fBaseline + 12;
\r
763 boolean inbigrange = y > 0 && y < fHost.getSize().height + 20;
\r
764 int newpos = alignInt(x + fTrackDelta);
\r
768 switch (fTrackItem) {
\r
771 repaint = !fTrackVisible;
\r
772 fTrackVisible = true;
\r
773 if (newpos != fTrackTab.fPosition) {
\r
774 fTrackTab.fPosition = newpos;
\r
777 } else if (fTrackVisible) {
\r
778 fTrackVisible = false;
\r
783 /* It would be nice to optionally track the margin 'independently' of the first line indent.
\r
784 Unfortunately this makes for more work when we have multiple paragraph styles selected.
\r
785 Since internally the first line indent is relative to the margin, moving the margin
\r
786 independently so that all affected paragraphs share the same margin but retain first
\r
787 line indents in the 'same' positions means that I need to also adjust the first line
\r
788 indents in each paragraph by some delta. I'm not ready to do that yet. */
\r
791 if (inbigrange && newpos != fLeadingMargin) {
\r
792 fFirstLineIndent += newpos - fLeadingMargin;
\r
793 fLeadingMargin = newpos;
\r
799 if (inbigrange && newpos != fFirstLineIndent) {
\r
800 fFirstLineIndent = newpos;
\r
806 if (inbigrange && newpos != fTrailingMarginPosition) {
\r
807 fTrailingMarginPosition = newpos;
\r
815 paint(fHost.getGraphics());
\r
820 * MouseListener method.
\r
822 public void mouseReleased(MouseEvent e)
\r
824 if (fTrackItem != kTrackNone) {
\r
825 if (fTrackItem == kTrackTab && fTrackVisible) {
\r
826 fRuler = fRuler.addTab(fTrackTab.getTabStop());
\r
831 notify(fTrackItem);
\r
833 fTrackItem = kTrackNone;
\r
837 fImageCache.setValid(false);
\r
838 paint(fHost.getGraphics());
\r
843 * MouseListener method.
\r
845 public void mouseMoved(MouseEvent e) {}
\r
847 private void notify(int change)
\r
849 if (fTextPanel != null) {
\r
851 StyleModifier modifier;
\r
853 if (change == kTrackTab) {
\r
854 TabStop newTab = fTrackTab==null? null : fTrackTab.getTabStop();
\r
855 modifier = new TabRulerModifier(fOldTab, newTab, fTextPanel.getDefaultValues());
\r
863 key = TextAttribute.LEADING_MARGIN;
\r
864 value = new Float(getLeadingMargin());
\r
868 key = TextAttribute.TRAILING_MARGIN;
\r
869 value = new Float(getTrailingMargin());
\r
873 key = TextAttribute.FIRST_LINE_INDENT;
\r
874 value = new Float(getFirstLineIndent());
\r
878 throw new Error("Invalid change code.");
\r
881 modifier = StyleModifier.createAddModifier(key, value);
\r
884 fTextPanel.modifyParagraphStyleOnSelection(modifier);
\r
889 * Component override.
\r
891 public Dimension getMinimumSize()
\r
893 return new Dimension(100, fBaseline + 13);
\r
897 * Component override.
\r
899 public Dimension getPreferredSize()
\r
901 return getMinimumSize();
\r