Skip to content
This repository has been archived by the owner on Aug 6, 2023. It is now read-only.

Add click events in the widgets? #166

Closed
ivanceras opened this issue Jun 30, 2019 · 10 comments
Closed

Add click events in the widgets? #166

ivanceras opened this issue Jun 30, 2019 · 10 comments

Comments

@ivanceras
Copy link

I look at gocui and seems to have support for click events on the widgets. I would want to see this implemented, is there any reason why this is not implemented. I'd try to get this to work, but I first I'd like to know if someone has tried doing and see if it's not worth adding?

@fdehau
Copy link
Owner

fdehau commented Jul 16, 2019

Currently events are not handled by the crate itself. Since the current architecture is not retained, supporting mouse events can be challenging. Some possible solutions could be providing the id of the widget where a hit happen or a way to define callbacks when those events are fired. Both imply a major change in the architecture and maybe in the api, so I would consider this a possible future improvement.

@ivanceras
Copy link
Author

The fork I have https://github.com/ivanceras/itui make the widgets hold the area they are in, instead of passing it every draw call. The event listener is also attached to the widget. Since, all the events is triggered from the application level, the way to let widgets it is the target is by checking the area if it was hit (if it is a mouseclick). All the widgets are check against the event (ie. mouseevent) to match the coordinate (x,y) if it hits the widget area and the event name/type is the same. The event listener is then emitted/called when the conditions are met.

I have yet to release the overall code of that glue all of this.
Meanwhile this what it looks like https://twitter.com/ivanceras/status/1150841336590786562

@lgirault
Copy link
Contributor

Hi, first thanks for this really cool library. Do you still consider handling click event a possible future improvement ? Perhaps even more generally having the possibily to pass an event handler ? with some defaults event handlers ? Since that widget can now be stateful, it seems the logical next step to handle behaviors like switching tabs. I'm just starting to learn rust but I'm willing to help on the subject.

@fdehau
Copy link
Owner

fdehau commented Mar 12, 2020

Thanks for your interest in the library. While recent additions to the crate might ease the processing of some user inputs, we are still far from a support of click events unfortunately. I still have not made up my mind about the way to implement this. As one can see, the library is very open regarding how, when and why you decide to draw to the terminal, especially because it does not manage an event loop. It is a nice property in a lot of cases but it also falls short for others, such as click events.

Given the current architecture of the project, I would be more inclined to provide some interface to let people check whether a particular widget was clicked than having event callback on the widget themselves because the latter imply that we have access to those events.

I would also point out that I'm not familiar with all the details and innovations that have been pushed out in the field of declarative and reactive UI recently so I may not be in the best position to provide the nicest solution to this problem =). I would thus be more than happy to see informed opinions about this matter.

@fdehau fdehau mentioned this issue May 27, 2020
@teohhanhui
Copy link

teohhanhui commented Jun 1, 2020

Something else to consider: currently it's impossible(?) to implement click to select for list items, as offset is private in ListState.

I can keep a mapping of clickable targets to their respective area (Rect), and figure out which Rect contains the clicked point (col, row). By extension, I can imagine splitting the Rect further to determine which displayed index is clicked on. However, there seems to be no way to map this back to actual index since we don't know the offset.

Or am I missing something?

EDIT: It's possible to select a list item by using selected + n / selected - n.
EDIT 2: Actually no... selected() gives the actual index, not the displayed index. So there's still no way to map that.

@fdehau
Copy link
Owner

fdehau commented Jun 3, 2020

@teohhanhui No that's not possible at the moment but it would definitively be taken into account in a solution to improve the mouse events integration. I'm still exploring different solutions but I've yet to come up with an api that I like. I'm might open an RFC with different solutions so that an open design discussion can happen on this subject.

@henkkuli
Copy link

henkkuli commented Oct 9, 2020

@teohhanhui @fdehau What would you think of adding a method index_of_item_at(&self, point: (u16, u16), area: Rect, state: ListState) -> Option<usize> for List that returns the index of the item at the given point? This should be a method of List instead of ListState because the list can hold a border which affects the calculation.

@teohhanhui
Copy link

@henkkuli There's already an Index trait in core / std.

@henkkuli
Copy link

henkkuli commented Oct 9, 2020

@henkkuli There's already an Index trait in core / std.

Sorry, I don't follow what you mean by this? There is std::ops::Index, but I don't see what it has to do with my proposal.

@teohhanhui
Copy link

teohhanhui commented Oct 10, 2020

I was thinking something like:

list.index((x, y))

but now I see it needs to be:

list.index(((x, y), area, state))

which probably doesn't make sense. So nevermind. 🙈

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

No branches or pull requests

5 participants