Skip to content

Making an advanced UIInputText #1318

@eschan145

Description

@eschan145

I've looked at many other GUI toolkits, like tkinter, PyQt5, and some other libraries, and I noticed they each have two separate input widgets: a text entry and an advanced one. I was thinking if we could implement something like that in Arcade. We should call it something like UIText or UIAdvancedText.
tkinter provides a Text widget, which handles formatting in specific tags, which have names, start, and end attributes. The Text widget also can insert images and other widgets. And PyQt5 has a TextEdit widget which allows easy formatting for creating text editors.
An advanced text entry in Arcade would support rich text formatting, complete with shortcuts like Control-b for bold, easy functions for adding images, copy and paste support, select all support, and much more.
Pyglet does provide formatted documents that are pretty easy to use. You create text, and you can add styles to it in different ranges with specified formatting. We could even add insert and delete functions, which accept ranges and text, to make it easy for users to delete text. Like many GUI toolkits, the basic text entry is only singleline, but the multiline text widget supports all of these formats.
I've been working on something like this in my own Arcade GUI toolkit I'm planning to largely distribute, but I'm getting glyph errors when I use formatted documents in the IncrementalTextLayout. Because in pyglet, documents can be attached to layouts, we can just make the document formatted like a pyglet.text.document.FormattedDocument.
Adding keyboard shortcuts and methods for formatting shouldn't be too hard. Below is some of the code I've used for my own toolkit. It's intended to be used programmatically. (BTW I'm using a custom documentation format)

def format_insert(self, *args, **kwargs):
    """Insert a formatted range to a range of indices in the entry. Formats
    are specified in **kwargs. Keep in mind that this is pyglet document
    formatting, not the custom formatting that has been provided by this
    module.
    
    >>> entry.format_insert(5, 10, bold=True, color=(255, 0, 0, 255)) 
    
    Overlapping formats are supported, so you can call this over the same
    range of text. This fixes the problem in tkinter, where overlapping
    tags are not supported.
    
    Dictionary from arguments from:
    https://stackoverflow.com/a/44412830/19573533
    
    indices - a tuple of the start and end indices of the range. Defaults
                to None, which is the whole range of the text.
    
    parameters: tuple (start, end)
    """
    
    indices = args or (0, self.length)
    
    formats = {("arg" + str(index + 1)): argument for index, argument in enumerate(args)}
    formats.update(kwargs)
    del formats["arg1"]
    del formats["arg2"]
    
    self.document.set_style(*indices, formats)

This widget could be really helpful in making rich text user descriptions, notes, and more.

UPDATE: Currently I'm experiencing issues with glyph management; pyglet thinks some glyphs are empty sometimes, and the selected background color is messed up so the selected text and its background color are completely transparent. There is another bug where two areas are supposedly selected, but one is with the correct background and the other one is without.

image

Another system we would have to add is a system that would check for overlapping styles, and then append them to the style stack. For example, if a range of text was made bold by the user, then italic sometime later on, then a system would have to be made so that the bold is added to the range. It could just check the added styles there, then format the style dictionary to have the included style.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementguiRelated to arcade GUI (sub module arcade.gui)

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions