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

Implement TreeView with patchable models #42

Open
eamsden opened this issue Feb 1, 2019 · 6 comments
Open

Implement TreeView with patchable models #42

eamsden opened this issue Feb 1, 2019 · 6 comments

Comments

@eamsden
Copy link
Contributor

eamsden commented Feb 1, 2019

Basic Proposal

A GtkTreeView is associated with an instance of GtkTreeModel which is what actually gets mutated in order to add or remove nodes from the tree (commonly GtkListStore or GtkTreeStore).

One way to handle this would be to have a new declarative widget type View

data ViewWidget widget model event where
  ViewWidget
    :: Typeable widget
    => IsWidget view
    => (Gtk.ManagedPtr widget -> widget)
    -> Vector (Attribute widget event)
    -> model
    -> ViewWidget widget model event

and corresponding smart constructor

viewWidget
  :: ( Patchable (ViewWidget widget model event)
     , Typeable widget
     , Typeable model
     , Typeable event
     , Gtk.IsWidget widget
     , FromWidget (ViewWidget widget model) target
  -> (Gtk.ManagedPtr widget -> widget)
  -> Vector (Atribute widget event)
  -> model
  -> target event

Plus a declarative implementation of columns, lists, and trees.

The Patchable instance for a ViewWidget should recurse into the model and build an operation to update the underlying GtkListStore or GtkTreeStore.

Possible enhancements

  • Newtype wrappers around instantiations of the Model type could be provided to e.g. change the diff algorithm used to generate patches for lists or trees.
@eamsden
Copy link
Contributor Author

eamsden commented Feb 1, 2019

@owickstrom I'm interested in implementing this but it definitely requires discussion and your sign-off on the design before I can start working on it.

@eamsden
Copy link
Contributor Author

eamsden commented Feb 1, 2019

The idea of a model underlying a widget recurs in GTK, for instance, GtkMenu and GtkMenuBar, as subclasses of GtkMenuShell, can take GMenuModel (defined in the gio lib with a very abstract and opaque concept of actions) as a model, and update themselves in response to changes in the model in a similar way to GtkTreeView with a GtkTreeModel. If we can figure this out on TreeView then I think we will have a good example to work from when implementing other widgets with underlying models.

@owickstrom
Copy link
Owner

Thanks for the proposal! I hope I can get some time this weekend to look more closely at it. 👍

@eamsden
Copy link
Contributor Author

eamsden commented Feb 1, 2019

One subtle thing here is that the widget itself can update the model. Users can drag-and-drop to reorder rows, rows can be editable, etc. We need some way to feed this back into the application state (via events probably) without the changes in the application state immediately triggering another update, causing model inconsistency and infinite loops.

@eamsden
Copy link
Contributor Author

eamsden commented Feb 6, 2019

@owickstrom Have you gotten a chance to look at this more closely? I'd really like to start implementing it.

@owickstrom
Copy link
Owner

owickstrom commented Feb 7, 2019

Hey, sorry it took a while longer.

OK, so in this library I've deliberately not used the concept of models from GTK+. As you say, they effectively implement a bidrectional mutating data flow between the application state and the widgets, and I want gi-gtk-declarative to be unidirectional. The only way for information from the user interface to flow back up to the application logic is through events. (I should document this stuff in some sort of general guidelines for gi-gtk-declarative widget implementation.) I'm not sure I like the "unidirectional" terminology much, but it as at least established in the React world.

When it comes to the TreeView widget, it's likely more complicated than the previously implemented widgets, but can probably be done in a similar way as them. As an example, the Menu widget that's already in this library defines a few data types to model how menus can be built up. It may not cover all features in GTK+ menus (yet), but it fits with the library.

I propose you start by defining such data types for the TreeView widget, and build the Patchable and EventSource instances around that. Also, do leave out drag-and-drop and other advanced features for now, we can always add more events later on. If you do have any TreeView-specific events you want to report up to the user, define a data type for those events and emit them from your subscribe implementation(s).

Does that make sense? Please ask more questions if you have any. I'm glad your here and want to help implement more widget support! 🙂

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

No branches or pull requests

2 participants