403 return null; 404 } 405 406 if (peer instanceof LWComponentPeer) 407 return (LWComponentPeer)peer; 408 409 return null; 410 } 411 412 // =========================== NSTextInput callbacks =========================== 413 // The 'marked text' that we get from Cocoa. We need to track this separately, since 414 // Java doesn't let us ask the IM context for it. 415 private AttributedString fCurrentText = null; 416 private String fCurrentTextAsString = null; 417 private int fCurrentTextLength = 0; 418 419 /** 420 * Tell the component to commit all of the characters in the string to the current 421 * text view. This effectively wipes out any text in progress. 422 */ 423 synchronized private void insertText(String aString) { 424 AttributedString attribString = new AttributedString(aString); 425 426 // Set locale information on the new string. 427 attribString.addAttribute(Attribute.LANGUAGE, getLocale(), 0, aString.length()); 428 429 TextHitInfo theCaret = TextHitInfo.afterOffset(aString.length() - 1); 430 InputMethodEvent event = new InputMethodEvent(fAwtFocussedComponent, 431 InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, 432 attribString.getIterator(), 433 aString.length(), 434 theCaret, 435 theCaret); 436 LWCToolkit.postEvent(LWCToolkit.targetToAppContext(fAwtFocussedComponent), event); 437 fCurrentText = null; 438 fCurrentTextAsString = null; 439 fCurrentTextLength = 0; 440 } 441 442 private void startIMUpdate (String rawText) { 443 fCurrentTextAsString = new String(rawText); 444 fCurrentText = new AttributedString(fCurrentTextAsString); 445 fCurrentTextLength = rawText.length(); 446 } 447 448 static private final int kCaretPosition = 0; 449 static private final int kRawText = 1; 450 static private final int kSelectedRawText = 2; 451 static private final int kConvertedText = 3; 452 static private final int kSelectedConvertedText = 4; 453 454 /** 455 * Convert Cocoa text highlight attributes into Java input method highlighting. 473 474 switch (markupType) { 475 case kSelectedRawText: 476 theHighlight = InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT; 477 break; 478 case kConvertedText: 479 theHighlight = InputMethodHighlight.UNSELECTED_CONVERTED_TEXT_HIGHLIGHT; 480 break; 481 case kSelectedConvertedText: 482 theHighlight = InputMethodHighlight.SELECTED_CONVERTED_TEXT_HIGHLIGHT; 483 break; 484 case kRawText: 485 default: 486 theHighlight = InputMethodHighlight.UNSELECTED_RAW_TEXT_HIGHLIGHT; 487 break; 488 } 489 490 fCurrentText.addAttribute(TextAttribute.INPUT_METHOD_HIGHLIGHT, theHighlight, begin, end); 491 } 492 493 /* Called from JNI to select the previously typed glyph during press and hold */ 494 private void selectPreviousGlyph() { 495 if (fIMContext == null) return; // ??? 496 try { 497 LWCToolkit.invokeLater(new Runnable() { 498 public void run() { 499 final int offset = fIMContext.getInsertPositionOffset(); 500 if (offset < 1) return; // ??? 501 502 if (fAwtFocussedComponent instanceof JTextComponent) { 503 ((JTextComponent) fAwtFocussedComponent).select(offset - 1, offset); 504 return; 505 } 506 507 if (fAwtFocussedComponent instanceof TextComponent) { 508 ((TextComponent) fAwtFocussedComponent).select(offset - 1, offset); 509 return; 510 } 511 // TODO: Ideally we want to disable press-and-hold in this case 512 } 513 }, fAwtFocussedComponent); 514 } catch (Exception e) { 515 e.printStackTrace(); 516 } 517 } 518 519 private void selectNextGlyph() { 520 if (fIMContext == null || !(fAwtFocussedComponent instanceof JTextComponent)) return; 521 try { 522 LWCToolkit.invokeLater(new Runnable() { 523 public void run() { 524 final int offset = fIMContext.getInsertPositionOffset(); 525 if (offset < 0) return; 526 ((JTextComponent) fAwtFocussedComponent).select(offset, offset + 1); 527 return; 528 } 529 }, fAwtFocussedComponent); 530 } catch (Exception e) { 531 e.printStackTrace(); 532 } 533 } 534 535 private void dispatchText(int selectStart, int selectLength, boolean pressAndHold) { 536 // Nothing to do if we have no text. 537 if (fCurrentText == null) 538 return; 539 540 TextHitInfo theCaret = (selectLength == 0 ? TextHitInfo.beforeOffset(selectStart) : null); 541 TextHitInfo visiblePosition = TextHitInfo.beforeOffset(0); 542 543 InputMethodEvent event = new InputMethodEvent(fAwtFocussedComponent, 544 InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, 545 fCurrentText.getIterator(), 546 0, 547 theCaret, 548 visiblePosition); 549 LWCToolkit.postEvent(LWCToolkit.targetToAppContext(fAwtFocussedComponent), event); 550 551 if (pressAndHold) selectNextGlyph(); 552 } 553 554 /** 555 * Frequent callbacks from NSTextInput. I think we're supposed to commit it here? 556 */ 557 synchronized private void unmarkText() { 558 if (fCurrentText == null) 559 return; 560 561 TextHitInfo theCaret = TextHitInfo.afterOffset(fCurrentTextLength); 562 TextHitInfo visiblePosition = theCaret; 563 InputMethodEvent event = new InputMethodEvent(fAwtFocussedComponent, 564 InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, 565 fCurrentText.getIterator(), 566 fCurrentTextLength, 567 theCaret, 568 visiblePosition); | 403 return null; 404 } 405 406 if (peer instanceof LWComponentPeer) 407 return (LWComponentPeer)peer; 408 409 return null; 410 } 411 412 // =========================== NSTextInput callbacks =========================== 413 // The 'marked text' that we get from Cocoa. We need to track this separately, since 414 // Java doesn't let us ask the IM context for it. 415 private AttributedString fCurrentText = null; 416 private String fCurrentTextAsString = null; 417 private int fCurrentTextLength = 0; 418 419 /** 420 * Tell the component to commit all of the characters in the string to the current 421 * text view. This effectively wipes out any text in progress. 422 */ 423 synchronized private void insertText(String aString, int replaceStart, int replaceLength) { 424 AttributedString attribString = new AttributedString(aString); 425 426 // Set locale information on the new string. 427 attribString.addAttribute(Attribute.LANGUAGE, getLocale(), 0, aString.length()); 428 429 TextHitInfo theCaret = TextHitInfo.afterOffset(aString.length() - 1); 430 InputMethodEvent event = new InputMethodEvent(fAwtFocussedComponent, 431 InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, 432 attribString.getIterator(), 433 aString.length(), 434 theCaret, 435 theCaret, 436 replaceStart, replaceStart + replaceLength); 437 LWCToolkit.postEvent(LWCToolkit.targetToAppContext(fAwtFocussedComponent), event); 438 fCurrentText = null; 439 fCurrentTextAsString = null; 440 fCurrentTextLength = 0; 441 } 442 443 private void startIMUpdate (String rawText) { 444 fCurrentTextAsString = new String(rawText); 445 fCurrentText = new AttributedString(fCurrentTextAsString); 446 fCurrentTextLength = rawText.length(); 447 } 448 449 static private final int kCaretPosition = 0; 450 static private final int kRawText = 1; 451 static private final int kSelectedRawText = 2; 452 static private final int kConvertedText = 3; 453 static private final int kSelectedConvertedText = 4; 454 455 /** 456 * Convert Cocoa text highlight attributes into Java input method highlighting. 474 475 switch (markupType) { 476 case kSelectedRawText: 477 theHighlight = InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT; 478 break; 479 case kConvertedText: 480 theHighlight = InputMethodHighlight.UNSELECTED_CONVERTED_TEXT_HIGHLIGHT; 481 break; 482 case kSelectedConvertedText: 483 theHighlight = InputMethodHighlight.SELECTED_CONVERTED_TEXT_HIGHLIGHT; 484 break; 485 case kRawText: 486 default: 487 theHighlight = InputMethodHighlight.UNSELECTED_RAW_TEXT_HIGHLIGHT; 488 break; 489 } 490 491 fCurrentText.addAttribute(TextAttribute.INPUT_METHOD_HIGHLIGHT, theHighlight, begin, end); 492 } 493 494 private void selectNextGlyph() { 495 if (fIMContext == null || !(fAwtFocussedComponent instanceof JTextComponent)) return; 496 try { 497 LWCToolkit.invokeLater(new Runnable() { 498 public void run() { 499 final int offset = fIMContext.getInsertPositionOffset(); 500 if (offset < 0) return; 501 ((JTextComponent) fAwtFocussedComponent).select(offset, offset + 1); 502 return; 503 } 504 }, fAwtFocussedComponent); 505 } catch (Exception e) { 506 e.printStackTrace(); 507 } 508 } 509 510 private void dispatchText(int selectStart, int selectLength, int replaceStart, int replaceEnd, boolean pressAndHold) { 511 // Nothing to do if we have no text. 512 if (fCurrentText == null) 513 return; 514 515 TextHitInfo theCaret = (selectLength == 0 ? TextHitInfo.beforeOffset(selectStart) : null); 516 TextHitInfo visiblePosition = TextHitInfo.beforeOffset(0); 517 518 InputMethodEvent event = new InputMethodEvent(fAwtFocussedComponent, 519 InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, 520 fCurrentText.getIterator(), 521 0, 522 theCaret, 523 visiblePosition, 524 replaceStart, replaceStart + replaceEnd); 525 LWCToolkit.postEvent(LWCToolkit.targetToAppContext(fAwtFocussedComponent), event); 526 527 if (pressAndHold) selectNextGlyph(); 528 } 529 530 /** 531 * Frequent callbacks from NSTextInput. I think we're supposed to commit it here? 532 */ 533 synchronized private void unmarkText() { 534 if (fCurrentText == null) 535 return; 536 537 TextHitInfo theCaret = TextHitInfo.afterOffset(fCurrentTextLength); 538 TextHitInfo visiblePosition = theCaret; 539 InputMethodEvent event = new InputMethodEvent(fAwtFocussedComponent, 540 InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, 541 fCurrentText.getIterator(), 542 fCurrentTextLength, 543 theCaret, 544 visiblePosition); |