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.64k stars 238 forks source link

question about focus function of Text widget #290

Closed uthline closed 3 years ago

uthline commented 3 years ago

Hi, Thanks for making a great framework.

I have a question related to the focus function of TEXT widget. When focus is transferred to the Text widget using Tab, the Text widget receives keystrokes well. If focus is forcibly given to the Text widget by using the focus function, the Text widget cannot receive key input.

Should I do more thing to give focus to TEXT widget?

I wrote test example code. After run the example below, press F2 and type, then you will be able to reproduce the symptoms I am talking about.

thanks in advance. have a nice day.

Here is my test code:

#!/usr/bin/env python3

from asciimatics.event import KeyboardEvent
from asciimatics.widgets import Frame, Layout, ListBox, Widget, Label, Text, \
    Divider
from asciimatics.scene import Scene
from asciimatics.screen import Screen
from asciimatics.exceptions import ResizeScreenError, StopApplication
import sys
import os
try:
    import magic
except ImportError:
    pass

class DemoFrame(Frame):
    def __init__(self, screen):
        super(DemoFrame, self).__init__(
            screen, screen.height, screen.width, has_border=False, name="My Form")

        # Create the (very simple) form layout...
        layout = Layout([1], fill_frame=True)
        self.add_layout(layout)

        # Now populate it with the widgets we want to use.
        self._details = Text()
        self._details.disabled = True
        self._details.custom_colour = "field"
        self._details.value = "focus function test"
        self._list = ListBox(
            Widget.FILL_FRAME,
            [('item1', 1),('item2', 2),('item3', 3),],
            name="contacts",
            add_scroll_bar=True,
            on_change=self._on_pick,
            on_select=self._edit)

        # Create the form for displaying the list of contacts.
        # layout = Layout([100], fill_frame=True)
        # self.add_layout(layout)
        layout.add_widget(self._list)
        layout.add_widget(Divider())
        layout.add_widget(self._details)
        layout.add_widget(Label("Press Enter to connect or `q` to quit."))

        self._foot = Text(on_change=self._on_change)
        self._foot.custom_colour = "edit_text"
        layout.add_widget(self._foot)
        self.fix()

    def _on_change(self):
        self._foot.value

    def _on_pick(self):
        pass
        #  self._edit_button.disabled = self._list_view.value is None
        # self._delete_button.disabled = self._list_view.value is None

    def _reload_list(self, new_value=None):
        # self._list_view.options = self._model.get_summary()
        # self._list_view.value = new_value
        pass

    def _edit(self):
        raise StopApplication("User quit")
        # self.save()
        # self._model.current_id = self.data["contacts"]
        # raise NextScene("Edit Contact")

    def process_event(self, event):
        # Do the key handling for this Frame.
        if isinstance(event, KeyboardEvent):
            if event.key_code in [ord('q'), ord('Q'), Screen.ctrl("c")]:
                raise StopApplication("User quit")
            elif event.key_code == Screen.KEY_F1:
                self._list.focus()
            elif event.key_code == Screen.KEY_F2:
                self._foot.focus()
        # Now pass on to lower levels for normal handling of the event.
        return super(DemoFrame, self).process_event(event)

def demo(screen, old_scene):
    screen.play([Scene([DemoFrame(screen)], -1)], stop_on_resize=True, start_scene=old_scene)

last_scene = None
while True:
    try:
        Screen.wrapper(demo, catch_interrupt=True, arguments=[last_scene])
        sys.exit(0)
    except ResizeScreenError as e:
        last_scene = e.scene
peterbrittain commented 3 years ago

You're using the wrong function. That is only really meant for use by the framework.

In order to move the focus properly, you need to call https://asciimatics.readthedocs.io/en/stable/asciimatics.html#asciimatics.widgets.Frame.switch_focus

uthline commented 3 years ago

@peterbrittain thank you. Now I can make the program as I intended.