1 19 20 package org.netbeans.editor; 21 22 import java.awt.Color ; 23 import java.awt.Container ; 24 import java.awt.Font ; 25 import java.awt.FontMetrics ; 26 import java.awt.Graphics ; 27 import java.awt.Point ; 28 import java.awt.Rectangle ; 29 import java.awt.Shape ; 30 import javax.swing.JComponent ; 31 import javax.swing.event.DocumentEvent ; 32 import javax.swing.text.AttributeSet ; 33 import javax.swing.text.BadLocationException ; 34 import javax.swing.text.Caret ; 35 import javax.swing.text.Document ; 36 import javax.swing.text.Element ; 37 import javax.swing.text.JTextComponent ; 38 import javax.swing.text.Position ; 39 import javax.swing.text.View ; 40 import javax.swing.text.ViewFactory ; 41 import org.netbeans.editor.ext.ExtEditorUI; 42 import org.netbeans.editor.ext.ToolTipSupport; 43 import org.netbeans.editor.view.spi.LockView; 44 45 52 class CollapsedView extends View implements SettingsChangeListener { 53 54 private Position startPos; 55 56 private Position endPos; 57 58 private String foldDescription; 59 60 private Font font; 61 62 private Color foreColor; 63 64 private Color backColor; 65 66 67 68 public CollapsedView(Element elem, Position startPos, Position endPos, String foldDescription) { 69 super(elem); 70 71 this.startPos = startPos; 72 this.endPos = endPos; 73 this.foldDescription = foldDescription; 74 Settings.addSettingsChangeListener(this); 75 } 76 77 private JTextComponent getComponent() { 78 return (JTextComponent )getContainer(); 79 } 80 81 private BaseTextUI getBaseTextUI(){ 82 JTextComponent comp = getComponent(); 83 return (comp!=null)?(BaseTextUI)comp.getUI():null; 84 } 85 86 private EditorUI getEditorUI(){ 87 BaseTextUI btui = getBaseTextUI(); 88 return (btui!=null) ? btui.getEditorUI() : null; 89 } 90 91 public void insertUpdate(DocumentEvent e, Shape a, ViewFactory f) { 92 } 93 94 public void removeUpdate(DocumentEvent e, Shape a, ViewFactory f) { 95 } 96 97 public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f) { 98 } 99 100 public Document getDocument() { 101 View parent = getParent(); 102 return (parent == null) ? null : parent.getDocument(); 103 } 104 105 public int getStartOffset() { 106 return startPos.getOffset(); 107 } 108 109 public int getEndOffset() { 110 return endPos.getOffset(); 111 } 112 113 protected void forwardUpdate(DocumentEvent.ElementChange ec, 114 DocumentEvent e, Shape a, ViewFactory f) { 115 } 116 117 protected void forwardUpdateToView(View v, DocumentEvent e, 118 Shape a, ViewFactory f) { 119 } 120 121 public float getAlignment(int axis) { 122 return 0f; 123 } 124 125 public float getPreferredSpan(int axis){ 126 switch (axis) { 127 case Y_AXIS: 128 return getEditorUI().getLineHeight(); 129 case X_AXIS: 130 return getCollapsedFoldStringWidth(); 131 } 132 return 1f; 133 } 134 135 136 private int getCollapsedFoldStringWidth() { 137 JTextComponent comp = getComponent(); 138 if (comp==null) return 0; 139 FontMetrics fm = FontMetricsCache.getFontMetrics(getColoringFont(), comp); 140 if (fm==null) return 0; 141 return fm.stringWidth(foldDescription); 142 } 143 144 public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException { 145 return new Rectangle (a.getBounds().x, a.getBounds().y, getCollapsedFoldStringWidth(), getEditorUI().getLineHeight()); 146 } 147 148 public int viewToModel(float x, float y, Shape a, Position.Bias [] biasReturn) { 149 return getStartOffset(); 150 } 151 152 public void paint(Graphics g, Shape allocation){ 153 Rectangle allocRect = allocation.getBounds(); 154 g.setColor(getBackColor()); 155 int x = allocRect.x+2; 156 int y = allocRect.y; 157 int width = allocRect.width-1; 158 int height = allocRect.height-1; 159 g.fillRect(x, y, width, height); 160 g.setColor(getForeColor()); 161 g.setFont(getColoringFont()); 162 g.drawRect(x, y, width, height); 163 g.drawString(foldDescription, x, y + getEditorUI().getLineAscent()-1); 164 } 165 166 public int getNextVisualPositionFrom(int pos, Position.Bias b, Shape a, 167 int direction, Position.Bias [] biasRet) 168 throws BadLocationException { 169 biasRet[0] = Position.Bias.Forward; 170 switch (direction) { 171 case NORTH: 172 case SOUTH: 173 { 174 JTextComponent target = (JTextComponent ) getContainer(); 175 Caret c = (target != null) ? target.getCaret() : null; 176 Point mcp; 179 if (c != null) { 180 mcp = c.getMagicCaretPosition(); 181 } 182 else { 183 mcp = null; 184 } 185 int x; 186 if (mcp == null) { 187 Rectangle loc = target.modelToView(pos); 188 x = (loc == null) ? 0 : loc.x; 189 } 190 else { 191 x = mcp.x; 192 } 193 if (direction == NORTH) { 194 pos = Utilities.getPositionAbove(target, pos, x); 195 } 196 else { 197 pos = Utilities.getPositionBelow(target, pos, x); 198 } 199 } 200 break; 201 case WEST: 202 if(pos == -1) { 203 pos = Math.max(0, getStartOffset()); 204 } 205 else { 206 if (b == Position.Bias.Backward){ 207 pos = Math.max(0, getStartOffset()); 208 }else{ 209 pos = Math.max(0, getStartOffset() - 1); 210 } 211 } 212 break; 213 case EAST: 214 if(pos == -1) { 215 pos = getStartOffset(); 216 } 217 else { 218 pos = Math.min(getEndOffset(), getDocument().getLength()); 219 } 222 break; 223 default: 224 throw new IllegalArgumentException ("Bad direction: " + direction); } 226 return pos; 227 } 228 229 private View getExpandedView(){ 230 Element parentElem = getElement().getParentElement(); 231 int sei = parentElem.getElementIndex(getStartOffset()); 232 int so = parentElem.getElement(sei).getStartOffset(); 233 234 int eei = parentElem.getElementIndex(getEndOffset()); 235 int eo = parentElem.getElement(eei).getEndOffset(); 236 237 LockView fakeView = new LockView( 238 new DrawEngineFakeDocView(parentElem, so, eo, false) 239 ); 240 RootView rootView = new RootView(); 241 rootView.setView(fakeView); 242 return fakeView; 243 } 244 245 public String getToolTipText(float x, float y, Shape allocation){ 246 ToolTipSupport tts = ((ExtEditorUI)getEditorUI()).getToolTipSupport(); 247 JComponent toolTip = new FoldingToolTip(getExpandedView(), getEditorUI()); 248 tts.setToolTip(toolTip, PopupManager.ScrollBarBounds, PopupManager.Largest, -FoldingToolTip.BORDER_WIDTH, 0); 249 return ""; 250 } 251 252 public void settingsChange(SettingsChangeEvent evt) { 253 if (evt == null || org.netbeans.editor.Utilities.getKitClass(getComponent()) != evt.getKitClass()) return; 254 255 String defaultColoringName = SettingsNames.DEFAULT_COLORING+SettingsNames.COLORING_NAME_SUFFIX; 256 String foldingColoringName = SettingsNames.CODE_FOLDING_COLORING+SettingsNames.COLORING_NAME_SUFFIX; 257 EditorUI editorUI = getEditorUI(); 258 if (editorUI==null) return; 259 Coloring foldingColoring = editorUI.getColoring(SettingsNames.CODE_FOLDING_COLORING); 260 Coloring defaultColoring = editorUI.getDefaultColoring(); 261 262 Font foldingFont = null; 263 Color foldingForeColor = null; 264 Color foldingBackColor = null; 265 if (foldingColoring!=null){ 266 foldingFont = foldingColoring.getFont(); 267 foldingForeColor = foldingColoring.getForeColor(); 268 foldingBackColor = foldingColoring.getBackColor(); 269 } 270 271 if (defaultColoringName.equals(evt.getSettingName())){ 272 273 if (foldingForeColor == null){ 274 Color tempColor = getDefaultForeColor(); 276 if (!tempColor.equals(foreColor)){ 277 foreColor = tempColor; 278 } 279 } 280 281 if (foldingBackColor == null){ 282 Color tempColor = getDefaultBackColor(); 284 if (!tempColor.equals(backColor)){ 285 backColor = tempColor; 286 } 287 } 288 289 Font tempFont = getDefaultColoringFont(); 291 if (!tempFont.equals(font) && foldingFont==null){ 292 font = tempFont; 294 } 296 298 }else if (foldingColoringName.equals(evt.getSettingName())){ 299 if (foldingColoring == null) return; 301 302 Color tempColor = foldingColoring.getForeColor(); 303 foreColor = (tempColor!=null) ? tempColor : getDefaultForeColor(); 304 305 tempColor = foldingColoring.getBackColor(); 306 backColor = (tempColor!=null) ? tempColor : getDefaultBackColor(); 307 308 if (foldingFont == null){ Font tempFont = getDefaultColoringFont(); 310 if (!tempFont.equals(font)){ 311 font = tempFont; 312 } 314 }else{ 315 if (!foldingFont.equals(font)){ 316 font = foldingFont; 317 } 319 } 320 321 } 323 } 324 325 private Font getDefaultColoringFont(){ 326 EditorUI editorUI = getEditorUI(); 328 if (editorUI!=null){ 329 Coloring defaultColoring = editorUI.getDefaultColoring(); 330 if (defaultColoring!=null){ 331 if (defaultColoring.getFont() != null){ 332 return defaultColoring.getFont(); 333 } 334 } 335 } 336 return SettingsDefaults.defaultFont; 337 } 338 339 protected Font getColoringFont(){ 340 if (font != null) return font; 341 EditorUI editorUI = getEditorUI(); 342 if (editorUI!=null){ 343 Coloring foldColoring = editorUI.getColoring(SettingsNames.CODE_FOLDING_COLORING); 344 if (foldColoring != null){ 345 if (foldColoring.getFont()!=null){ 346 font = foldColoring.getFont(); 347 return font; 348 } 349 } 350 } 351 font = getDefaultColoringFont(); 352 return font; 353 } 354 355 protected Color getForeColor(){ 356 if (foreColor != null) return foreColor; 357 EditorUI editorUI = getEditorUI(); 358 if (editorUI!=null){ 359 Coloring foldColoring = editorUI.getColoring(SettingsNames.CODE_FOLDING_COLORING); 360 if (foldColoring != null && foldColoring.getForeColor()!=null){ 361 foreColor = foldColoring.getForeColor(); 362 return foreColor; 363 } 364 } 365 foreColor = getDefaultForeColor(); 366 return foreColor; 367 } 368 369 private Color getDefaultForeColor(){ 370 EditorUI editorUI = getEditorUI(); 371 if (editorUI!=null){ 372 Coloring defaultColoring = editorUI.getDefaultColoring(); 374 if (defaultColoring!=null && defaultColoring.getForeColor()!=null){ 375 return defaultColoring.getForeColor(); 376 } 377 } 378 return SettingsDefaults.defaultForeColor; 379 } 380 381 private Color getDefaultBackColor(){ 382 EditorUI editorUI = getEditorUI(); 383 if (editorUI!=null){ 384 Coloring defaultColoring = editorUI.getDefaultColoring(); 386 if (defaultColoring!=null){ 387 return defaultColoring.getBackColor(); 388 } 389 } 390 return SettingsDefaults.defaultBackColor; 391 } 392 393 protected Color getBackColor(){ 394 if (backColor != null) return backColor; 395 EditorUI editorUI = getEditorUI(); 396 if (editorUI!=null){ 397 Coloring foldColoring = editorUI.getColoring(SettingsNames.CODE_FOLDING_COLORING); 398 if (foldColoring != null && foldColoring.getBackColor()!=null){ 399 backColor = foldColoring.getBackColor(); 400 return backColor; 401 } 402 } 403 backColor = getDefaultBackColor(); 404 return backColor; 405 } 406 407 408 class RootView extends View { 409 410 RootView() { 411 super(null); 412 } 413 414 void setView(View v) { 415 if (view != null) { 416 view.setParent(null); 419 } 420 view = v; 421 if (view != null) { 422 view.setParent(this); 423 } 424 } 425 426 431 public AttributeSet getAttributes() { 432 return null; 433 } 434 435 444 public float getPreferredSpan(int axis) { 445 if (view != null) { 446 return view.getPreferredSpan(axis); 447 } 448 return 10; 449 } 450 451 460 public float getMinimumSpan(int axis) { 461 if (view != null) { 462 return view.getMinimumSpan(axis); 463 } 464 return 10; 465 } 466 467 476 public float getMaximumSpan(int axis) { 477 return Integer.MAX_VALUE; 478 } 479 480 498 public void preferenceChanged(View child, boolean width, boolean height) { 499 500 } 501 502 509 public float getAlignment(int axis) { 510 if (view != null) { 511 return view.getAlignment(axis); 512 } 513 return 0; 514 } 515 516 522 public void paint(Graphics g, Shape allocation) { 523 if (view != null) { 524 Rectangle alloc = (allocation instanceof Rectangle ) ? 525 (Rectangle )allocation : allocation.getBounds(); 526 setSize(alloc.width, alloc.height); 527 view.paint(g, allocation); 528 } 529 } 530 531 536 public void setParent(View parent) { 537 throw new Error ("Can't set parent on root view"); } 539 540 548 public int getViewCount() { 549 return 1; 550 } 551 552 558 public View getView(int n) { 559 return view; 560 } 561 562 572 public int getViewIndex(int pos, Position.Bias b) { 573 return 0; 574 } 575 576 588 public Shape getChildAllocation(int index, Shape a) { 589 return a; 590 } 591 592 600 public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException { 601 if (view != null) { 602 return view.modelToView(pos, a, b); 603 } 604 return null; 605 } 606 607 626 public Shape modelToView(int p0, Position.Bias b0, int p1, Position.Bias b1, Shape a) throws BadLocationException { 627 if (view != null) { 628 return view.modelToView(p0, b0, p1, b1, a); 629 } 630 return null; 631 } 632 633 643 public int viewToModel(float x, float y, Shape a, Position.Bias [] bias) { 644 if (view != null) { 645 int retValue = view.viewToModel(x, y, a, bias); 646 return retValue; 647 } 648 return -1; 649 } 650 651 668 public int getNextVisualPositionFrom(int pos, Position.Bias b, Shape a, 669 int direction, 670 Position.Bias [] biasRet) 671 throws BadLocationException { 672 if( view != null ) { 673 int nextPos = view.getNextVisualPositionFrom(pos, b, a, 674 direction, biasRet); 675 if(nextPos != -1) { 676 pos = nextPos; 677 } 678 else { 679 biasRet[0] = b; 680 } 681 } 682 return pos; 683 } 684 685 693 public void insertUpdate(DocumentEvent e, Shape a, ViewFactory f) { 694 if (view != null) { 695 view.insertUpdate(e, a, f); 696 } 697 } 698 699 707 public void removeUpdate(DocumentEvent e, Shape a, ViewFactory f) { 708 if (view != null) { 709 view.removeUpdate(e, a, f); 710 } 711 } 712 713 721 public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f) { 722 if (view != null) { 723 view.changedUpdate(e, a, f); 724 } 725 } 726 727 732 public Document getDocument() { 733 EditorUI editorUI = getEditorUI(); 734 return (editorUI==null) ? null : editorUI.getDocument(); 735 } 736 737 742 public int getStartOffset() { 743 if (view != null) { 744 return view.getStartOffset(); 745 } 746 return getElement().getStartOffset(); 747 } 748 749 754 public int getEndOffset() { 755 if (view != null) { 756 return view.getEndOffset(); 757 } 758 return getElement().getEndOffset(); 759 } 760 761 766 public Element getElement() { 767 if (view != null) { 768 return view.getElement(); 769 } 770 return view.getDocument().getDefaultRootElement(); 771 } 772 773 782 public View breakView(int axis, float len, Shape a) { 783 throw new Error ("Can't break root view"); } 785 786 793 public int getResizeWeight(int axis) { 794 if (view != null) { 795 return view.getResizeWeight(axis); 796 } 797 return 0; 798 } 799 800 806 public void setSize(float width, float height) { 807 if (view != null) { 808 view.setSize(width, height); 809 } 810 } 811 812 820 public Container getContainer() { 821 EditorUI editorUI = getEditorUI(); 822 return (editorUI==null) ? null : editorUI.getComponent(); 823 } 824 825 838 public ViewFactory getViewFactory() { 839 EditorUI editorUI = getEditorUI(); 840 if (editorUI!=null){ 841 BaseKit kit = Utilities.getKit(editorUI.getComponent()); 842 843 ViewFactory f = kit.getViewFactory(); 844 if (f != null) { 845 return f; 846 } 847 } 848 return getBaseTextUI(); 849 } 850 851 private View view; 852 853 } 854 855 856 } 857 | Popular Tags |