1 19 20 package org.netbeans.editor; 21 22 import java.awt.Insets ; 23 import java.awt.Color ; 24 import java.awt.Font ; 25 import java.awt.font.FontRenderContext ; 26 import java.awt.Graphics ; 27 import java.awt.Shape ; 28 import java.awt.Rectangle ; 29 import javax.swing.text.Element ; 30 import javax.swing.text.View ; 31 import javax.swing.text.ViewFactory ; 32 import javax.swing.text.Position ; 33 import javax.swing.text.BadLocationException ; 34 import javax.swing.text.JTextComponent ; 35 import javax.swing.text.Document ; 36 import javax.swing.SwingUtilities ; 37 import javax.swing.event.DocumentEvent ; 38 39 81 82 public class LeafView extends BaseView { 83 84 87 protected int mainHeight; 88 89 90 ModelToViewDG modelToViewDG = new ModelToViewDG(); 91 92 93 ViewToModelDG viewToModelDG = new ViewToModelDG(); 94 95 96 public LeafView(Element elem) { 97 super(elem); 98 } 99 100 public void setParent(View parent) { 101 super.setParent(parent); 102 103 if (getParent() != null) { 104 updateMainHeight(); 105 } 106 } 107 108 109 protected int getPaintAreas(Graphics g, int clipY, int clipHeight) { 110 if (clipHeight <= 0) { 112 return 0; 113 } 114 115 int clipEndY = clipY + clipHeight; 116 int startY = getStartY(); 117 if (insets != null) { int mainAreaY = startY + insets.top; 119 if (clipEndY <= mainAreaY) { 120 return INSETS_TOP; 121 } 122 int bottomInsetsY = mainAreaY + mainHeight; 123 if (clipEndY <= bottomInsetsY) { 124 if (clipY <= mainAreaY) { 125 return INSETS_TOP + MAIN_AREA; 126 } else { 127 return MAIN_AREA; 128 } 129 } 130 if (clipY <= mainAreaY) { 131 return INSETS_TOP + MAIN_AREA + INSETS_BOTTOM; 132 } else if (clipY <= bottomInsetsY) { 133 return MAIN_AREA + INSETS_BOTTOM; 134 } else if (clipY <= bottomInsetsY + insets.bottom) { 135 return INSETS_BOTTOM; 136 } else { 137 return 0; 138 } 139 } else { if (clipEndY <= startY || clipY >= startY + getHeight()) { 141 return 0; 142 } else { 143 return MAIN_AREA; 144 } 145 } 146 } 147 148 149 protected void paintAreas(Graphics g, int clipY, int clipHeight, int paintAreas) { 150 if ((paintAreas & MAIN_AREA) == MAIN_AREA) { 151 EditorUI editorUI = getEditorUI(); 152 int paintY = Math.max(clipY, 0); int startPos = getPosFromY(paintY); 154 if (clipHeight > 0) { BaseDocument doc = (BaseDocument)getDocument(); 156 try { 157 int pos = getPosFromY(clipY + clipHeight - 1); 158 int endPos = Utilities.getRowEnd(doc, pos); 159 int baseY = getYFromPos(startPos); 160 DrawEngine.getDrawEngine().draw(new DrawGraphics.GraphicsDG(g), 161 editorUI, startPos, endPos, 162 getBaseX(baseY), baseY, Integer.MAX_VALUE 163 ); 164 } catch (BadLocationException e) { 165 e.printStackTrace(); 166 } 167 } 168 } 169 } 170 171 172 public int getHeight() { 173 if (insets != null) { 174 return insets.top + mainHeight + insets.bottom; 175 } else { 176 return mainHeight; 177 } 178 } 179 180 181 public void updateMainHeight() { 182 LeafElement elem = (LeafElement)getElement(); try { 184 int lineDiff = (elem.getEndMark().getLine() - elem.getStartMark().getLine() 185 + 1); 186 mainHeight = lineDiff * getEditorUI().getLineHeight(); 187 } catch (InvalidMarkException e) { 188 Utilities.annotateLoggable(e); 189 mainHeight = 0; 190 } 191 } 192 193 202 protected int getPosFromY(int y) { 203 int relY = y - getStartY() - ((insets != null) ? insets.top : 0); 205 if (relY < 0) { return getStartOffset(); 207 } 208 if (relY >= mainHeight) { return getEndOffset(); 210 } 211 212 int line = 0; 213 try { 215 line = ((BaseElement)getElement()).getStartMark().getLine(); 216 } catch (InvalidMarkException e) { 217 Utilities.annotateLoggable(e); 218 } 219 line += relY / getEditorUI().getLineHeight(); 221 222 int startOffset = getStartOffset(); 223 int pos; 224 pos = Utilities.getRowStartFromLineOffset(((BaseDocument)getDocument()), line); 225 if (pos == -1) { 226 pos = startOffset; 227 } 228 return Math.max(pos, startOffset); 229 } 230 231 public int getBaseX(int y) { 232 return getEditorUI().getTextMargin().left + ((insets != null) ? insets.left : 0); 233 } 234 235 236 public final int getViewCount() { 237 return 0; 238 } 239 240 241 public final View getView(int n) { 242 return null; 243 } 244 245 246 public int getNextVisualPositionFrom(int pos, Position.Bias b, Shape a, 247 int direction, Position.Bias [] biasRet) 248 throws BadLocationException { 249 if (biasRet != null) { 250 biasRet[0] = Position.Bias.Forward; 251 } 252 switch (direction) { 253 case NORTH: 254 { 255 try { 256 BaseDocument doc = (BaseDocument)getDocument(); 257 int visCol = doc.getVisColFromPos(pos); 258 pos = doc.getOffsetFromVisCol(visCol, Utilities.getRowStart(doc, pos, -1)); 259 } catch (BadLocationException e) { 260 } 262 return pos; 263 } 264 case SOUTH: 265 { 266 try { 267 BaseDocument doc = (BaseDocument)getDocument(); 268 int visCol = doc.getVisColFromPos(pos); 269 pos = doc.getOffsetFromVisCol(visCol, Utilities.getRowStart(doc, pos, 1)); 270 } catch (BadLocationException e) { 271 } 273 return pos; 274 } 275 case WEST: 276 return (pos == -1) ? getStartOffset() : (pos - 1); 277 case EAST: 278 return (pos == -1) ? getEndOffset() : (pos + 1); 279 default: 280 throw new IllegalArgumentException ("Bad direction: " + direction); } 282 } 283 284 287 protected int getYFromPos(int pos) throws BadLocationException { 288 int relLine = 0; 289 try { 290 relLine = Utilities.getLineOffset(((BaseDocument)getDocument()), pos) 291 - ((BaseElement)getElement()).getStartMark().getLine(); 292 } catch (InvalidMarkException e) { 293 Utilities.annotateLoggable(e); 294 } 295 return getStartY() + ((insets != null) ? insets.top : 0) 296 + relLine * getEditorUI().getLineHeight(); 297 } 298 299 public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException { 300 EditorUI editorUI = getEditorUI(); 301 Rectangle ret = new Rectangle (); 302 BaseDocument doc = (BaseDocument)getDocument(); 303 if (pos < 0 || pos > doc.getLength()) { 304 throw new BadLocationException ("Invalid offset", pos); } 306 307 ret.y = getYFromPos(pos); 308 309 try { 310 synchronized (modelToViewDG) { 311 modelToViewDG.r = ret; 313 Element lineElement = doc.getParagraphElement(pos); 314 int bolPos = lineElement.getStartOffset(); 315 int eolPos = lineElement.getEndOffset() - 1; 316 DrawEngine.getDrawEngine().draw(modelToViewDG, editorUI, 317 bolPos, eolPos, 318 getBaseX(ret.y), ret.y, pos 319 ); 320 modelToViewDG.r = null; 321 } 322 } catch (BadLocationException e) { 323 Utilities.annotateLoggable(e); 324 } 325 326 return ret; 327 } 328 329 public Shape modelToView(int p0, Position.Bias b0, int p1, Position.Bias b1, 330 Shape a) throws BadLocationException { 331 Rectangle r0 = (Rectangle )modelToView(p0, a, b0); 332 Rectangle r1 = (Rectangle )modelToView(p1, a, b1); 333 if (r0.y != r1.y) { 334 r0.x = getComponent().getX(); 336 r0.width = getComponent().getWidth(); 337 } 338 r0.add(r1); 339 return r0; 340 } 341 342 public void modelToViewDG(int pos, DrawGraphics dg) 343 throws BadLocationException { 344 EditorUI editorUI = getEditorUI(); 345 BaseDocument doc = (BaseDocument)getDocument(); 346 if (pos < 0 || pos > doc.getLength()) { 347 throw new BadLocationException ("Invalid offset", pos); } 349 350 int y = getYFromPos(pos); 351 Element lineElement = doc.getParagraphElement(pos); 352 DrawEngine.getDrawEngine().draw(dg, editorUI, lineElement.getStartOffset(), 353 lineElement.getEndOffset() - 1, getBaseX(y), y, pos); 354 } 355 356 363 public int viewToModel(float x, float y, Shape a, Position.Bias [] biasReturn) { 364 int intX = (int)x; 365 int intY = (int)y; 366 if (biasReturn != null) { 367 biasReturn[0] = Position.Bias.Forward; 368 } 369 int begMainY = getStartY() + ((insets != null) ? insets.top : 0); 370 if (intY < begMainY) { return -1; } else if (intY > begMainY + mainHeight) { return getEndOffset(); 374 } else { int pos = getPosFromY(intY); EditorUI editorUI = getEditorUI(); 377 try { 378 int eolPos = Utilities.getRowEnd((BaseDocument)getDocument(), pos); 379 synchronized (viewToModelDG) { 380 viewToModelDG.setTargetX(intX); 381 viewToModelDG.setEOLOffset(eolPos); 382 DrawEngine.getDrawEngine().draw(viewToModelDG, editorUI, pos, eolPos, 383 getBaseX(intY), 0, -1); 384 pos = viewToModelDG.getOffset(); 385 } 386 } catch (BadLocationException e) { 387 } 389 return pos; 390 } 391 } 392 393 400 public void insertUpdate(DocumentEvent evt, Shape a, ViewFactory f) { 401 try { 402 BaseDocumentEvent bevt = (BaseDocumentEvent)evt; 403 EditorUI editorUI = getEditorUI(); 404 int y = getYFromPos(evt.getOffset()); 405 int lineHeight = editorUI.getLineHeight(); 406 if (bevt.getLFCount() > 0) { int addHeight = bevt.getLFCount() * lineHeight; 408 mainHeight += addHeight; 409 editorUI.repaint(y); 410 411 } else { 413 int syntaxY = getYFromPos(bevt.getSyntaxUpdateOffset()); 414 if (bevt.getSyntaxUpdateOffset() == evt.getDocument().getLength()) { 416 syntaxY += lineHeight; 417 } 418 419 if (getComponent().isShowing()) { 420 editorUI.repaint(y, Math.max(lineHeight, syntaxY - y)); 421 } 422 } 423 424 } catch (BadLocationException ex) { 425 Utilities.annotateLoggable(ex); 426 } 427 } 428 429 436 public void removeUpdate(DocumentEvent evt, Shape a, ViewFactory f) { 437 try { 438 BaseDocumentEvent bevt = (BaseDocumentEvent)evt; 439 EditorUI editorUI = getEditorUI(); 440 int y = getYFromPos(evt.getOffset()); 441 int lineHeight = editorUI.getLineHeight(); 442 if (bevt.getLFCount() > 0) { int removeHeight = bevt.getLFCount() * lineHeight; 444 mainHeight -= removeHeight; 445 editorUI.repaint(y); 446 447 } else { int syntaxY = getYFromPos(bevt.getSyntaxUpdateOffset()); 449 if (bevt.getSyntaxUpdateOffset() == evt.getDocument().getLength()) { 451 syntaxY += lineHeight; 452 } 453 454 if (getComponent().isShowing()) { 455 editorUI.repaint(y, Math.max(lineHeight, syntaxY - y)); 456 } 457 } 458 459 } catch (BadLocationException ex) { 460 Utilities.annotateLoggable(ex); 461 } 462 } 463 464 469 public void changedUpdate(DocumentEvent evt, Shape a, ViewFactory f) { 470 try { 471 if (getComponent().isShowing()) { 472 getEditorUI().repaintBlock(evt.getOffset(), evt.getOffset() + evt.getLength()); 473 } 474 } catch (BadLocationException ex) { 475 Utilities.annotateLoggable(ex); 476 } 477 } 478 479 480 protected int getViewStartY(BaseView view, int helperInd) { 481 return 0; } 483 484 static final class ModelToViewDG extends DrawGraphics.SimpleDG { 485 486 Rectangle r; 487 488 public boolean targetOffsetReached(int pos, char ch, int x, 489 int charWidth, DrawContext ctx) { 490 r.x = x; 491 r.y = getY(); 492 r.width = charWidth; 493 r.height = getLineHeight(); 494 return false; 495 } 496 497 } 498 499 static final class ViewToModelDG extends DrawGraphics.SimpleDG { 500 501 int targetX; 502 503 int offset; 504 505 int eolOffset; 506 507 void setTargetX(int targetX) { 508 this.targetX = targetX; 509 } 510 511 void setEOLOffset(int eolOffset) { 512 this.eolOffset = eolOffset; 513 this.offset = eolOffset; 514 } 515 516 int getOffset() { 517 return offset; 518 } 519 520 public boolean targetOffsetReached(int offset, char ch, int x, 521 int charWidth, DrawContext ctx) { 522 if (offset <= eolOffset) { 523 if (x + charWidth < targetX) { 524 this.offset = offset; 525 return true; 526 527 } else { this.offset = offset; 529 if (targetX > x + charWidth / 2) { 530 Document doc = ctx.getEditorUI().getDocument(); 531 if (ch != '\n' && doc != null && offset < doc.getLength()) { 532 this.offset++; 533 } 534 } 535 536 return false; 537 } 538 } 539 return false; 540 } 541 542 } 543 544 } 545 | Popular Tags |