Commit Graph

59404 Commits

Author SHA1 Message Date
Benjamin Otte
13a6b3c64e gridview: Add factory handling
Just copy the listview APIs.

Code still doesn't do anything with it.
2019-10-15 07:17:31 +02:00
Benjamin Otte
0d2f70bd16 listview: Expose GtkListItemFactory APIs
Due to the many different ways to set factories, it makes sense to
expose them as custom objects.

This makes the actual APIs for the list widgets simpler, because they
can just have a regular "factory" property.

As a convenience function, gtk_list_view_new_with_factory() was added
to make this whole approach easy to use from C.
2019-10-15 07:17:31 +02:00
Benjamin Otte
2158d97800 textview: Make cursor work when blinking is disabled 2019-10-15 07:17:31 +02:00
Benjamin Otte
7ff18b7b5b gtk-demo: Add a rough start at a Weather demo
This demos a horizontal listview.
2019-10-15 07:17:31 +02:00
Benjamin Otte
ed19c3eeee listview: Implement GtkOrientable 2019-10-15 07:17:31 +02:00
Benjamin Otte
c633d01e4f tests: Add a rough form of multiselection
Just store a "filechooser::selected" attribute in the GFileInfo if
the file is meant to be selected.
2019-10-15 07:17:31 +02:00
Benjamin Otte
8b12e8acd4 listview: Implement extending selections
Shift-clicking to extend selections now also works, imitating the
behavior of normal clicking and Windows Explorer (but not treeview):

1. We track the last selected item (normally, not via extend-clicking).

2. When shift-selecting, we modify the range from the last selected item
   to this item the same way we modify the regular item when not using
   shift:

2a. If Ctrl is not pressed, we select the range and unselect everything
    else.

2b. If Ctrl is pressed, we make the range have the same selection state
    as the last selected item:
    - If the last selected item is selected, select the range.
    - If the last selected item is not selected, unselect the range.
2019-10-15 07:17:31 +02:00
Benjamin Otte
1532dff5a8 listview: Add list.scroll_to_item action
The action scrolls the given item into view.

Listitems activate this action when they gain focus.
2019-10-15 07:17:31 +02:00
Benjamin Otte
7666d41a79 testlistview: Load icons async
Speeds up loading by 4x, because out of view icons aren't loaded
anymore.
2019-10-15 07:17:31 +02:00
Benjamin Otte
54bbccf0de directorylist: Add
Adds a new listmodel called GtkDirectoryList that lists the children of
a GFile as GFileInfos.

This is supposed to be used by the filechooser.
2019-10-15 07:17:31 +02:00
Benjamin Otte
5974aaa59b gtk-demo: Introduce awards
We need a way to get a useful listbox, so here we go!
2019-10-15 07:17:31 +02:00
Benjamin Otte
9cb49d23c8 listitemfactory: Add a factory for ui files
Reuse <template> magic to initialize GtkListItems. This feels
amazingly hacky, but it also amazingly worked on the first try.
2019-10-15 07:17:31 +02:00
Benjamin Otte
2301a18987 listitemfactory: Split implementation out
.. into gtkfunctionslistitemfactory.c

Now we can add a different implmenetation.
2019-10-15 07:17:31 +02:00
Benjamin Otte
7fbbdcb2af listitemfactory: vfuncify
No functional changes other than a new indirection.
2019-10-15 07:17:31 +02:00
Benjamin Otte
46165449ef listitemfactory: Sanitize APIs
Make sure the APIs follow a predictable path:

setup
  bind
    rebind/update (0-N times)
  unbind
teardown

This is the first step towards providing multiple different factories.
2019-10-15 07:17:31 +02:00
Benjamin Otte
19be08854f listview: Add gtk_list_view_set_show_separators()
Do the same thing that GtkListBox does in commit
0249bd4f8a
2019-10-15 07:17:31 +02:00
Benjamin Otte
f2e20904f1 listitemmanager: Add trackers
... and replace the anchor tracking with a tracker.

Trackers track an item through the list across changes and ensure that
this item (and potentially siblings before/after it) are always backed
by a GtkListItem and that if the item gets removed a replacement gets
chosen.

This is now used for tracking the anchor but can also be used to add
trackers for the cursor later.
2019-10-15 07:17:31 +02:00
Benjamin Otte
95e462e181 listitemmanager: Simplify
Remove a bunch of API from the headers that isn't used anymore and then
refactor code to not call it anymore.

