Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Help] Modify Tab key function in TextArea widget #646

Closed
bauripalash opened this issue Mar 28, 2022 · 4 comments
Closed

[Help] Modify Tab key function in TextArea widget #646

bauripalash opened this issue Mar 28, 2022 · 4 comments

Comments

@bauripalash
Copy link

I am working on a prototype regex tester project https://github.com/bauripalash/rxr-ui
I want to modify the Tab key behavior on the TextArea widget ( or whole window).

I want Tab key to input \t character instead of widget switching.

on_event function seems to handle these, but I can't find any documentation or example how to modify key behaviors on the widget, clearing global callbacks doesn't help. Any suggestions regarding this situation?

@gyscos
Copy link
Owner

gyscos commented Mar 28, 2022

Hi!

The default behaviour of TextArea is to ignore this Tab key.
The default behaviour of most view groups, if no one consumes a tab key, is to move the focus to the next child.
The default behaviour of global callbacks is to only trigger if the event is entirely ignored.
That's why the global callback never has a chance to trigger: the tab key is consumed by the parent of TextArea.

  • Note that you can also add a "pre-event" global callback, which will trigger before the event is event sent to the views. This way it doesn't matter if some view would consume the event, you can react to it before.
  • Another solution is to wrap the TextArea in an OnEventView, and define your own callback for the tab key just for this view (for example using on_event_inner, so the callback has access to the TextArea.). Compared to a global pre-event callback, this will only trigger if the text area is focused, and will not affect other parts of the UI.
let text_area = OnEventView::new(TextArea::new())
    .on_event_inner('\t', |text_area, _event| {
        // Right now, no convenient way to append text...
        let text = text_area.get_content().to_string();
        text_area.set_content(text + "\t");

        // Mark the event as consumed.
        Some(EventResult::consumed())
    });

@bauripalash
Copy link
Author

bauripalash commented Mar 28, 2022

I was working on the solution all afternoon, I tried the same thing you mentioned, but in addition to it, I had also had to move the cursor to the correct position.
Another thing I noticed is that if I insert the \t (tab) characters, the cursor goes to the correct position, but the I-beam just goes a little less ahead, and it makes the interface look confusing, so I used 4 spaces instead of \t character

Here is the commit, where I made the changes bauripalash/rxr-ui@bafba49

How it looks like when I use \t char
asciicast

@gyscos
Copy link
Owner

gyscos commented Mar 28, 2022

but in addition to it, I had also had to move the cursor to the correct position.

Ah right I totally forgot about the cursor. In that case you'll also want to insert the tab character at the cursor's location, and not just append it to the end.

But yeaah tab characters are not easy to deal with; replacing it with a fixed numbers of spaces is probably a simpler solution at this point.

Note that TextArea is really basic, and may not be a perfect fit for a complete code editor. Among other things, it doesn't really support the styling required for syntax highlighting, it stores the content as a simple String so it's not the best for random edition, and I now see that tab handling is also imperfect (I think unicode-width reports a tab as 1-width character, while in practice its width will depend on the terminal, which explains the cursor issue). A better solution might make the tab/space conversion internally, displaying spaces but allowing to erase it entirely with a single backspace, and leaving the \t character in the use-accessible content.

@bauripalash
Copy link
Author

Well, I'm building a regex tester something like regex101 but more simpler, so I don't need much more complicated features just a simple string editor is sufficient.

Thank you, for the help and this awesome library. 😁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants