gi-gtk-declarative icon indicating copy to clipboard operation
gi-gtk-declarative copied to clipboard

ComboBoxText support

Open niteria opened this issue 5 years ago • 3 comments

I've had some success adding support for Gtk.Grid by basing it on the Gtk.Box container implementation, but I'm not sure what the best approach for ComboBoxText would be.

The difference between ComboBoxText and Gtk.Grid is that there's nothing that's a Widget inside of ComboBoxText (at least on the surface, I suspect it might be implemented in terms of ComboBox). That got me stuck when I needed to implement Patchable for the item type.

Right now I think that CustomWidget route is a promising one, but maybe I'm missing something.

niteria avatar Jul 09 '19 22:07 niteria

I haven't used ComboBoxText before, but I had a quick look at it. I think we can go either of the following two routes:

  1. Use CustomWidget and implement a wrapper, either for your project or in gi-gtk-declarative
  2. Create a new widget wrapper (without CustomWidget) in gi-gtk-declarative:
  • Provide orphan instances (as in https://github.com/owickstrom/gi-gtk-declarative/blob/master/gi-gtk-declarative/src/GI/Gtk/Declarative/Container/ListBox.hs):
    • IsContainer Gtk.ComboBoxText ComboText
    • ToChildren Gtk.ComboBoxText ComboText
  • You might instead do this for ComboBox directly, and use label widgets as the children. I don't think the ComboBoxText will give you much benefit (as you wouldn't be using it's model/view state handling)

I think option 2 is valuable if you can make it work for ComboBox with any child widget type. Otherwise you might want to try the CustomWidget approach in your own project first, then maybe we can merge it in later?

owickstrom avatar Jul 10 '19 06:07 owickstrom

Thank you for your prompt response.

I gave it another go and using CustomWidget with Gtk.ComboBoxText was the easiest to get working. It became fairly straightforward once I realized that #getActive also works for Gtk.ComboBoxText, the generated haddock (https://www.stackage.org/haddock/nightly-2019-07-10/gi-gtk-3.0.31/GI-Gtk-Objects-ComboBoxText.html) suggested that it's Gtk.ComboBox specific, but that isn't the case.

For now whenever a list of options changes I just remove all of them from the ComboBox and add the new ones. This has the unfortunate effect of deselecting the current selection even if it's still an option. One way to approach this is to do a proper diff and only add/remove what's necessary. There's a Diff package on hackage that implements that. What I opted for instead is to have the current selection as the property of the CustomWidget. This helps me satisfy another requirement that I had - being able to set the active selection from outside.

This brings me to a slightly off-topic question. As I understand, whenever the application state changes we generate a new virtual UI. Say that I have a text input (Gtk.Entry) widget and I want to be able to pre-fill it. That's easy enough, the virtual UI just needs to have a Gtk.Entry with an appropriate property set to the text I want. Now say I start modifying the text. Unless I hook up the "text changed" event for Gtk.Entry and remember the intermediate value, on the next "tick" - when we regenerate the virtual UI the Gtk.Entry will go back to the old value. Does this make sense? Another way of rephrasing my statement is that every hidden state of the UI has to be made explicit in the App state.

I gave it a shot to try option 2, but even ComboBox can't embed any widget type, so it's not really a container in the gi-gtk-declarative sense. I tried it anyway because I was still thinking that Gtk.ComboBoxText doesn't provide #getActive. Setting up the model (using ListStore) is relatively easy if you look at examples in other languages, but I stopped when I needed to set up the view.

niteria avatar Jul 11 '19 21:07 niteria

I just pushed an implementation in terms of CustomWidget to https://github.com/niteria/gi-gtk-declarative/tree/comboboxtext. If that's something you'd like to merge into gi-gtk-declarative please let me know and I will create a pull request.

I'm not that attached to the unsafePtrNeq bits, I can remove them before a pull request if that's something objectionable.

niteria avatar Jul 12 '19 14:07 niteria