slint-ui / slint

Slint is a declarative GUI toolkit to build native user interfaces for Rust, C++, or JavaScript apps.
https://slint.dev
Other
16.93k stars 565 forks source link

TextInput: Cursor moved to start after text reaches end of widget #1308

Closed FloVanGH closed 2 years ago

FloVanGH commented 2 years ago

On text input, if the cursor reaches the width of TextInput it is moved to the start of the widget. Expected behavior is, that the cursor stays on the end of the text and the text is automatic scrolled horizontal.

I tested it on macOS 12.04.

image
ogoffart commented 2 years ago

I cannot reproduce this issue on my Linux. (trying adding text in the line edit in the gallery example) Are you saying the cursor jumps to the start position if you type enough text?

FloVanGH commented 2 years ago

Some more information:

This is my source code:

global Style := {
    // brushes
    property <brush> background: Brushes.widget-background-regular;
    property <brush> background-hover: Brushes.widget-background-hover;
    property <brush> foreground: Brushes.widget-foreground;
    property <brush> foreground-placeholder: Brushes.widget-foreground-placeholder;
    property <brush> border-brush: transparent;
    property <brush> border-brush-hover: Brushes.widget-border-regular;
    property <brush> border-brush-focused: Brushes.widget-accent;

    // lenghts
    property <length> height: Sizes.widget-height-small;
    property <length> padding: Spacing.widget-spacing-medium;
    property <length> border-radius: Radius.widget-radius-regular;
    property <length> border-width: Spacing.widget-spacing-small;

    // font
    property <length> font-size: Typography.font-size-regular;
    property <string> font-family: Typography.font-family;
    property <int> font-weight: Typography.font-weight-regular;

     // duration
     property <duration> duration: Durations.fast;
}

export TextField := Rectangle {
    property <string> text <=> text-input.text;
    property <string> placeholder-text <=> placeholder.text;

    border-width: Style.border-width;
    border-color: Style.border-brush;
    border-radius: Style.border-radius;
    forward-focus: text-input;
    height: Style.height;
    min-width: 75px;
    clip: true;

    text-input := TextInput { 
        x: Style.padding;
        width: root.width - 2 * Style.padding;
        color: Style.foreground;
        font-family: Style.font-family;
        font-size: Style.font-size;
        font-weight: Style.font-weight;
        horizontal-alignment: TextHorizontalAlignment.left;
        vertical-alignment: TextVerticalAlignment.center;
    }

    placeholder := Text {
        color: Style.foreground-placeholder;
        text: "placeholder";
        x: text-input.x;
        y: text-input.y;
        width: text-input.width;
        height: text-input.height;
        horizontal-alignment: text-input.horizontal-alignment;
        vertical-alignment: text-input.vertical-alignment;
        font-family: text-input.font-family;
        font-size: text-input.font-size;
        font-weight: text-input.font-weight;
        visible: false;

        states [  
            empty when root.text == "" : {
                placeholder.visible: true;
            }
        ]
    }

    touch-area := TouchArea {
        clicked => { text-input.focus(); }
    }

    animate border-color {  
        duration: Style.duration;
    }

    states [  
        focused when text-input.has-focus : {
            root.border-color: Style.border-brush-focused;
            touch-area.enabled: false;
        }
        hover when touch-area.has-hover : {
            root.border-color: Style.border-brush-hover;
        }
    ]
}

After I insert text and the cursor reaches the end of the TextInput width the cursor is displayed at the start of the TextInput. After that it is not possible to move the cursor with arrow key and you cannot remove characters by Backspace or Delete key. But you can move the cursor by mouse click.

I will check the gallery example later.

FloVanGH commented 2 years ago

I checked the gallery example. There is used a TextEdit and it works like expected. But if a use instead a TextInput with a fixed width, then I have the same issue.

In my code I use also a TextInput instead of a TextEdit because I want to create a custom TextEdit(Field).

ogoffart commented 2 years ago

Ah, sorry, I thought you were using the LineEdit. The TextInput is quite low level and a bit harder to use.

Here is how we use it to build a LineEdit: https://github.com/slint-ui/slint/blob/81b53e2ae078d8db096a3d6df08427f0a471c41b/internal/compiler/widgets/common/common.slint#L6

FloVanGH commented 2 years ago

It works :-) thank you!