gi-gtk-declarative
gi-gtk-declarative copied to clipboard
ComboBoxText support
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.
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:
- Use
CustomWidget
and implement a wrapper, either for your project or ingi-gtk-declarative
- Create a new widget wrapper (without
CustomWidget
) ingi-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?
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.
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.