In particular, get rid of GtkListItemManagerChange and replace it with a
GHashTable.
2019-10-15 07:17:31 +02:00
Benjamin Otte
2a54786be8 gridview: Implement GtkScrollable
We can now scroll all the nothing we display.

We also clip it properly.
2019-10-15 07:17:31 +02:00
Benjamin Otte
9c55ac513c listitemmanager: Move list of listitems here
All the listview infrastructure moved with it, so the next step is
moving that back...
2019-10-15 07:17:31 +02:00
Benjamin Otte
1f1f5e2aed wayland: Remove function declaration for nonexisting function 2019-10-15 07:17:31 +02:00
Benjamin Otte
18a03fa043 gridview: Add API for setting number of columns
The API isn't used yet.
2019-10-15 07:17:31 +02:00
Benjamin Otte
a0e4be18a0 gtk: Add a GtkGridView skeleton 2019-10-15 07:17:30 +02:00
Benjamin Otte
30a471bc31 listitem: Add a press gesture to select the item
This is implemented by using actions, which are a neat trick to get to
allow the ListItem to call functions on the ListView without actually
needing to be aware of it.
2019-10-15 07:17:30 +02:00
Benjamin Otte
7346d69217 listview: Add initial support for displaying selections 2019-10-15 07:17:30 +02:00
Benjamin Otte
0a85576377 listview: Reset listitems' CSS animations when rebinding
This way, newly displayed rows don't play an unselect animation (text
fading in) when they are unselected, but the row was previously used for
a selected item.
2019-10-15 07:17:30 +02:00
Benjamin Otte
ca6aa9e549 listview: Add selection properties to ListItem
This just brings the infrastructure into place, we're not using the
properties yet.
2019-10-15 07:17:30 +02:00
Benjamin Otte
97db41c8a0 listview: Try to keep the list items in order when scrolling
Instead of just destroying all items and then recreating them (or even
hide()ing and then show()ing them again (or even even repositioning
them in the widget tree)), just try to reust them in the order they are.

This works surprisingly well when scrolling and most/all widgets
just moved.
2019-10-15 07:17:30 +02:00
Benjamin Otte
41815d3d26 listlistmodel: Add gtk_list_list_model_item_moved()
Use it to fix a case that just said g_warning ("oops").

Apparently I had forgotten the case where a container moved a child
in the widget tree.
2019-10-15 07:17:30 +02:00
Benjamin Otte
c60b4fd031 listitemmanager: Switch from "insert_before" to "insert_after" argumnet
We reorder widgets start to end, so when reusing a list item, we
correctly know the previous sibling for that list item, but not the
next sibling yet. We just know the widget it should ultimately be in
front of.
So we can do a more correct guess of the list item's place in the widget
tree if we think about where to place an item like this.

Actually using this change will come in the next commit.
2019-10-15 07:17:30 +02:00
Benjamin Otte
d227a713ed testlistview: Create widgets only once
Previously, we were recreating all widgets every time the list item was
rebound, which caused a lot of extra work every time we scrolled.

Now we keep the widgets around and only set their properties again when
the item changes.
2019-10-15 07:17:30 +02:00
Benjamin Otte
112c5aa1ff testlistview: Show the row number
Always show the current row. This is mostly useful for debugging, not
for beauty.
2019-10-15 07:17:30 +02:00
Benjamin Otte
88f43cdff8 listview: Only allocate necesary rows
This is the big one.

The listview only allocates 200 rows around the visible row now.
Everything else is kept in ListRow instances with row->widget == NULL.

For rows without a widget, we assign the median height of the child
widgets as the row's height and then do all calculations as if there
were widgets that had requested that height (like setting adjustment
values or reacting to adjustment value changes).

When the view is scrolled, we bind the 200 rows to the new visible area,
so that the part of the listview that can be seen is always allocated.
2019-10-15 07:17:30 +02:00
Benjamin Otte
e90758a43f listview: Change anchor handling again
The anchor is now a tuple of { listitem, align }.

Using the actual list item allows keeping the anchor across changes
in position (ie when lists get resorted) while still being able to fall
back to positions (list items store their position) when an item gets
removed.

The align value is in the range [0..1] and defines where in the visible
area to do the alignment.
0.0 means to align the top of the row with the top of the visible area,
1.0 aligns the bottom of the widget with the visible area and 0.5 keeps
the center of the widget at the center of the visible area.
It works conceptually the same as percentages in CSS background-position
(where the background area and the background image's size are matched
the same way) or CSS transform-origin.
2019-10-15 07:17:30 +02:00
Benjamin Otte
b2a6938805 listview: Change how binding is done
We now don't let the functions create widgets for the item from the
listmodel, instead we hand out a GtkListItem for them to add a widget
to.

