You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I tried to get started with relm4 by porting one of my applications, but unfortunately I hit a major roadblock in form of adw::TabView, which proved to be challenging to fit into relm4's scaffold. The natural relm4 way to operate a TabView seems to be through factories:
However, there are two problems. The first one is that you want your Page prototype to control not just the page's child widget, but also the properties of the adw::TabPage itself, such as title or loading or icon, ideally though a mechanism similar to view! {} with change tracking and all. This could be worked around by giving the prototype some way to access to adw::TabPage from view(); something similar is needed for dialog components that get access to their parent's window.
The second problem is unfortunately much more difficult. adw::TabView is far from just a view; it has its own internal model of the tabs, which it actively manages. An adw::TabBar lets the user close, rearrange, detach, attach, move to and from a different tab view, any tab, which needs to somehow be reflected back onto our AppModel's pages field. adw::TabView provides signals such as page-attached, page-detached, page-reordered that notify us of the changes that we need to propagate to our own pages, however:
Changing our own pages will result in the factory trying to "apply" these changes to the TabView "again". There are a few widgets that already have this issue, e.g. gtk::DropDown, which in this relm4 example is handled by listening to its notify callback and reflecting the changes on the model. Here double-state-application is not a problem because gtk::DropDown will simply check that we're setting it the same value and avoid emitting the notify callback, and thus an infinite loop. adw::TabView has much more complex interactions that need careful handling.
adw::TabView operates on adw::TabPages and their child widgets: you can look up an adw::TabPage by the child widget, and you get an adw::TabPage from the callbacks. This corresponds to the GTK architecture where widgets contain all their state, but not to the relm4 architecture where the state (the model) is separated from the view (the widget). Therefore there needs to be some way to get the model back from an adw::TabPage (and it needs to support receiving a TabPage from some other TabView elsewhere in the app). One idea I came up with is a wrapper bin widget that stores a pointer to the model (i.e. as a OnceCell<Box<dyn Any>>) and allows relm4 to retrieve it back; I'm not sure if that's the best approach.
I tried to get some sort of hackish solution to adw::TabView working within the bounds of relm4, but I couldn't really get past the roadblocks I kept hitting. I believe it needs some rearchitecturing of relm4 to support these kinds of widgets.
The text was updated successfully, but these errors were encountered:
I tried to get started with relm4 by porting one of my applications, but unfortunately I hit a major roadblock in form of
adw::TabView
, which proved to be challenging to fit into relm4's scaffold. The natural relm4 way to operate aTabView
seems to be through factories:However, there are two problems. The first one is that you want your
Page
prototype to control not just the page's child widget, but also the properties of theadw::TabPage
itself, such astitle
orloading
oricon
, ideally though a mechanism similar toview! {}
with change tracking and all. This could be worked around by giving the prototype some way to access toadw::TabPage
fromview()
; something similar is needed for dialog components that get access to their parent's window.The second problem is unfortunately much more difficult.
adw::TabView
is far from just a view; it has its own internal model of the tabs, which it actively manages. Anadw::TabBar
lets the user close, rearrange, detach, attach, move to and from a different tab view, any tab, which needs to somehow be reflected back onto ourAppModel
'spages
field.adw::TabView
provides signals such aspage-attached
,page-detached
,page-reordered
that notify us of the changes that we need to propagate to our ownpages
, however:pages
will result in the factory trying to "apply" these changes to theTabView
"again". There are a few widgets that already have this issue, e.g.gtk::DropDown
, which in this relm4 example is handled by listening to its notify callback and reflecting the changes on the model. Here double-state-application is not a problem becausegtk::DropDown
will simply check that we're setting it the same value and avoid emitting the notify callback, and thus an infinite loop.adw::TabView
has much more complex interactions that need careful handling.adw::TabView
operates onadw::TabPage
s and their child widgets: you can look up anadw::TabPage
by the child widget, and you get anadw::TabPage
from the callbacks. This corresponds to the GTK architecture where widgets contain all their state, but not to the relm4 architecture where the state (the model) is separated from the view (the widget). Therefore there needs to be some way to get the model back from anadw::TabPage
(and it needs to support receiving aTabPage
from some otherTabView
elsewhere in the app). One idea I came up with is a wrapper bin widget that stores a pointer to the model (i.e. as aOnceCell<Box<dyn Any>>
) and allows relm4 to retrieve it back; I'm not sure if that's the best approach.I tried to get some sort of hackish solution to
adw::TabView
working within the bounds of relm4, but I couldn't really get past the roadblocks I kept hitting. I believe it needs some rearchitecturing of relm4 to support these kinds of widgets.The text was updated successfully, but these errors were encountered: