owlkettle icon indicating copy to clipboard operation
owlkettle copied to clipboard

Add stack widget

Open PhilippMDoerner opened this issue 2 years ago • 2 comments

This is another trickier one in my eyes.

Things that really need to be thought through here:

  • How to "implement" StackPage

PhilippMDoerner avatar Oct 21 '23 23:10 PhilippMDoerner

I added a list of topics that make this PR quite challenging in the PR description. For now the only problem I see in particular for a "propper" wrapping of GtkStack is StackPage, or rather how to deal with it..

StackPage isn't really a widget. It doesn't have a constructor and basically is a GObject like Toast. You could ignore it to be honest and just use an adder with 6 pragmas. But that's an adder with 6 pragmas and doesn't express nicely. This also runs into the problem that I can't figure out how to trigger an update of a StackPage property if the value of an adder-parameter changes!.

More explicitly: How could I toggle a StackPage's visibility via its visible property when my change of the visible value in the adder doesn't trigger/propagate that value-change to the StackPage instance.

Imo this should be handled with the Syntax for a widget so that you can easily and readabily set all the necessary properties of the StackPage on it and be done with it. Particularly since these come with a mechanism to automatically update properties. Example:

        Stack():
          hhomogenous = app.hhomogenous
          interpolateSize = app.interpolateSize
          transitionDuration = app.transitionDuration
          transitionType = app.transitionType
          vhomogenous = app.vhomogenous
          visibleChildName = app.visibleChildName
          sensitive = app.sensitive
          tooltip = app.tooltip
          sizeRequest = app.sizeRequest
          
          for labelChild in app.labelChildren:
             {.name: labelChild.name, title: labelChild.title.}

            StackPage():
              iconName = 
              name = labelChild.name
              title = labelChild.title
              Label(text = labelChild.text)

Now this has 2 problems:

  1. StackPage has no constructor. Okay, we can solve this with g_object_new
  2. There is no way to add a GtkStackPage instance to a Stack!

The last one is the real problem. I couldn't find any way to do this. What you do have access to is procs that add GtkWidgets to a GtkStack and return you the GtkStackPage instance that gets created in the process.

That means for this kind of Syntax we'd need to set GtkStackPage instances on our StackPage widgets as part of a (build, update) hook on GtkStack. And we'd also need to re-instantiate GtkStackPages as needed and update the corresponding StackPage widgets with the new values accordingly. Which makes my brain hurt.

All of this could be solved if I could programmatically add a GtkStackPage to a GtkStack, but I really don't see it.

I guess another option would be to use Builder to instantiate the Stack initially and pull out the GtkWidget instances that get created? That seems like an incredibly ugly solution though.

PhilippMDoerner avatar Nov 25 '23 21:11 PhilippMDoerner

I managed to figure out most of it! I can just fake StackPage being an actual widget on making it internally a Box-Widget! Then it can be treated as normal. The updateChildren proc will need to be somewhat special but I got that down pat. I did this experiment in a different branch in order to keep this branch at a "stable" level that is still usable.

The next bit is problematic though. StackSwitcher and Sidebar require references to the GtkStack Widget. However I can't access the GtkWidget from within a view method as far as I can see. I also can't just "insert" the owlkettle Stack widget as that creates a new instance.

Could it be that this runs into the same issue as described in #115 , where the core issue is that you can't have references to widgets in a view methods generally and thus no circular references?

Edit: Given that the "Pseudo-StackPage"-Widget approach works as well or better than what this PR offered previously, I merged the two. The fact it doesn't work with StackSwitcher and StackSidebar doesn't really change anything to before, where they didn't work either.

I've also started experimenting with the "Ref" approach discussed in #115 , but honestly I think either we need to talk architecture about that (as I may be missing a piece of the puzzle that'd make it easier) or you implement it as I'm stuck.

PhilippMDoerner avatar Nov 26 '23 09:11 PhilippMDoerner