peterbrittain / asciimatics

A cross platform package to do curses-like operations, plus higher level APIs and widgets to create text UIs and ASCII art animations
Apache License 2.0
3.61k stars 238 forks source link

Right side will not align if you use Unicode character. #385

Closed nitsort closed 4 months ago

nitsort commented 4 months ago

Describe the bug If you try to add Chinese in DropdownList, the right side will not align. If fit is true, incomplete content is displayed.

To Reproduce This is my code.

#!/usr/bin/env python3

from asciimatics.widgets import Frame, Layout, DropdownList, Divider
from asciimatics.effects import Background
from asciimatics.event import KeyboardEvent
from asciimatics.scene import Scene
from asciimatics.screen import Screen
from asciimatics.exceptions import ResizeScreenError, StopApplication

class MainFrame(Frame):
    def __init__(self, screen):
        super(MainFrame, self).__init__(screen,
                                       screen.height,
                                       screen.width,
                                       has_border=True,
                                       can_scroll=True,
                                       name="Test")
        layout = Layout([1, 18, 5, 1])
        self.add_layout(layout)
        layout.add_widget(DropdownList([
                ("This is the first option", 1),
                ("This is the second option", 2),
                ("This is the third option", 3)],
                label="DropdownList_en", name="DropdownList_en"), 1)
        layout.add_widget(DropdownList([
                ("这是第一个选项", 1),
                ("这是第二个选项", 2),
                ("这是第三个选项", 3)],
                label="DropdownList_zh", name="DropdownList_zh"), 1)
        layout.add_widget(Divider(draw_line=False, height=3), 1)
        layout.add_widget(DropdownList([
                ("This is the first option", 1),
                ("This is the second option", 2),
                ("This is the third option", 3)],
                label="DropdownList_en", name="DropdownList_en", fit=True), 1)
        layout.add_widget(DropdownList([
                ("这是第一个选项", 1),
                ("这是第二个选项", 2),
                ("这是第三个选项", 3)],
                label="DropdownList_zh", name="DropdownList_zh", fit=True), 1)
        self.fix()

    def process_event(self, event):
        if (event is not None and isinstance(event, KeyboardEvent) and event.key_code == Screen.ctrl("c")):
            raise StopApplication("User quit")

        return super(MainFrame, self).process_event(event)

def demo(screen, scene):
    scenes = [Scene([
        Background(screen),
        MainFrame(screen),
    ], -1)]

    screen.play(scenes, stop_on_resize=True, start_scene=scene, allow_int=True)

last_scene = None
while True:
    try:
        Screen.wrapper(demo, catch_interrupt=True, arguments=[last_scene])
        quit()
    except ResizeScreenError as e:
        last_scene = e.scene

Expected behavior The interface display is the same as in English.

Screenshots image

System details (please complete the following information):

Additional context

peterbrittain commented 4 months ago

Yup - I can see the problem. Will push a patch shortly.