Search Unity

Changing caret style (inside a TextField)?

Discussion in 'UI Toolkit' started by herra_lehtiniemi, Nov 30, 2020.

  1. herra_lehtiniemi

    herra_lehtiniemi

    Joined:
    Feb 12, 2017
    Posts:
    133
    Is it possible to change the caret style inside TextField? For example, making it wider and a bit more visible etc.

    Using UI Toolkit Preview 12
     
  2. HugoBD-Unity

    HugoBD-Unity

    Unity Technologies

    Joined:
    May 14, 2018
    Posts:
    499
    Hi @herra_lehtiniemi!

    It's not something we currently support, but I'll make sure we keep track of this because it would indeed be a really neat feature.
     
    Kirsche likes this.
  3. herra_lehtiniemi

    herra_lehtiniemi

    Joined:
    Feb 12, 2017
    Posts:
    133
    Yea! In my case, for example, I have a white background and black font color. The caret is really invisible and not blinking, so it's hard to find it. Having it blink and a bit wider and in black would really help locating it quickly in a very big multiline TextField.
    Näyttökuva 2020-12-1 kello 12.35.39.png

    Would be easiest to be able to style it directly via USS, maybe some -unity-caret-type with blink/no-blink, -unity-caret-blink-speed or something in that general direction.
     
    Kirsche and HugoBD-Unity like this.
  4. Kirsche

    Kirsche

    Joined:
    Apr 14, 2015
    Posts:
    121
    Hello, I also would like to see this feature. Specifically being able to change the caret color so we can make a dark textbox:

    Unity_LcVuhpYfoe.png
     
  5. osimaleki

    osimaleki

    Joined:
    Jan 15, 2020
    Posts:
    35
    I wanted to add that I am having the same challenge. A big UI challenge that I have not been able to come up with a solution so far. Really need a built in feature to solve for this.
     
    HugoBD-Unity likes this.
  6. HugoBD-Unity

    HugoBD-Unity

    Unity Technologies

    Joined:
    May 14, 2018
    Posts:
    499
    We are planning to improve the InputFields for 2023.1 and improving the customizability of the caret and selection will be part of it.
     
  7. osimaleki

    osimaleki

    Joined:
    Jan 15, 2020
    Posts:
    35
    Thank you for the prompt reply @hugobd! Any chance this change can be pushed to something in 2022 or anything earlier than 2 years from now?

    Could really improve adoptability of the UI for mobile apps and we could really use it!

    A workaround suggestion would be very helpful too. If you can think of anything we can do.

    Thank you!
     
    manuelgoellnitz and Nexer8 like this.
  8. manuelgoellnitz

    manuelgoellnitz

    Joined:
    Feb 15, 2017
    Posts:
    397
    We also have a project with a black background. And you can guess where the caret is :(
     
  9. HugoBD-Unity

    HugoBD-Unity

    Unity Technologies

    Joined:
    May 14, 2018
    Posts:
    499
    You might be able to set the cursor color through USS using this custom style:
    Code (CSharp):
    1. --unity-cursor-color:#B4B4B4;
    Let me know if it worked!
     
    Last edited: Feb 8, 2022
  10. manuelgoellnitz

    manuelgoellnitz

    Joined:
    Feb 15, 2017
    Posts:
    397
    The custom style worked in 2021.2.9
    thx

    Another thing: can we make it blink?
    It is so static...
     
    Last edited: Feb 8, 2022
  11. HugoBD-Unity

    HugoBD-Unity

    Unity Technologies

    Joined:
    May 14, 2018
    Posts:
    499
    Hi @manuelgoellnitz !

    We are aware that InputFields are lacking a blinking cursor, and it's something we are looking to add.

    In the meantime, you could do something like this to add a blinking cursor:

    C#:
    Code (CSharp):
    1.     public static void BlinkingCursor(TextField tf)
    2.     {
    3.         tf.schedule.Execute(() =>
    4.         {
    5.             if(tf.ClassListContains("transparentCursor"))
    6.                 tf.RemoveFromClassList("transparentCursor");
    7.             else
    8.                 tf.AddToClassList("transparentCursor");
    9.         }).Every(1000);
    10.     }
    USS:
    Code (CSharp):
    1. .transparentCursor {
    2.     --unity-cursor-color: rgba(0, 0, 0, 0);
    3. }
     
  12. manuelgoellnitz

    manuelgoellnitz

    Joined:
    Feb 15, 2017
    Posts:
    397
    I didn't think of that although it's quite obvious :)
    I made it a bit more efficient and let it only run, when the textfield is in focus.
     
    HugoBD-Unity likes this.
  13. ChGuidi

    ChGuidi

    Joined:
    Dec 28, 2021
    Posts:
    111
    Thanks for the workaround! However it would be really nice to have this behaviour by default :)
     
  14. manuelgoellnitz

    manuelgoellnitz

    Joined:
    Feb 15, 2017
    Posts:
    397
    I discoverd that when the UI is "Scaled with Screen Size" also is the caret. And since this is allways done to a full pixel, the caret is scaled to 0px width in my case. Which is not very usefull.
    Is there a way to resize it?
     
  15. HugoBD-Unity

    HugoBD-Unity

    Unity Technologies

    Joined:
    May 14, 2018
    Posts:
    499
    Hi @manuelgoellnitz !

    Thanks for bringing this up, it's an issue that has already been reported. We'll look into it shortly and this will be backported. There's a property to change the cursorWidth, but it's currently internal. We are also looking to expose it.
     
    pawelduda and manuelgoellnitz like this.
  16. pawelduda

    pawelduda

    Joined:
    Feb 1, 2019
    Posts:
    45
    Hi,

    Any ETA on this one @hugobd ?
     
  17. HugoBD-Unity

    HugoBD-Unity

    Unity Technologies

    Joined:
    May 14, 2018
    Posts:
    499
    Hi @pawelduda ! We still plan to provide a blinking-cursor and to expose the cursorWidth but it's currently not in the work. No clear ETA on these tasks yet.

    As for the cursor being 0px depending on scale, this is a high-priority bug for us and we'll look into this one shortly.
     
    rage2050a likes this.
  18. ChGuidi

    ChGuidi

    Joined:
    Dec 28, 2021
    Posts:
    111
    Hi,

    I was using this solution but after upgrading to Unity 2022.2.5 it doesn't seem to work anymore. Did something change to the API?
     
  19. HugoBD-Unity

    HugoBD-Unity

    Unity Technologies

    Joined:
    May 14, 2018
    Posts:
    499
    @ChGuidi from which version did you upgrade from?

    The inner hierarchy of the TextField changed in 2022.1, you might need to retarget the USS selector. For more info on the refactor have a look at this forum post.
     
  20. ChGuidi

    ChGuidi

    Joined:
    Dec 28, 2021
    Posts:
    111
    Thanks for the quick reply. We upgraded from 2022.1.24 and there it was still working. I was trying a couple of things to change the cursorColor in code instead of from uss but it's not doing much. To where should I retarget the USS selector?
     
  21. HugoBD-Unity

    HugoBD-Unity

    Unity Technologies

    Joined:
    May 14, 2018
    Posts:
    499
    Another user had a similar issue recently, but with the Selection Color. The selector he's using should work for the cursor color. Let me know if it helps, otherwise I think you should log a but for it.

    Link to other thread.
     
  22. ChGuidi

    ChGuidi

    Joined:
    Dec 28, 2021
    Posts:
    111
    I tried the uss selector of the thread but it doesn't work. I tried several other ones and I do see it appearing in the UI Toolkit Debugger but it's not showing any difference unfortunately. I'll reproduce it in a sample model and report it as a bug.
     
    HugoBD-Unity likes this.
  23. cmdexecutor

    cmdexecutor

    Joined:
    Sep 30, 2014
    Posts:
    21
    Composed a script based on the advices from here, maybe will come handy to someone
    It's an extended TextField with blinking caret and some properties exposed

    Code (CSharp):
    1. using UnityEngine.UIElements;
    2.  
    3. namespace LOL.UI
    4. {
    5.     /// <summary>
    6.     /// Text field with blinking caret.
    7.     /// <list type="bullet">
    8.     ///     <listheader>Exposed UXML properties</listheader>
    9.     ///     <item>blink-interval (in ms)</item>
    10.     ///     <item>blink-enable (if true, caret blinks)</item>
    11.     ///     <item>blink-style (uss style which applies to caret on blink)</item>
    12.     /// </list>
    13.     /// </summary>
    14.     public class BlinkingTextField : TextField
    15.     {
    16.         private readonly IVisualElementScheduledItem _blink;
    17.  
    18.         private long _blinkInterval = 500;
    19.         private bool _isBlinkEnabled = true;
    20.         private string _blinkStyle = "cursor-transparent";
    21.  
    22.         /// <summary>
    23.         /// Caret blink interval in ms.
    24.         /// </summary>
    25.         public long BlinkInterval
    26.         {
    27.             get => _blinkInterval;
    28.             set
    29.             {
    30.                 _blinkInterval = value;
    31.                 _blink?.Every(_blinkInterval);
    32.             }
    33.         }
    34.  
    35.         /// <summary>
    36.         /// Caret uss style applied on blink.
    37.         /// </summary>
    38.         public string BlinkStyle { get => _blinkStyle; set => _blinkStyle = value; }
    39.  
    40.         /// <summary>
    41.         /// If true, caret blinks.
    42.         /// </summary>
    43.         public bool BlinkEnable
    44.         {
    45.             get => _isBlinkEnabled;
    46.             set
    47.             {
    48.                 if (_isBlinkEnabled == value)
    49.                     return;
    50.  
    51.                 _isBlinkEnabled = value;
    52.  
    53.                 if (!_isBlinkEnabled)
    54.                 {
    55.                     if (IsFocused)
    56.                         _blink?.Pause();
    57.  
    58.                     if (ClassListContains(_blinkStyle))
    59.                         RemoveFromClassList(_blinkStyle);
    60.                 }
    61.                 else if (IsFocused)
    62.                 {
    63.                     _blink?.Resume();
    64.                 }
    65.             }
    66.         }
    67.  
    68.         /// <summary>
    69.         /// Returns true if active input.
    70.         /// </summary>
    71.         public bool IsFocused => focusController?.focusedElement == this;
    72.  
    73.         public BlinkingTextField()
    74.         {
    75.             RegisterCallback<FocusEvent>(OnFocus);
    76.             RegisterCallback<BlurEvent>(OnInputEnded);
    77.  
    78.             _blink = schedule.Execute(() =>
    79.             {
    80.                 if (ClassListContains(_blinkStyle))
    81.                     RemoveFromClassList(_blinkStyle);
    82.                 else
    83.                     AddToClassList(_blinkStyle);
    84.             }).Every(_blinkInterval);
    85.  
    86.             _blink.Pause();
    87.         }
    88.  
    89.         private void OnFocus(FocusEvent evt)
    90.         {
    91.             if (!_isBlinkEnabled)
    92.                 return;
    93.  
    94.             _blink.Resume();
    95.         }
    96.  
    97.         private void OnInputEnded(BlurEvent evt)
    98.         {
    99.             _blink.Pause();
    100.         }
    101.  
    102.         public new class UxmlFactory : UxmlFactory<BlinkingTextField, BlinkingUxmlTraits>
    103.         {
    104.         }
    105.  
    106.         [UnityEngine.Scripting.Preserve]
    107.         public class BlinkingUxmlTraits : UxmlTraits
    108.         {
    109.             private readonly UxmlLongAttributeDescription _blinkInterval = new() { name = "blink-interval", use = UxmlAttributeDescription.Use.Optional, defaultValue = 500 };
    110.             private readonly UxmlBoolAttributeDescription _blinkEnable = new() { name = "blink-enable", use = UxmlAttributeDescription.Use.Optional, defaultValue = true };
    111.             private readonly UxmlStringAttributeDescription _blinkStyle = new() { name = "blink-style", use = UxmlAttributeDescription.Use.Optional, defaultValue = "cursor-transparent" };
    112.  
    113.             public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
    114.             {
    115.                 base.Init(ve, bag, cc);
    116.                 ((BlinkingTextField)ve).BlinkInterval = _blinkInterval.GetValueFromBag(bag, cc);
    117.                 ((BlinkingTextField)ve).BlinkEnable = _blinkEnable.GetValueFromBag(bag, cc);
    118.                 ((BlinkingTextField)ve).BlinkStyle = _blinkStyle.GetValueFromBag(bag, cc);
    119.             }
    120.         }
    121.     }
    122. }
    And the styles would be:

    Code (JavaScript):
    1. .unity-text-field {
    2.     --unity-cursor-color:#FFFFFF;
    3. }
    4.  
    5. .cursor-transparent {
    6.     --unity-cursor-color: rgba(0, 0, 0, 0);
    7. }
    8.  
    9. .cursor-red {
    10.     --unity-cursor-color: red;
    11. }
     
    Last edited: Jul 27, 2023
  24. manuelgoellnitz

    manuelgoellnitz

    Joined:
    Feb 15, 2017
    Posts:
    397
    Which Unity Version do you use?
    I had something similar, but since unity 2022.2. my version did not work anymore. I think the problem was that the Textfield is only repainted, when the user types something.
     
  25. cmdexecutor

    cmdexecutor

    Joined:
    Sep 30, 2014
    Posts:
    21
    It's 2022.3.5
    hmm, never faced issues with that script yet. Not sure, sometimes it requires to postpone executions to redraw something, I had a case where I had to schedule executions one after another
     
    manuelgoellnitz likes this.
  26. manuelgoellnitz

    manuelgoellnitz

    Joined:
    Feb 15, 2017
    Posts:
    397
    In this version my code seams to work again :)
     
    cmdexecutor likes this.
  27. ChGuidi

    ChGuidi

    Joined:
    Dec 28, 2021
    Posts:
    111
    manuelgoellnitz likes this.
  28. ahuyscpy

    ahuyscpy

    Joined:
    Nov 16, 2022
    Posts:
    1
    Now how do i can change caret color with 2022.3.10f1 , release note at 2022.3.10f1 has no more supported with --unity-cursor-color and textEdition.cursorColor not effective anymore
     
    rage2050a likes this.
  29. rage2050a

    rage2050a

    Joined:
    Jul 18, 2020
    Posts:
    5
    Adding
    .unity-text-field {
    --unity-cursor-color:#00FF00;
    }​
    to my uss file worked for me.
    (Unity 2023.2.5f1)
     
    unity_3Vgvc20-AT9hew likes this.
  30. BruceKristelijn

    BruceKristelijn

    Joined:
    Apr 28, 2017
    Posts:
    108
    Thanks this is great! Could we animate / smooth the blink in some way?