1 22 package org.gjt.sp.jedit.textarea; 23 24 import org.gjt.sp.jedit.OperatingSystem; 25 import org.gjt.sp.jedit.TextUtilities; 26 import org.gjt.sp.util.StandardUtilities; 27 28 import javax.swing.event.MouseInputAdapter ; 29 import java.awt.event.MouseEvent ; 30 import java.awt.*; 31 32 36 public class TextAreaMouseHandler extends MouseInputAdapter 37 { 38 TextAreaMouseHandler(TextArea textArea) 40 { 41 this.textArea = textArea; 42 } 44 public void mousePressed(MouseEvent evt) 46 { 47 showCursor(); 48 49 control = (OperatingSystem.isMacOS() && evt.isMetaDown()) 50 || (!OperatingSystem.isMacOS() && evt.isControlDown()); 51 52 textArea.getInputHandler().resetLastActionCount(); 55 56 quickCopyDrag = (textArea.isQuickCopyEnabled() && 57 isMiddleButton(evt.getModifiers())); 58 59 if(!quickCopyDrag) 60 { 61 textArea.requestFocus(); 62 TextArea.focusedComponent = textArea; 63 } 64 65 if(textArea.getBuffer().isLoading()) 66 return; 67 68 int x = evt.getX(); 69 int y = evt.getY(); 70 71 dragStart = textArea.xyToOffset(x,y, 72 !(textArea.getPainter().isBlockCaretEnabled() 73 || textArea.isOverwriteEnabled())); 74 dragStartLine = textArea.getLineOfOffset(dragStart); 75 dragStartOffset = dragStart - textArea.getLineStartOffset( 76 dragStartLine); 77 78 79 dragged = false; 80 81 textArea.blink = true; 82 textArea.invalidateLine(textArea.getCaretLine()); 83 84 clickCount = evt.getClickCount(); 85 86 if(textArea.isDragEnabled() 87 && textArea.selectionManager.insideSelection(x,y) 88 && clickCount == 1 && !evt.isShiftDown()) 89 { 90 maybeDragAndDrop = true; 91 textArea.moveCaretPosition(dragStart,false); 92 return; 93 } 94 else 95 maybeDragAndDrop = false; 96 97 if(quickCopyDrag) 98 { 99 doSingleClick(evt); 101 } 102 else 103 { 104 switch(clickCount) 105 { 106 case 1: 107 doSingleClick(evt); 108 break; 109 case 2: 110 doDoubleClick(); 111 break; 112 default: doTripleClick(); 114 break; 115 } 116 } 117 } 119 protected void doSingleClick(MouseEvent evt) 121 { 122 int x = evt.getX(); 123 124 int extraEndVirt = 0; 125 if(textArea.chunkCache.getLineInfo( 126 textArea.getLastScreenLine()).lastSubregion) 127 { 128 int dragStart = textArea.xyToOffset(x,evt.getY(), 129 !textArea.getPainter().isBlockCaretEnabled() 130 && !textArea.isOverwriteEnabled()); 131 int screenLine = textArea.getScreenLineOfOffset(dragStart); 132 ChunkCache.LineInfo lineInfo = textArea.chunkCache.getLineInfo(screenLine); 133 int offset = textArea.getScreenLineEndOffset(screenLine); 134 if ((1 != offset - dragStart) || (lineInfo.lastSubregion)) 135 { 136 offset--; 137 } 138 float dragStartLineWidth = textArea.offsetToXY(offset).x; 139 if(x > dragStartLineWidth) 140 { 141 extraEndVirt = (int)( 142 (x - dragStartLineWidth) 143 / textArea.charWidth); 144 if(!textArea.getPainter().isBlockCaretEnabled() 145 && !textArea.isOverwriteEnabled() 146 && (x - textArea.getHorizontalOffset()) 147 % textArea.charWidth > textArea.charWidth / 2) 148 { 149 extraEndVirt++; 150 } 151 } 152 } 153 154 if((control || textArea.isRectangularSelectionEnabled()) 155 && textArea.isEditable()) 156 { 157 int screenLine = (evt.getY() / textArea.getPainter() 158 .getFontMetrics().getHeight()); 159 if(screenLine > textArea.getLastScreenLine()) 160 screenLine = textArea.getLastScreenLine(); 161 ChunkCache.LineInfo info = textArea.chunkCache.getLineInfo(screenLine); 162 if(info.lastSubregion && extraEndVirt != 0) 163 { 164 String whitespace = StandardUtilities 167 .createWhiteSpace(extraEndVirt,0); 168 textArea.getBuffer().insert(dragStart,whitespace); 169 170 dragStart += whitespace.length(); 171 } 172 } 173 174 if(evt.isShiftDown()) 175 { 176 textArea.resizeSelection( 178 textArea.getMarkPosition(),dragStart,extraEndVirt, 179 textArea.isRectangularSelectionEnabled() 180 || control); 181 182 if(!quickCopyDrag) 183 textArea.moveCaretPosition(dragStart,false); 184 185 dragStartLine = textArea.getMarkLine(); 187 dragStart = textArea.getMarkPosition(); 188 dragStartOffset = dragStart 189 - textArea.getLineStartOffset(dragStartLine); 190 191 dragged = true; 193 194 return; 195 } 196 197 if(!quickCopyDrag) 198 textArea.moveCaretPosition(dragStart,false); 199 200 if(!(textArea.isMultipleSelectionEnabled() 201 || quickCopyDrag)) 202 textArea.selectNone(); 203 } 205 protected void doDoubleClick() 207 { 208 if(textArea.getLineLength(dragStartLine) == 0) 210 return; 211 212 String lineText = textArea.getLineText(dragStartLine); 213 String noWordSep = textArea.getBuffer() 214 .getStringProperty("noWordSep"); 215 if(dragStartOffset == textArea.getLineLength(dragStartLine)) 216 dragStartOffset--; 217 218 boolean joinNonWordChars = textArea.getJoinNonWordChars(); 219 int wordStart = TextUtilities.findWordStart(lineText,dragStartOffset, 220 noWordSep,textArea.getJoinNonWordChars()); 221 int wordEnd = TextUtilities.findWordEnd(lineText, 222 dragStartOffset+1,noWordSep, 223 textArea.getJoinNonWordChars()); 224 225 int lineStart = textArea.getLineStartOffset(dragStartLine); 226 Selection sel = new Selection.Range( 227 lineStart + wordStart, 228 lineStart + wordEnd); 229 if(textArea.isMultipleSelectionEnabled()) 230 textArea.addToSelection(sel); 231 else 232 textArea.setSelection(sel); 233 234 if(quickCopyDrag) 235 quickCopyDrag = false; 236 237 textArea.moveCaretPosition(lineStart + wordEnd,false); 238 239 dragged = true; 240 } 242 protected void doTripleClick() 244 { 245 int newCaret = textArea.getLineEndOffset(dragStartLine); 246 if(dragStartLine == textArea.getLineCount() - 1) 247 newCaret--; 248 249 Selection sel = new Selection.Range( 250 textArea.getLineStartOffset(dragStartLine), 251 newCaret); 252 if(textArea.isMultipleSelectionEnabled()) 253 textArea.addToSelection(sel); 254 else 255 textArea.setSelection(sel); 256 257 if(quickCopyDrag) 258 quickCopyDrag = false; 259 260 textArea.moveCaretPosition(newCaret,false); 261 262 dragged = true; 263 } 265 public void mouseMoved(MouseEvent evt) 267 { 268 showCursor(); 269 } 271 public void mouseDragged(MouseEvent evt) 273 { 274 if(maybeDragAndDrop) 275 { 276 textArea.startDragAndDrop(evt,control); 277 return; 278 } 279 280 if(textArea.isDragInProgress()) 281 return; 282 283 if(textArea.getBuffer().isLoading()) 284 return; 285 286 TextAreaPainter painter = textArea.getPainter(); 287 if(evt.getY() < 0) 288 { 289 int delta = Math.min(-1,evt.getY() 290 / painter.getFontMetrics() 291 .getHeight()); 292 textArea.setFirstLine(textArea.getFirstLine() + delta); 293 } 294 else if(evt.getY() >= painter.getHeight()) 295 { 296 int delta = Math.max(1,(evt.getY() 297 - painter.getHeight()) / 298 painter.getFontMetrics() 299 .getHeight()); 300 if(textArea.lastLinePartial) 301 delta--; 302 textArea.setFirstLine(textArea.getFirstLine() + delta); 303 } 304 305 switch(clickCount) 306 { 307 case 1: 308 doSingleDrag(evt); 309 break; 310 case 2: 311 doDoubleDrag(evt); 312 break; 313 default: doTripleDrag(evt); 315 break; 316 } 317 } 319 private void doSingleDrag(MouseEvent evt) 321 { 322 dragged = true; 323 324 TextAreaPainter painter = textArea.getPainter(); 325 326 int x = evt.getX(); 327 int y = evt.getY(); 328 if(y < 0) 329 y = 0; 330 else if(y >= painter.getHeight()) 331 y = painter.getHeight() - 1; 332 333 int dot = textArea.xyToOffset(x,y, 334 (!painter.isBlockCaretEnabled() 335 && !textArea.isOverwriteEnabled()) 336 || quickCopyDrag); 337 int dotLine = textArea.getLineOfOffset(dot); 338 int extraEndVirt = 0; 339 340 if(textArea.chunkCache.getLineInfo( 341 textArea.getLastScreenLine()) 342 .lastSubregion) 343 { 344 int screenLine = textArea.getScreenLineOfOffset(dot); 345 ChunkCache.LineInfo lineInfo = textArea.chunkCache.getLineInfo(screenLine); 346 int offset = textArea.getScreenLineEndOffset(screenLine); 347 if ((1 != offset - dot) || (lineInfo.lastSubregion)) 348 { 349 offset--; 350 } 351 float dotLineWidth = textArea.offsetToXY(offset).x; 352 if(x > dotLineWidth) 353 { 354 extraEndVirt = (int)((x - dotLineWidth) / textArea.charWidth); 355 if(!painter.isBlockCaretEnabled() 356 && !textArea.isOverwriteEnabled() 357 && (x - textArea.getHorizontalOffset()) % textArea.charWidth > textArea.charWidth / 2) 358 extraEndVirt++; 359 } 360 } 361 362 textArea.resizeSelection(dragStart,dot,extraEndVirt, 363 textArea.isRectangularSelectionEnabled() 364 || control); 365 366 if(quickCopyDrag) 367 { 368 textArea.scrollTo(dotLine,dot - textArea.getLineStartOffset(dotLine),false); 370 } 371 else 372 { 373 if(dot != textArea.getCaretPosition()) 374 textArea.moveCaretPosition(dot,false); 375 if(textArea.isRectangularSelectionEnabled() 376 && extraEndVirt != 0) 377 { 378 textArea.scrollTo(dotLine,dot - textArea.getLineStartOffset(dotLine) 379 + extraEndVirt,false); 380 } 381 } 382 } 384 private void doDoubleDrag(MouseEvent evt) 386 { 387 int markLineStart = textArea.getLineStartOffset(dragStartLine); 388 int markLineLength = textArea.getLineLength(dragStartLine); 389 int mark = dragStartOffset; 390 391 TextAreaPainter painter = textArea.getPainter(); 392 393 int pos = textArea.xyToOffset(evt.getX(), 394 Math.max(0,Math.min(painter.getHeight(),evt.getY())), 395 !(painter.isBlockCaretEnabled() 396 || textArea.isOverwriteEnabled())); 397 int line = textArea.getLineOfOffset(pos); 398 int lineStart = textArea.getLineStartOffset(line); 399 int lineLength = textArea.getLineLength(line); 400 int offset = pos - lineStart; 401 402 String lineText = textArea.getLineText(line); 403 String markLineText = textArea.getLineText(dragStartLine); 404 String noWordSep = textArea.getBuffer() 405 .getStringProperty("noWordSep"); 406 boolean joinNonWordChars = textArea.getJoinNonWordChars(); 407 408 if(markLineStart + dragStartOffset > lineStart + offset) 409 { 410 if(offset != 0 && offset != lineLength) 411 { 412 offset = TextUtilities.findWordStart( 413 lineText,offset,noWordSep, 414 joinNonWordChars); 415 } 416 417 if(markLineLength != 0) 418 { 419 mark = TextUtilities.findWordEnd( 420 markLineText,mark,noWordSep, 421 joinNonWordChars); 422 } 423 } 424 else 425 { 426 if(offset != 0 && lineLength != 0) 427 { 428 offset = TextUtilities.findWordEnd( 429 lineText,offset,noWordSep, 430 joinNonWordChars); 431 } 432 433 if(mark != 0 && mark != markLineLength) 434 { 435 mark = TextUtilities.findWordStart( 436 markLineText,mark,noWordSep, 437 joinNonWordChars); 438 } 439 } 440 441 if(lineStart + offset == textArea.getCaretPosition()) 442 return; 443 444 textArea.resizeSelection(markLineStart + mark, 445 lineStart + offset,0,false); 446 textArea.moveCaretPosition(lineStart + offset,false); 447 448 dragged = true; 449 } 451 private void doTripleDrag(MouseEvent evt) 453 { 454 TextAreaPainter painter = textArea.getPainter(); 455 456 int offset = textArea.xyToOffset(evt.getX(), 457 Math.max(0,Math.min(painter.getHeight(),evt.getY())), 458 false); 459 int mouseLine = textArea.getLineOfOffset(offset); 460 int mark; 461 int mouse; 462 if(dragStartLine > mouseLine) 463 { 464 mark = textArea.getLineEndOffset(dragStartLine) - 1; 465 if(offset == textArea.getLineEndOffset(mouseLine) - 1) 466 mouse = offset; 467 else 468 mouse = textArea.getLineStartOffset(mouseLine); 469 } 470 else 471 { 472 mark = textArea.getLineStartOffset(dragStartLine); 473 if(offset == textArea.getLineStartOffset(mouseLine)) 474 mouse = offset; 475 else if(offset == textArea.getLineEndOffset(mouseLine) - 1 476 && mouseLine != textArea.getLineCount() - 1) 477 mouse = textArea.getLineEndOffset(mouseLine); 478 else 479 mouse = textArea.getLineEndOffset(mouseLine) - 1; 480 } 481 482 mouse = Math.min(textArea.getBuffer().getLength(),mouse); 483 484 if(mouse == textArea.getCaretPosition()) 485 return; 486 487 textArea.resizeSelection(mark,mouse,0,false); 488 textArea.moveCaretPosition(mouse,false); 489 490 dragged = true; 491 } 493 public void mouseReleased(MouseEvent evt) 495 { 496 if(!dragged && textArea.isQuickCopyEnabled() && 497 isMiddleButton(evt.getModifiers())) 498 { 499 textArea.requestFocus(); 500 TextArea.focusedComponent = textArea; 501 502 textArea.setCaretPosition(dragStart,false); 503 } 504 else if(maybeDragAndDrop 505 && !textArea.isMultipleSelectionEnabled()) 506 { 507 textArea.selectNone(); 508 } 509 510 dragged = false; 511 } 513 521 public static boolean isPopupTrigger(MouseEvent evt) 522 { 523 return isRightButton(evt.getModifiers()); 524 } 526 531 public static boolean isMiddleButton(int modifiers) 532 { 533 if (OperatingSystem.isMacOS()) 534 { 535 if((modifiers & MouseEvent.BUTTON1_MASK) != 0) 536 return (modifiers & MouseEvent.ALT_MASK) != 0; 537 else 538 return (modifiers & MouseEvent.BUTTON2_MASK) != 0; 539 } 540 else 541 return (modifiers & MouseEvent.BUTTON2_MASK) != 0; 542 } 544 549 public static boolean isRightButton(int modifiers) 550 { 551 if (OperatingSystem.isMacOS()) 552 { 553 if((modifiers & MouseEvent.BUTTON1_MASK) != 0) 554 return (modifiers & MouseEvent.CTRL_MASK) != 0; 555 else 556 return (modifiers & MouseEvent.BUTTON3_MASK) != 0; 557 } 558 else 559 return (modifiers & MouseEvent.BUTTON3_MASK) != 0; 560 } 562 protected TextArea textArea; 564 protected int dragStartLine; 565 protected int dragStartOffset; 566 protected int dragStart; 567 protected int clickCount; 568 protected boolean dragged; 569 protected boolean quickCopyDrag; 570 protected boolean control; 571 573 protected boolean maybeDragAndDrop; 574 575 protected void showCursor() 577 { 578 textArea.getPainter().setCursor( 579 Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); 580 } 582 } 584 | Popular Tags |