GtkSignalListItemFactory

GtkSignalListItemFactory and GtkBulderListItemFactory

GtkBuilderlistItemFactory is convenient when GtkListView just shows the contents of a list. Its binding direction is always from an item of a list to a child of GtkListItem.

When it comes to dynamic connection, it’s not enough. For example, you want to edit the contents of a list. You set a child of GtkListItem to a GtkText instance so a user can edit a text with it. You need to bind an item in the list with the buffer of the GtkText. The direction is opposite from the one with GtkBuilderListItemFactory. It is from the GtkText instance to the item in the list. You can implement this with GtkSignalListItemFactory, which is more flexible than GtkBuilderListItemFactory.

Two things are shown in this section.

This section shows just a part of the source file listeditor.c. If you want to see the whole codes, see src/listeditor directory of the Gtk4 tutorial repository.

A list editor

The sample program is a list editor and data of the list are strings. It’s the same as a line editor. It reads a text file line by line. Each line is an item of the list. The list is displayed with GtkColumnView. There are two columns. The one is a button, which makes the line be a current line. If the line is the current line, the button is colored with red. The other is a string which is the contents of the corresponding item of the list.

List editor

The source files are located at src/listeditor directory. You can compile end execute it as follows.

$ meson _build
$ ninja -C _build
$ _build/listeditor

The current line number (zero-based) is shown at the left of the tool bar. The file name is shown at the right of the write button.

Connect a GtkText instance and an item in the list

The second column (GtkColumnViewColumn) sets its factory property to GtkSignalListItemFactory. It uses three signals setup, bind and unbind. The following is their sgnal handlers.

@@@include listeditor/listeditor.c setup2_cb bind2_cb unbind2_cb @@@

This technique is not so complicated. You can use it when you make a cell editable application.

Change the cell of GtkColumnView dynamically

Next topic is to change the GtkColumnView (or GtkListView) cells dynamically. The example changes the color of the buttons, which are children of GtkListItem instances, as the current line position moves.

The line editor has the current position of the list.

The button of the current line is colored with red and otherwise white.

The current line has no relationship to GtkSingleSelection object. GtkSingleSelection selects a line on the display. The current line doesn’t need to be on the display. It is possible to be on the line out of the Window (GtkScrolledWindow). Actually, the program doesn’t use GtkSingleSelection.

It is necessary to know the corresponding GtkListItem instance from the item in the list. It is the opposite direction from gtk_list_item_get_item function. To accomplish this, we set a listitem element of LeData to point the corresponding GtkListItem instance. Therefore, items (LeData) in the list always know the GtkListItem. If there’s no GtkListItem bound to the item, NULL is assigned.

@@@include listeditor/listeditor.c select_cb setup1_cb bind1_cb unbind1_cb @@@

@@@include listeditor/listeditor.c update_current @@@

The function update_current does several things.

The color of buttons are determined by the “background” CSS style. The following CSS is applied to the default GdkDisplay in advance (in the startup handler of the application).

columnview listview row button.current {background: red;}

The selectors “columnview listview row” is needed before “button” selector. Otherwise the buttons in the GtkColumnview won’t be found. The button selector has “current” class. So, the only “current” class button is colored with red. Other buttons are not colored, which means they are white.

Gtk_widget_dispose_template function

The function gtk_widget_dispose_template clears the template children for the given widget. This is the opposite of gtk_widget_init_template(). It is a new function of GTK 4.8 version. If your GTK version is lower than 4.8, you need to modify the program.

A waring from GtkText

If your program has the following two, a warning message can be issued.

GtkText - unexpected blinking selection. Removing

I don’t have an exact idea why this happens. But if GtkText “focusable” property is FALSE, the warning doesn’t happen. So it probably comes from focus and scroll.

You can avoid this by unsetting any focus widget under the main window. When scroll begins, the “value-changed” signal on the vertical adjustment of the scrolled window is emitted.

The following is extracted from the ui file and C source file.

... ... ...
<object class="GtkScrolledWindow">
  <property name="hexpand">TRUE</property>
  <property name="vexpand">TRUE</property>
  <property name="vadjustment">
    <object class="GtkAdjustment">
      <signal name="value-changed" handler="adjustment_value_changed_cb" swapped="no" object="LeWindow"/>
    </object>
  </property>
... ... ...  

@@@include listeditor/listeditor.c adjustment_value_changed_cb @@@