rawpython / remi

Python REMote Interface library. Platform independent. In about 100 Kbytes, perfect for your diet.
Apache License 2.0
3.48k stars 401 forks source link

key events on listview #459

Closed caco3 closed 1 year ago

caco3 commented 2 years ago

It would be great to navigate through a listview by keys (up, down).

I think of different ways:

Bonus:

dddomodossola commented 2 years ago

@caco3 this is a good idea, but I think that arrow keys should not change the selection. The arrows should allow navigation between elements (list view scroll) and selection should be changed by SPACE or ENTER. This is because sometimes selection is an important activities (think about an industrial machine setup), and requires an additional command. What do you think about this?

caco3 commented 2 years ago

I understand your point. How ever on most other GUIs one can change the selection in a (focused) list with up/down keys.

What do you think by simply providing a key press event like we have it on a textinput? Then the user would be free to use it in what ever way he wants.

My usecase: I created a photo album editor. A user can set a comment for each photo. There is a listview listing all photos. and a text field which shows the comment of the selected photo. For convenience, the textinput catches the up/down keys and allows switching the selected photo in the listview. This of course how ever only works if the focus is in the textview.

dddomodossola commented 2 years ago

List view should already be able to receive key down and key up events, doesn't it?

dddomodossola commented 2 years ago

@caco3 I will look into this tomorrow and provide you an example ;-)

caco3 commented 2 years ago

List view should already be able to receive key down and key up events, doesn't it?

No, it doesn't work (eg. onkeyup) nor is it documented.

@caco3 I will look into this tomorrow and provide you an example ;-)

Thank you for looking into it. Your framework really is cool!

dddomodossola commented 2 years ago

@caco3 here is an example for you:

import remi.gui as gui
from remi import start, App

class MyApp(App):

    def main(self):
        # creating a container VBox type, vertical (you can use also HBox or Widget)
        main_container = gui.VBox(width=400, height=400, style={'margin': '0px auto'})

        self.lbl = gui.Label("output")
        main_container.append(self.lbl)

        items = ('Danny Young','Christine Holand','Lars Gordon','Roberto Robitaille')
        self.listView = gui.ListView.new_from_list(items, width=300, height=120, margin='10px')
        self.listView.onselection.do(self.list_view_on_selected)
        self.listView.onkeyup.do(self.onkeyup_listview)

        #     vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
        #>>>> this is fundamental to make the list focusable <<<<
        #     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        self.listView.attributes['tabindex'] = '1'

        main_container.append(self.listView)

        # returning the root widget
        return main_container

    def onkeyup_listview(self, emitter, key, keycode, ctrl, shift, alt):
        print("onkeyup: " + keycode)
        self.lbl.set_text("onkeyup: " + keycode) 

        index = 0
        #if an item is selected, get its index
        if self.listView.get_key() in self.listView.children.keys():
            index = list(self.listView.children.keys()).index(self.listView.get_key())

        if keycode == '38': #arrow up
            index-=1 

        elif keycode == '40': #arrow down
            index+=1

        else:
            return

        #prevent index less than zero
        index = max(index, 0)
        #limit index at list size
        index = index % len(self.listView.children)

        #select the index
        key = list(self.listView.children.keys())[index]
        self.listView.select_by_key( key )
        #trigger the onselection event
        self.listView.onselection( self.listView.children[key] )

    def list_view_on_selected(self, emitter, selected_item_key):
        print("list_view_on_selected")
        self.lbl.set_text('List selection: ' + self.listView.children[selected_item_key].get_text())

if __name__ == "__main__":
    # starts the webserver
    start(MyApp, address='0.0.0.0', port=0, start_browser=True, username=None, password=None)
caco3 commented 2 years ago

Dear @dddomodossola Thank you very much for your quick and helpful response! Indeed this is what I wanted! Now as you showed the tabindex thingy, I also see it in the documentation (I wasn't carefully enough to also check the parent widgets documentation :(

Now, there is just one thing left: When the list is so long that scrollbars are needed, a key Up/Down will also scroll it. How ever I don't think suppression of this is easily possible!

dddomodossola commented 2 years ago

Unfortunately remi has no documentation and so, no worries to ask me for help.

About scroll bars there should be a solution. However, for your use case maybe a listview is not perfectly suitable. Maybe you can easily construct your own thumbnail preview gallery, by simply using an HBox (or VBox I you need it vertically), and simulate navigation by appending and removing elements by key press. Maybe you can give it a try, and eventually I can create an example.

caco3 commented 2 years ago

Thanks, it is fine for me as is right now!

As for the documentation: Have you thought about using a wiki for the documentation? An ideal place to host (generated) project documentation is https://readthedocs.org. It free for opensource projects.

How ever I think maybe a wiki form would be better where others can provide explanations by themself. Github provides one automatically: https://github.com/dddomodossola/remi/wiki An example where I contributed before is https://github.com/bit-team/backintime/wiki/FAQ (The pages are too long, its better to have many, short pages).

And if you would want to grow the project and have others actively contributing more, maybe think of moving the project from your space to an organization space: https://docs.github.com/en/get-started/learning-about-github/types-of-github-accounts#organization-accounts.

I would be willing to help you to start something,. because I think this project is really cool!

dddomodossola commented 2 years ago

You are welcome ;-)

The wiki is a good idea.

I already planned to move the project to an organization account. I have already created https://github.com/orgs/rawpython and https://github.com/orgs/the Open Place, I should choose in which one of the two organisations I will move remi.

Have you tried the remi graphical editor? https://github.com/dddomodossola/remi/tree/master/editor