GtkListItems are created in advance and can only be filled in by the
binding code by gtk_container_add()ing a widget.
However, they are GObjects, so they can provide properties that the
binding code can make use of - either via notify signals or GBinding.
2019-10-15 07:17:30 +02:00
Benjamin Otte
bc61ad4bc4 listitem: Add gtk_list_item_get_position()
Also refactor the whole list item management yet again.

Now, list item APIs doesn't have bind/unbind functions anymore, but only
property setters.

The item factory is the only one doing the binding.
As before, the item manager manages when items need to be bound.
2019-10-15 07:17:30 +02:00
Benjamin Otte
f967055224 tests: Make animating listview do random resorts 2019-10-15 07:17:30 +02:00
Benjamin Otte
c387f76e64 listview: Change change management
Add a GtkListItemManagerChange object that tracks all removed list
rows during an item-changed signal so they can be added back later.
2019-10-15 07:17:30 +02:00
Benjamin Otte
c22a6d355f listview: Make the listitemmanager stricter
Require that items created with the manager get destroyed via the
manager.

To that purpose, renamed create_list_item() to acquire_list_item() and
add a matching release_list_item() function.

This way, the manager can in the future keep track of all items and
cache information about them.
2019-10-15 07:17:30 +02:00
Benjamin Otte
a6a93ba340 listview: Add GtkListItem
GtkListItem is a generic row widget that is supposed to replace
GtkListBoxRow and GtkFlowBoxChild.
2019-10-15 07:17:30 +02:00
Benjamin Otte
f32c010904 listview: Add GtkListItemManager
It's all stubs for now, but here's the basic ideas about what
this object is supposed to do:

(1) It's supposed to be handling all the child GtkWidgets that are
    used by the listview, so that the listview can concern
    itself with how many items it needs and where to put them.
(2) It's meant to do the caching of widgets that are not (currently)
    used.
(3) It's meant to track items that remain in the model across
    items-changed emissions and just change position.
(2) It's code that can be shared between listview and potential
    other widgets like a GridView.

It's also free to assume that the number of items it's supposed to
manage doesn't grow too much, so it's free to use O(N) algorithms.
2019-10-15 07:17:30 +02:00
Benjamin Otte
e72eb6c302 listview: Implement an anchor
The anchor selection is very basic: just anchor the top row.

That's vastly better than any other widget already though.
2019-10-15 07:17:30 +02:00
Benjamin Otte
4d19b7d612 tests: Add a test for a permanently changing listview
This is mostly for dealing with proper anchoring and can be used to
check that things don't scroll or that selection and focus handling
properly works.

For comparison purposes, a ListBox is provided next to it.
2019-10-15 07:17:30 +02:00
Benjamin Otte
42b04251d5 listview: Implement GtkScrollable
Scrolling in a very basic form is also supported
2019-10-15 07:17:30 +02:00
Benjamin Otte
a53afb694d listview: Make widget actually do something
The thing we're actually doing is create and maintain a widget for every
row. That's it.

Also add a testcase using this. The testcase quickly allocates too many
rows though and then becomes unresponsive though. You have been warned.
2019-10-15 07:17:30 +02:00
Benjamin Otte
477fa48557 listview: Introduce GtkListItemFactory
Thisis the abstraction I intend to use for creating widgets and binding
them to the item out of the listview.

For now this is a very dumb wrapper around the functions that exist in
the API.

But it leaves the freedom to turn this into public API, make an
interface out of it and most of all write different implementations, in
particular one that uses GtkBuilder.
2019-10-15 07:17:30 +02:00
Benjamin Otte
389eb0de56 gtk: Add a GtkListView skeleton 2019-10-15 07:17:30 +02:00
Benjamin Otte
a1a70a1130 bindings: Add gtk_binding_entry_add_callback()
This allows bindings that have no public API.
2019-10-15 07:17:30 +02:00
Benjamin Otte
19304c1d2c bindings: Add gtk_binding_entry_add_action()
Allows registering bindings for activating widget actions, as an
alternative to signal emissions.
2019-10-15 07:17:30 +02:00
Benjamin Otte
01be7f0666 widget: Make gtk_widget_activate_action() return TRUE/FALSE
TRUE if an action was successfully activated, FALSE if it wasn't found.
2019-10-15 07:17:30 +02:00