Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add stack widget #124

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

PhilippMDoerner
Copy link
Contributor

@PhilippMDoerner PhilippMDoerner commented Oct 21, 2023

This is another trickier one in my eyes.

Things that really need to be thought through here:

  • How to "implement" StackPage

PhilippMDoerner and others added 16 commits October 14, 2023 18:32
* Add Search Entry Widget

* Add text field to searchEntry widget

* Add missing text hook

* Improve search entry example

* Further improve example

* Refine which fields you shouldn't have access to

* Add activity to when you stop a search

* Add activity to when you stop a search

* Fix search entry displaying weird spacing

* Unify GtkMinor into a single constant

* Debug change

Attempt to cat out the gtk.nim file to see how the hell it is
getting the impression that GtkMinor is defined twice.

* Move GtkMInor before the passL flag is passed?

Maybe this fixes the problem with the pipeline sudenly thinking
that value was defined twice.

* Unto test-pipeline debug change

* Comment out unsupported search thingy

* Minor tweaks

- Removed searchstring parameter from callbacks
- made sure only changed callback can modify search value
- Updated example
- Moved example to far nicer looking ListBox

* Remove unnecessary Box

* Update examples/widgets/search_entry.nim

Co-authored-by: Can Lehmann <85876381+can-lehmann@users.noreply.github.com>

---------

Co-authored-by: Can Lehmann <85876381+can-lehmann@users.noreply.github.com>
* Add core of password entry widget

* Add bindings for menu model

I do not plan to act on them yet but I'd like to
at least already add them so I don't have to
make the effort later

* Update password entry docs

* Improve gitignore

* Use unsafeAddr for nim version 1.0

* Fix GValue being let instead of var

* Add text field to password entry

* Ensure activateEventCallback also updates state

* Add missing text hook

* Add way to demonstrate 2 way binding

* Remove unnecessary pragma ping pong

* Removed password from activate callback parameters
* Make Centerbox orientable

* Add Action Bar Widget and docs

* Minor refinement to the action bar example

It now actually "deletes" the contents of the label.
There's also a button to reset its value.

* Improve example button styling
This way it is treated like a normal widget everywhere.

However, the updateChildren proc has become pretty special.
Tons of casting WidgetState and Widget to
StackPageState and StackPage
to deal with its internal Widget.
@PhilippMDoerner
Copy link
Contributor Author

PhilippMDoerner commented Nov 25, 2023

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
Copy link
Contributor Author

PhilippMDoerner commented Nov 26, 2023

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.

It now behaves exactly as one would intend and gets animated Stack stuff.

StackSidebar and StackSwitcher are still problematic though as they
require circular references which owlkettle can't do.
If you try to use insert() twice it will instantiate 2 independent Stacks.
@can-lehmann can-lehmann added this to the Owlkettle 4.0.0 milestone Mar 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants