381 private final ObjectProperty<Paint> textFill = new StyleableObjectProperty<Paint>(Color.BLACK) { 382 @Override protected void invalidated() { 383 updateTextFill(); 384 } 385 386 @Override public Object getBean() { 387 return TextInputControlSkin.this; 388 } 389 390 @Override public String getName() { 391 return "textFill"; 392 } 393 394 @Override public CssMetaData<TextInputControl,Paint> getCssMetaData() { 395 return StyleableProperties.TEXT_FILL; 396 } 397 }; 398 399 /** 400 * The fill {@code Paint} used for the foreground text color. 401 */ 402 protected final void setTextFill(Paint value) { 403 textFill.set(value); 404 } 405 protected final Paint getTextFill() { 406 return textFill.get(); 407 } 408 protected final ObjectProperty<Paint> textFillProperty() { 409 return textFill; 410 } 411 412 // --- prompt text fill 413 private final ObjectProperty<Paint> promptTextFill = new StyleableObjectProperty<Paint>(Color.GRAY) { 414 @Override public Object getBean() { 415 return TextInputControlSkin.this; 416 } 417 418 @Override public String getName() { 419 return "promptTextFill"; 420 } 421 422 @Override public CssMetaData<TextInputControl,Paint> getCssMetaData() { 423 return StyleableProperties.PROMPT_TEXT_FILL; 424 } 425 }; 426 427 /** 428 * The fill {@code Paint} used for the foreground prompt text color. 429 */ 430 protected final void setPromptTextFill(Paint value) { 431 promptTextFill.set(value); 432 } 433 protected final Paint getPromptTextFill() { 434 return promptTextFill.get(); 435 } 436 protected final ObjectProperty<Paint> promptTextFillProperty() { 437 return promptTextFill; 438 } 439 440 // --- hightlight fill 441 /** 442 * The fill to use for the text when highlighted. 443 */ 444 private final ObjectProperty<Paint> highlightFill = new StyleableObjectProperty<Paint>(Color.DODGERBLUE) { 445 @Override protected void invalidated() { 446 updateHighlightFill(); 447 } 448 449 @Override public Object getBean() { 450 return TextInputControlSkin.this; 451 } 452 453 @Override public String getName() { 454 return "highlightFill"; 455 } 456 457 @Override public CssMetaData<TextInputControl,Paint> getCssMetaData() { 458 return StyleableProperties.HIGHLIGHT_FILL; 459 } 460 }; 461 462 /** 463 * The fill {@code Paint} used for the background of selected text. 464 */ 465 protected final void setHighlightFill(Paint value) { 466 highlightFill.set(value); 467 } 468 protected final Paint getHighlightFill() { 469 return highlightFill.get(); 470 } 471 protected final ObjectProperty<Paint> highlightFillProperty() { 472 return highlightFill; 473 } 474 475 // --- highlight text fill 476 private final ObjectProperty<Paint> highlightTextFill = new StyleableObjectProperty<Paint>(Color.WHITE) { 477 @Override protected void invalidated() { 478 updateHighlightTextFill(); 479 } 480 481 @Override public Object getBean() { 482 return TextInputControlSkin.this; 483 } 484 485 @Override public String getName() { 486 return "highlightTextFill"; 487 } 488 489 @Override public CssMetaData<TextInputControl,Paint> getCssMetaData() { 490 return StyleableProperties.HIGHLIGHT_TEXT_FILL; 491 } 492 }; 493 494 /** 495 * The fill {@code Paint} used for the foreground of selected text. 496 */ 497 protected final void setHighlightTextFill(Paint value) { 498 highlightTextFill.set(value); 499 } 500 protected final Paint getHighlightTextFill() { 501 return highlightTextFill.get(); 502 } 503 protected final ObjectProperty<Paint> highlightTextFillProperty() { 504 return highlightTextFill; 505 } 506 507 // --- display caret 508 private final BooleanProperty displayCaret = new StyleableBooleanProperty(true) { 509 @Override public Object getBean() { 510 return TextInputControlSkin.this; 511 } 512 513 @Override public String getName() { 514 return "displayCaret"; 515 } 538 protected final BooleanProperty forwardBiasProperty() { 539 return forwardBias; 540 } 541 // Public for behavior 542 public final void setForwardBias(boolean isLeading) { 543 forwardBias.set(isLeading); 544 } 545 protected final boolean isForwardBias() { 546 return forwardBias.get(); 547 } 548 549 550 551 /************************************************************************** 552 * 553 * Abstract API 554 * 555 **************************************************************************/ 556 557 /** 558 * @return the path elements describing the shape of the underline for the given range. 559 */ 560 protected abstract PathElement[] getUnderlineShape(int start, int end); 561 /** 562 * @return the path elements describing the bounding rectangles for the given range of text. 563 */ 564 protected abstract PathElement[] getRangeShape(int start, int end); 565 /** 566 * Adds highlight for composed text from Input Method. 567 */ 568 protected abstract void addHighlight(List<? extends Node> nodes, int start); 569 /** 570 * Removes highlight for composed text from Input Method. 571 */ 572 protected abstract void removeHighlight(List<? extends Node> nodes); 573 574 // Public for behavior 575 /** 576 * Moves the caret by one of the given text unit, in the given 577 * direction. Note that only certain combinations are valid, 578 * depending on the implementing subclass. 579 * 580 * @param unit the unit of text to move by. 581 * @param dir the direction of movement. 582 * @param select whether to extends the selection to the new posititon. 583 */ 584 public abstract void moveCaret(TextUnit unit, Direction dir, boolean select); 585 586 /************************************************************************** 587 * 588 * Public API 589 * 590 **************************************************************************/ 591 592 593 // Public for behavior 594 /** 595 * Returns the position to be used for a context menu, based on the location 596 * of the caret handle or selection handles. This is supported only on touch 597 * displays and does not use the location of the mouse. 598 */ 599 public Point2D getMenuPosition() { 600 if (SHOW_HANDLES) { 601 if (caretHandle.isVisible()) { 602 return new Point2D(caretHandle.getLayoutX() + caretHandle.getWidth() / 2, 603 caretHandle.getLayoutY()); 604 } else if (selectionHandle1.isVisible() && selectionHandle2.isVisible()) { 605 return new Point2D((selectionHandle1.getLayoutX() + selectionHandle1.getWidth() / 2 + 606 selectionHandle2.getLayoutX() + selectionHandle2.getWidth() / 2) / 2, 607 selectionHandle2.getLayoutY() + selectionHandle2.getHeight() / 2); 608 } else { 609 return null; 610 } 611 } else { 612 throw new UnsupportedOperationException(); 613 } 614 } 615 616 // For use with PasswordField in TextFieldSkin 617 /** 618 * This method may be overridden by subclasses to replace the displayed 619 * characters without affecting the actual text content. This is used to 620 * display bullet characters in PasswordField. 621 * 622 * @param txt the content that may need to be masked. 623 * @return the replacement string. This may just be the input string, or may be a string of replacement characters with the same length as the input string. 624 */ 625 protected String maskText(String txt) { 626 return txt; 627 } 628 629 /** 630 * Returns the insertion point for a given location. 631 * 632 * @param x 633 * @param y 634 */ 635 protected int getInsertionPoint(double x, double y) { return 0; } 636 637 /** 638 * Returns the bounds of the character at a given index. 639 * 640 * @param index 641 */ 642 public Rectangle2D getCharacterBounds(int index) { return null; } 643 644 /** 645 * Ensures that the character at a given index is visible. 646 * 647 * @param index 648 */ 649 protected void scrollCharacterToVisible(int index) {} 650 651 /** 652 * Invalidates cached min and pref sizes for the TextInputControl. 653 */ 654 protected void invalidateMetrics() { 655 } 656 657 /** 658 * Called when textFill property changes. 659 */ 660 protected void updateTextFill() {}; 661 662 /** 663 * Called when highlightFill property changes. 664 */ 665 protected void updateHighlightFill() {}; 666 667 /** 942 } 943 }; 944 945 private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES; 946 static { 947 List<CssMetaData<? extends Styleable, ?>> styleables = 948 new ArrayList<CssMetaData<? extends Styleable, ?>>(SkinBase.getClassCssMetaData()); 949 styleables.add(TEXT_FILL); 950 styleables.add(PROMPT_TEXT_FILL); 951 styleables.add(HIGHLIGHT_FILL); 952 styleables.add(HIGHLIGHT_TEXT_FILL); 953 styleables.add(DISPLAY_CARET); 954 955 STYLEABLES = Collections.unmodifiableList(styleables); 956 } 957 } 958 959 /** 960 * Returns the CssMetaData associated with this class, which may include the 961 * CssMetaData of its superclasses. 962 */ 963 public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() { 964 return StyleableProperties.STYLEABLES; 965 } 966 967 /** 968 * {@inheritDoc} 969 */ 970 @Override public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() { 971 return getClassCssMetaData(); 972 } 973 974 @Override protected void executeAccessibleAction(AccessibleAction action, Object... parameters) { 975 switch (action) { 976 case SHOW_TEXT_RANGE: { 977 Integer start = (Integer)parameters[0]; 978 Integer end = (Integer)parameters[1]; 979 if (start != null && end != null) { 980 scrollCharacterToVisible(end); 981 scrollCharacterToVisible(start); | 381 private final ObjectProperty<Paint> textFill = new StyleableObjectProperty<Paint>(Color.BLACK) { 382 @Override protected void invalidated() { 383 updateTextFill(); 384 } 385 386 @Override public Object getBean() { 387 return TextInputControlSkin.this; 388 } 389 390 @Override public String getName() { 391 return "textFill"; 392 } 393 394 @Override public CssMetaData<TextInputControl,Paint> getCssMetaData() { 395 return StyleableProperties.TEXT_FILL; 396 } 397 }; 398 399 /** 400 * The fill {@code Paint} used for the foreground text color. 401 * @param value the text fill 402 */ 403 protected final void setTextFill(Paint value) { 404 textFill.set(value); 405 } 406 protected final Paint getTextFill() { 407 return textFill.get(); 408 } 409 protected final ObjectProperty<Paint> textFillProperty() { 410 return textFill; 411 } 412 413 // --- prompt text fill 414 private final ObjectProperty<Paint> promptTextFill = new StyleableObjectProperty<Paint>(Color.GRAY) { 415 @Override public Object getBean() { 416 return TextInputControlSkin.this; 417 } 418 419 @Override public String getName() { 420 return "promptTextFill"; 421 } 422 423 @Override public CssMetaData<TextInputControl,Paint> getCssMetaData() { 424 return StyleableProperties.PROMPT_TEXT_FILL; 425 } 426 }; 427 428 /** 429 * The fill {@code Paint} used for the foreground prompt text color. 430 * @param value the prompt text fill 431 */ 432 protected final void setPromptTextFill(Paint value) { 433 promptTextFill.set(value); 434 } 435 protected final Paint getPromptTextFill() { 436 return promptTextFill.get(); 437 } 438 protected final ObjectProperty<Paint> promptTextFillProperty() { 439 return promptTextFill; 440 } 441 442 // --- hightlight fill 443 /** 444 * The fill to use for the text when highlighted. 445 */ 446 private final ObjectProperty<Paint> highlightFill = new StyleableObjectProperty<Paint>(Color.DODGERBLUE) { 447 @Override protected void invalidated() { 448 updateHighlightFill(); 449 } 450 451 @Override public Object getBean() { 452 return TextInputControlSkin.this; 453 } 454 455 @Override public String getName() { 456 return "highlightFill"; 457 } 458 459 @Override public CssMetaData<TextInputControl,Paint> getCssMetaData() { 460 return StyleableProperties.HIGHLIGHT_FILL; 461 } 462 }; 463 464 /** 465 * The fill {@code Paint} used for the background of selected text. 466 * @param value the highlight fill 467 */ 468 protected final void setHighlightFill(Paint value) { 469 highlightFill.set(value); 470 } 471 protected final Paint getHighlightFill() { 472 return highlightFill.get(); 473 } 474 protected final ObjectProperty<Paint> highlightFillProperty() { 475 return highlightFill; 476 } 477 478 // --- highlight text fill 479 private final ObjectProperty<Paint> highlightTextFill = new StyleableObjectProperty<Paint>(Color.WHITE) { 480 @Override protected void invalidated() { 481 updateHighlightTextFill(); 482 } 483 484 @Override public Object getBean() { 485 return TextInputControlSkin.this; 486 } 487 488 @Override public String getName() { 489 return "highlightTextFill"; 490 } 491 492 @Override public CssMetaData<TextInputControl,Paint> getCssMetaData() { 493 return StyleableProperties.HIGHLIGHT_TEXT_FILL; 494 } 495 }; 496 497 /** 498 * The fill {@code Paint} used for the foreground of selected text. 499 * @param value the highlight text fill 500 */ 501 protected final void setHighlightTextFill(Paint value) { 502 highlightTextFill.set(value); 503 } 504 protected final Paint getHighlightTextFill() { 505 return highlightTextFill.get(); 506 } 507 protected final ObjectProperty<Paint> highlightTextFillProperty() { 508 return highlightTextFill; 509 } 510 511 // --- display caret 512 private final BooleanProperty displayCaret = new StyleableBooleanProperty(true) { 513 @Override public Object getBean() { 514 return TextInputControlSkin.this; 515 } 516 517 @Override public String getName() { 518 return "displayCaret"; 519 } 542 protected final BooleanProperty forwardBiasProperty() { 543 return forwardBias; 544 } 545 // Public for behavior 546 public final void setForwardBias(boolean isLeading) { 547 forwardBias.set(isLeading); 548 } 549 protected final boolean isForwardBias() { 550 return forwardBias.get(); 551 } 552 553 554 555 /************************************************************************** 556 * 557 * Abstract API 558 * 559 **************************************************************************/ 560 561 /** 562 * @param start the start 563 * @param end the end 564 * @return the path elements describing the shape of the underline for the given range. 565 */ 566 protected abstract PathElement[] getUnderlineShape(int start, int end); 567 /** 568 * @param start the start 569 * @param end the end 570 * @return the path elements describing the bounding rectangles for the given range of text. 571 */ 572 protected abstract PathElement[] getRangeShape(int start, int end); 573 /** 574 * Adds highlight for composed text from Input Method. 575 * @param nodes the list of nodes 576 * @param start the start 577 */ 578 protected abstract void addHighlight(List<? extends Node> nodes, int start); 579 /** 580 * Removes highlight for composed text from Input Method. 581 * @param nodes the list of nodes 582 */ 583 protected abstract void removeHighlight(List<? extends Node> nodes); 584 585 // Public for behavior 586 /** 587 * Moves the caret by one of the given text unit, in the given 588 * direction. Note that only certain combinations are valid, 589 * depending on the implementing subclass. 590 * 591 * @param unit the unit of text to move by. 592 * @param dir the direction of movement. 593 * @param select whether to extends the selection to the new posititon. 594 */ 595 public abstract void moveCaret(TextUnit unit, Direction dir, boolean select); 596 597 /************************************************************************** 598 * 599 * Public API 600 * 601 **************************************************************************/ 602 603 604 // Public for behavior 605 /** 606 * Returns the position to be used for a context menu, based on the location 607 * of the caret handle or selection handles. This is supported only on touch 608 * displays and does not use the location of the mouse. 609 * @return the position to be used for this context menu 610 */ 611 public Point2D getMenuPosition() { 612 if (SHOW_HANDLES) { 613 if (caretHandle.isVisible()) { 614 return new Point2D(caretHandle.getLayoutX() + caretHandle.getWidth() / 2, 615 caretHandle.getLayoutY()); 616 } else if (selectionHandle1.isVisible() && selectionHandle2.isVisible()) { 617 return new Point2D((selectionHandle1.getLayoutX() + selectionHandle1.getWidth() / 2 + 618 selectionHandle2.getLayoutX() + selectionHandle2.getWidth() / 2) / 2, 619 selectionHandle2.getLayoutY() + selectionHandle2.getHeight() / 2); 620 } else { 621 return null; 622 } 623 } else { 624 throw new UnsupportedOperationException(); 625 } 626 } 627 628 // For use with PasswordField in TextFieldSkin 629 /** 630 * This method may be overridden by subclasses to replace the displayed 631 * characters without affecting the actual text content. This is used to 632 * display bullet characters in PasswordField. 633 * 634 * @param txt the content that may need to be masked. 635 * @return the replacement string. This may just be the input string, or may be a string of replacement characters with the same length as the input string. 636 */ 637 protected String maskText(String txt) { 638 return txt; 639 } 640 641 /** 642 * Returns the insertion point for a given location. 643 * 644 * @param x the x location 645 * @param y the y location 646 * @return the insertion point for a given location 647 */ 648 protected int getInsertionPoint(double x, double y) { return 0; } 649 650 /** 651 * Returns the bounds of the character at a given index. 652 * 653 * @param index the index 654 * @return the bounds of the character at a given index 655 */ 656 public Rectangle2D getCharacterBounds(int index) { return null; } 657 658 /** 659 * Ensures that the character at a given index is visible. 660 * 661 * @param index the index 662 */ 663 protected void scrollCharacterToVisible(int index) {} 664 665 /** 666 * Invalidates cached min and pref sizes for the TextInputControl. 667 */ 668 protected void invalidateMetrics() { 669 } 670 671 /** 672 * Called when textFill property changes. 673 */ 674 protected void updateTextFill() {}; 675 676 /** 677 * Called when highlightFill property changes. 678 */ 679 protected void updateHighlightFill() {}; 680 681 /** 956 } 957 }; 958 959 private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES; 960 static { 961 List<CssMetaData<? extends Styleable, ?>> styleables = 962 new ArrayList<CssMetaData<? extends Styleable, ?>>(SkinBase.getClassCssMetaData()); 963 styleables.add(TEXT_FILL); 964 styleables.add(PROMPT_TEXT_FILL); 965 styleables.add(HIGHLIGHT_FILL); 966 styleables.add(HIGHLIGHT_TEXT_FILL); 967 styleables.add(DISPLAY_CARET); 968 969 STYLEABLES = Collections.unmodifiableList(styleables); 970 } 971 } 972 973 /** 974 * Returns the CssMetaData associated with this class, which may include the 975 * CssMetaData of its superclasses. 976 * @return the CssMetaData associated with this class, which may include the 977 * CssMetaData of its superclasses 978 */ 979 public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() { 980 return StyleableProperties.STYLEABLES; 981 } 982 983 /** 984 * {@inheritDoc} 985 */ 986 @Override public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() { 987 return getClassCssMetaData(); 988 } 989 990 @Override protected void executeAccessibleAction(AccessibleAction action, Object... parameters) { 991 switch (action) { 992 case SHOW_TEXT_RANGE: { 993 Integer start = (Integer)parameters[0]; 994 Integer end = (Integer)parameters[1]; 995 if (start != null && end != null) { 996 scrollCharacterToVisible(end); 997 scrollCharacterToVisible(start); |