mirror of
https://github.com/ToshioCP/Gtk4-tutorial.git
synced 2025-01-12 20:03:28 +01:00
Update gfm files of the section 16-30.
This commit is contained in:
parent
e0897922ce
commit
c84cffd8ef
5 changed files with 961 additions and 875 deletions
194
gfm/sec26.md
194
gfm/sec26.md
|
@ -3,29 +3,29 @@ Up: [README.md](../README.md), Prev: [Section 25](sec25.md), Next: [Section 27]
|
||||||
# GtkListView
|
# GtkListView
|
||||||
|
|
||||||
GTK 4 has added new list objects GtkListView, GtkGridView and GtkColumnView.
|
GTK 4 has added new list objects GtkListView, GtkGridView and GtkColumnView.
|
||||||
The new feature is described in [Gtk API Reference, List Widget Overview](https://docs.gtk.org/gtk4/section-list-widget.html).
|
The new feature is described in [Gtk API Reference -- List Widget Overview](https://docs.gtk.org/gtk4/section-list-widget.html).
|
||||||
|
|
||||||
GTK 4 has other means to implement lists.
|
GTK 4 has other means to implement lists.
|
||||||
They are GtkListBox and GtkTreeView which are took over from GTK 3.
|
They are GtkListBox and GtkTreeView which are took over from GTK 3.
|
||||||
There's an article in [Gtk Development blog](https://blog.gtk.org/2020/06/07/scalable-lists-in-gtk-4/) about list widgets by Matthias Clasen.
|
There's an article in [Gtk Development blog](https://blog.gtk.org/2020/06/07/scalable-lists-in-gtk-4/) about list widgets by Matthias Clasen.
|
||||||
He described why GtkListView are developed to replace GtkListBox and GtkTreeView.
|
He described why GtkListView are developed to replace GtkListBox and GtkTreeView.
|
||||||
|
|
||||||
I want to explain GtkListView and its related objects in this tutorial.
|
GtkListView, GtkGridView, GtkColumnView and related objects are described in Section 26 to 29.
|
||||||
|
|
||||||
## Outline
|
## Outline
|
||||||
|
|
||||||
A list is a sequential data structure.
|
A list is a sequential data structure.
|
||||||
For example, an ordered string sequence "one", "two", "three", "four" is a list.
|
For example, an ordered string sequence "one", "two", "three", "four" is a list.
|
||||||
Each element of the list is called item.
|
Each element is called item.
|
||||||
A list is like an array, but in many cases it is implemented with pointers which point to the next item of the list.
|
A list is like an array, but in many cases it is implemented with pointers which point to the next items of the list.
|
||||||
And it has a start point.
|
And it has a start point.
|
||||||
So, each item can be referred by the index of the item (first item, second item, ..., nth item, ...).
|
So, each item can be referred by the index of the item (first item, second item, ..., nth item, ...).
|
||||||
There are two cases.
|
There are two cases.
|
||||||
One is the index starts from one (one-based) and the other is it starts from zero (zero-based).
|
One is the index starts from one (one-based) and the other is from zero (zero-based).
|
||||||
|
|
||||||
Gio provides GListModel interface.
|
Gio provides GListModel interface.
|
||||||
It is a zero-based list of the same type of GObject objects, or objects that implement the same interface.
|
It is a zero-based list of the same type of GObject descendants, or objects that implement the same interface.
|
||||||
An object implements GListModel is usually not a widget.
|
An object implements GListModel is not a widget.
|
||||||
So, the list is not displayed on the screen directly.
|
So, the list is not displayed on the screen directly.
|
||||||
There's another object GtkListView which is a widget to display the list.
|
There's another object GtkListView which is a widget to display the list.
|
||||||
The items in the list need to be connected to the items in GtkListView.
|
The items in the list need to be connected to the items in GtkListView.
|
||||||
|
@ -33,16 +33,11 @@ GtkListItemFactory object maps items in the list to GListView.
|
||||||
|
|
||||||
![List](../image/list.png)
|
![List](../image/list.png)
|
||||||
|
|
||||||
The instruction to build the whole list related objects is:
|
|
||||||
|
|
||||||
1. Implement the list object which implements GListModel.
|
|
||||||
2. Build widgets and put GtkListView as a child of GtkScrolledWindow.
|
|
||||||
3. Set GtkListItemFactory.
|
|
||||||
|
|
||||||
## GListModel
|
## GListModel
|
||||||
|
|
||||||
If you want to make a list of strings with GListModel, for example, "one", "two", "three", "four", note that strings can't be items of the list.
|
If you want to make a list of strings with GListModel, for example, "one", "two", "three", "four", note that strings can't be items of the list.
|
||||||
Because GListModel is a list of GObject objects and strings aren't GObject objects.
|
Because GListModel is a list of GObject objects and strings aren't GObject objects.
|
||||||
|
The word "GObject" here means "GObject class or its descendant class".
|
||||||
So, you need a wrapper which is a GObject and contains a string.
|
So, you need a wrapper which is a GObject and contains a string.
|
||||||
GtkStringObject is the wrapper object and GStringList, implements GListModel, is a list of GtkStringObject.
|
GtkStringObject is the wrapper object and GStringList, implements GListModel, is a list of GtkStringObject.
|
||||||
|
|
||||||
|
@ -51,7 +46,7 @@ char *array[] = {"one", "two", "three", "four", NULL};
|
||||||
GtkStringList *stringlist = gtk_string_list_new ((const char * const *) array);
|
GtkStringList *stringlist = gtk_string_list_new ((const char * const *) array);
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
The function `gtk_string_list_new` creates GtkStringList object.
|
The function `gtk_string_list_new` creates a GtkStringList object.
|
||||||
Its items are GtkStringObject objects which contain the strings "one", "two", "three" and "four".
|
Its items are GtkStringObject objects which contain the strings "one", "two", "three" and "four".
|
||||||
There are functions to add items to the list or remove items from the list.
|
There are functions to add items to the list or remove items from the list.
|
||||||
|
|
||||||
|
@ -59,9 +54,9 @@ There are functions to add items to the list or remove items from the list.
|
||||||
- `gtk_string_list_remove` removes an item from the list
|
- `gtk_string_list_remove` removes an item from the list
|
||||||
- `gtk_string_list_get_string` gets a string in the list
|
- `gtk_string_list_get_string` gets a string in the list
|
||||||
|
|
||||||
See [GTK 4 API Reference, GtkStringList](https://docs.gtk.org/gtk4/class.StringList.html) for further information.
|
See [GTK 4 API Reference -- GtkStringList](https://docs.gtk.org/gtk4/class.StringList.html) for further information.
|
||||||
|
|
||||||
I'll explain the other list objects later.
|
Other list objects will be explained later.
|
||||||
|
|
||||||
## GtkSelectionModel
|
## GtkSelectionModel
|
||||||
|
|
||||||
|
@ -101,7 +96,7 @@ There are four signals.
|
||||||
|
|
||||||
1. "setup" is emitted to set up GtkListItem object.
|
1. "setup" is emitted to set up GtkListItem object.
|
||||||
A user sets its child widget in the handler.
|
A user sets its child widget in the handler.
|
||||||
For example, creates a GtkLabel widget and sets the child property of GtkListItem to it.
|
For example, creates a GtkLabel widget and sets the child property of GtkListItem with it.
|
||||||
This setting is kept even the GtkListItem instance is recycled (to bind to another item of GListModel).
|
This setting is kept even the GtkListItem instance is recycled (to bind to another item of GListModel).
|
||||||
2. "bind" is emitted to bind an item in the list model to the widget.
|
2. "bind" is emitted to bind an item in the list model to the widget.
|
||||||
For example, a user gets the item from "item" property of the GtkListItem instance.
|
For example, a user gets the item from "item" property of the GtkListItem instance.
|
||||||
|
@ -121,7 +116,7 @@ GtkNoSelection is used, so user can't select any item.
|
||||||
1 #include <gtk/gtk.h>
|
1 #include <gtk/gtk.h>
|
||||||
2
|
2
|
||||||
3 static void
|
3 static void
|
||||||
4 setup_cb (GtkListItemFactory *factory, GtkListItem *listitem, gpointer user_data) {
|
4 setup_cb (GtkSignalListItemFactory *self, GtkListItem *listitem, gpointer user_data) {
|
||||||
5 GtkWidget *lb = gtk_label_new (NULL);
|
5 GtkWidget *lb = gtk_label_new (NULL);
|
||||||
6 gtk_list_item_set_child (listitem, lb);
|
6 gtk_list_item_set_child (listitem, lb);
|
||||||
7 }
|
7 }
|
||||||
|
@ -129,38 +124,38 @@ GtkNoSelection is used, so user can't select any item.
|
||||||
9 static void
|
9 static void
|
||||||
10 bind_cb (GtkSignalListItemFactory *self, GtkListItem *listitem, gpointer user_data) {
|
10 bind_cb (GtkSignalListItemFactory *self, GtkListItem *listitem, gpointer user_data) {
|
||||||
11 GtkWidget *lb = gtk_list_item_get_child (listitem);
|
11 GtkWidget *lb = gtk_list_item_get_child (listitem);
|
||||||
12 GtkStringObject *strobj = gtk_list_item_get_item (listitem);
|
12 /* Strobj is owned by the instance. Caller mustn't change or destroy it. */
|
||||||
13 const char *text = gtk_string_object_get_string (strobj);
|
13 GtkStringObject *strobj = gtk_list_item_get_item (listitem);
|
||||||
14
|
14 const char *text = gtk_string_object_get_string (strobj);
|
||||||
15 gtk_label_set_text (GTK_LABEL (lb), text);
|
15
|
||||||
16 }
|
16 gtk_label_set_text (GTK_LABEL (lb), text);
|
||||||
17
|
17 }
|
||||||
18 static void
|
18
|
||||||
19 unbind_cb (GtkSignalListItemFactory *self, GtkListItem *listitem, gpointer user_data) {
|
19 static void
|
||||||
20 /* There's nothing to do here. */
|
20 unbind_cb (GtkSignalListItemFactory *self, GtkListItem *listitem, gpointer user_data) {
|
||||||
21 /* If you does something like setting a signal in bind_cb, */
|
21 /* There's nothing to do here. */
|
||||||
22 /* then disconnecting the signal is necessary in unbind_cb. */
|
22 }
|
||||||
23 }
|
23
|
||||||
24
|
24 static void
|
||||||
25 static void
|
25 teardown_cb (GtkSignalListItemFactory *self, GtkListItem *listitem, gpointer user_data) {
|
||||||
26 teardown_cb (GtkListItemFactory *factory, GtkListItem *listitem, gpointer user_data) {
|
26 gtk_list_item_set_child (listitem, NULL);
|
||||||
27 gtk_list_item_set_child (listitem, NULL);
|
27 /* The previous child is destroyed automatically. */
|
||||||
28 /* When the child of listitem is set to NULL, the reference to GtkLabel will be released and lb will be destroyed. */
|
28 }
|
||||||
29 /* Therefore, g_object_unref () for the GtkLabel object doesn't need in the user code. */
|
29
|
||||||
30 }
|
30 static void
|
||||||
31
|
31 app_activate (GApplication *application) {
|
||||||
32 /* ----- activate, open, startup handlers ----- */
|
32 GtkApplication *app = GTK_APPLICATION (application);
|
||||||
33 static void
|
33 GtkWidget *win = gtk_application_window_new (app);
|
||||||
34 app_activate (GApplication *application) {
|
34 gtk_window_set_default_size (GTK_WINDOW (win), 600, 400);
|
||||||
35 GtkApplication *app = GTK_APPLICATION (application);
|
35 GtkWidget *scr = gtk_scrolled_window_new ();
|
||||||
36 GtkWidget *win = gtk_application_window_new (app);
|
36 gtk_window_set_child (GTK_WINDOW (win), scr);
|
||||||
37 gtk_window_set_default_size (GTK_WINDOW (win), 600, 400);
|
37
|
||||||
38 GtkWidget *scr = gtk_scrolled_window_new ();
|
38 char *array[] = {
|
||||||
39 gtk_window_set_child (GTK_WINDOW (win), scr);
|
39 "one", "two", "three", "four", NULL
|
||||||
40
|
40 };
|
||||||
41 char *array[] = {
|
41 /* sl is owned by ns */
|
||||||
42 "one", "two", "three", "four", NULL
|
42 /* ns and factory are owned by lv. */
|
||||||
43 };
|
43 /* Therefore, you don't need to care about their destruction. */
|
||||||
44 GtkStringList *sl = gtk_string_list_new ((const char * const *) array);
|
44 GtkStringList *sl = gtk_string_list_new ((const char * const *) array);
|
||||||
45 GtkNoSelection *ns = gtk_no_selection_new (G_LIST_MODEL (sl));
|
45 GtkNoSelection *ns = gtk_no_selection_new (G_LIST_MODEL (sl));
|
||||||
46
|
46
|
||||||
|
@ -175,34 +170,26 @@ GtkNoSelection is used, so user can't select any item.
|
||||||
55 gtk_window_present (GTK_WINDOW (win));
|
55 gtk_window_present (GTK_WINDOW (win));
|
||||||
56 }
|
56 }
|
||||||
57
|
57
|
||||||
58 static void
|
58 /* ----- main ----- */
|
||||||
59 app_startup (GApplication *application) {
|
59 #define APPLICATION_ID "com.github.ToshioCP.list1"
|
||||||
60 }
|
60
|
||||||
61
|
61 int
|
||||||
62 /* ----- main ----- */
|
62 main (int argc, char **argv) {
|
||||||
63 #define APPLICATION_ID "com.github.ToshioCP.list1"
|
63 GtkApplication *app;
|
||||||
64
|
64 int stat;
|
||||||
65 int
|
65
|
||||||
66 main (int argc, char **argv) {
|
66 app = gtk_application_new (APPLICATION_ID, G_APPLICATION_DEFAULT_FLAGS);
|
||||||
67 GtkApplication *app;
|
67
|
||||||
68 int stat;
|
68 g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
|
||||||
69
|
69
|
||||||
70 app = gtk_application_new (APPLICATION_ID, G_APPLICATION_DEFAULT_FLAGS);
|
70 stat =g_application_run (G_APPLICATION (app), argc, argv);
|
||||||
71
|
71 g_object_unref (app);
|
||||||
72 g_signal_connect (app, "startup", G_CALLBACK (app_startup), NULL);
|
72 return stat;
|
||||||
73 g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
|
73 }
|
||||||
74
|
|
||||||
75 stat =g_application_run (G_APPLICATION (app), argc, argv);
|
|
||||||
76 g_object_unref (app);
|
|
||||||
77 return stat;
|
|
||||||
78 }
|
|
||||||
79
|
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
The file `list1.c` is located under the directory [src/misc](../src/misc).
|
The file `list1.c` is located under the directory [src/misc](../src/misc).
|
||||||
Make a shell script below and save it to your bin directory.
|
Make a shell script below and save it to your bin directory, for example `$HOME/bin`.
|
||||||
(If you've installed GTK 4 from the source to $HOME/local, then your bin directory is $Home/local/bin.
|
|
||||||
Otherwise, $Home/bin is your private bin directory.)
|
|
||||||
|
|
||||||
~~~Shell
|
~~~Shell
|
||||||
gcc `pkg-config --cflags gtk4` $1.c `pkg-config --libs gtk4`
|
gcc `pkg-config --cflags gtk4` $1.c `pkg-config --libs gtk4`
|
||||||
|
@ -211,16 +198,16 @@ gcc `pkg-config --cflags gtk4` $1.c `pkg-config --libs gtk4`
|
||||||
Change the current directory to the directory includes `list1.c` and type as follows.
|
Change the current directory to the directory includes `list1.c` and type as follows.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
$ chmod 755 $HOME/local/bin/comp # or chmod 755 $Home/bin/comp
|
$ chmod 755 $HOME/bin/comp # or chmod 755 (your bin directory)/comp
|
||||||
$ comp list1
|
$ comp list1
|
||||||
$ ./a.out
|
$ ./a.out
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
Then, `list1.c` has been compiled and executed.
|
Then, the following window appears.
|
||||||
|
|
||||||
![list1](../image/list1.png)
|
![list1](../image/list1.png)
|
||||||
|
|
||||||
I think the program is not so difficult.
|
The program is not so difficult.
|
||||||
If you feel some difficulty, read this section again, especially GtkSignalListItemFactory subsubsection.
|
If you feel some difficulty, read this section again, especially GtkSignalListItemFactory subsubsection.
|
||||||
|
|
||||||
### GtkBuilderListItemFactory
|
### GtkBuilderListItemFactory
|
||||||
|
@ -311,28 +298,23 @@ Its name is `list2.c` and located under [src/misc](../src/misc) directory.
|
||||||
38 gtk_window_present (GTK_WINDOW (win));
|
38 gtk_window_present (GTK_WINDOW (win));
|
||||||
39 }
|
39 }
|
||||||
40
|
40
|
||||||
41 static void
|
41 /* ----- main ----- */
|
||||||
42 app_startup (GApplication *application) {
|
42 #define APPLICATION_ID "com.github.ToshioCP.list2"
|
||||||
43 }
|
43
|
||||||
44
|
44 int
|
||||||
45 /* ----- main ----- */
|
45 main (int argc, char **argv) {
|
||||||
46 #define APPLICATION_ID "com.github.ToshioCP.list2"
|
46 GtkApplication *app;
|
||||||
47
|
47 int stat;
|
||||||
48 int
|
48
|
||||||
49 main (int argc, char **argv) {
|
49 app = gtk_application_new (APPLICATION_ID, G_APPLICATION_DEFAULT_FLAGS);
|
||||||
50 GtkApplication *app;
|
50
|
||||||
51 int stat;
|
51 g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
|
||||||
52
|
52
|
||||||
53 app = gtk_application_new (APPLICATION_ID, G_APPLICATION_DEFAULT_FLAGS);
|
53 stat =g_application_run (G_APPLICATION (app), argc, argv);
|
||||||
54
|
54 g_object_unref (app);
|
||||||
55 g_signal_connect (app, "startup", G_CALLBACK (app_startup), NULL);
|
55 return stat;
|
||||||
56 g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
|
56 }
|
||||||
57
|
57
|
||||||
58 stat =g_application_run (G_APPLICATION (app), argc, argv);
|
|
||||||
59 g_object_unref (app);
|
|
||||||
60 return stat;
|
|
||||||
61 }
|
|
||||||
62
|
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
No signal handler is needed for GtkBulderListItemFactory.
|
No signal handler is needed for GtkBulderListItemFactory.
|
||||||
|
@ -382,7 +364,7 @@ Instead, closure tag is appropriate in this case.
|
||||||
Closure tag specifies a function and the type of the return value of the function.
|
Closure tag specifies a function and the type of the return value of the function.
|
||||||
|
|
||||||
~~~C
|
~~~C
|
||||||
char *
|
const char *
|
||||||
get_file_name (GtkListItem *item, GFileInfo *info) {
|
get_file_name (GtkListItem *item, GFileInfo *info) {
|
||||||
if (! G_IS_FILE_INFO (info))
|
if (! G_IS_FILE_INFO (info))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -408,23 +390,26 @@ get_file_name (GtkListItem *item, GFileInfo *info) {
|
||||||
"</interface>"
|
"</interface>"
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
- "gchararray" is the type name of strings.
|
- The string "gchararray" is the type name of strings.
|
||||||
"gchar" is the same as "char" type.
|
The type "gchar" is the same as "char".
|
||||||
Therefore, "gchararray" is "an array of char type", which is the same as string type.
|
Therefore, "gchararray" is "an array of char type", which is the same as string type.
|
||||||
It is used to get the type of GValue object.
|
It is used to get the type of GValue object.
|
||||||
GValue is a generic value and it can contain various type of values.
|
GValue is a generic value and it can contain various type of values.
|
||||||
For example, the type name can be gboolean, gchar (char), gint (int), gfloat (float), gdouble (double), gchararray (char *) and so on.
|
For example, the type name can be gboolean, gchar (char), gint (int), gfloat (float), gdouble (double), gchararray (char *) and so on.
|
||||||
These type names are the names of the fundamental types that are registered to the type system.
|
These type names are the names of the fundamental types that are registered to the type system.
|
||||||
See [GObject tutorial](https://github.com/ToshioCP/Gobject-tutorial/blob/main/gfm/sec5.md#gvalue).
|
See [GObject tutorial](https://github.com/ToshioCP/Gobject-tutorial/blob/main/gfm/sec5.md#gvalue).
|
||||||
- closure tag has type attribute and function attribute.
|
- Closure tag has type attribute and function attribute.
|
||||||
Function attribute specifies the function name and type attribute specifies the type of the return value of the function.
|
Function attribute specifies the function name and type attribute specifies the type of the return value of the function.
|
||||||
The contents of closure tag (it is between \<closure...\> and\</closure\>) is parameters of the function.
|
The contents of closure tag (it is between \<closure...\> and\</closure\>) is parameters of the function.
|
||||||
`<lookup name="item">GtkListItem</lookup>` gives the value of the item property of the GtkListItem.
|
`<lookup name="item">GtkListItem</lookup>` gives the value of the item property of the GtkListItem.
|
||||||
This will be the second argument of the function.
|
This will be the second argument of the function.
|
||||||
The first parameter is always the GListItem instance.
|
The first parameter is always the GListItem instance.
|
||||||
- `gtk_file_name` function first check the `info` parameter.
|
- `gtk_file_name` function first checks the `info` parameter.
|
||||||
Because it can be NULL when GListItem `item` is unbound.
|
Because it can be NULL when GListItem `item` is unbounded.
|
||||||
If its GFileInfo, then return the filename (copy of the filename).
|
If it's GFileInfo, it returns the filename.
|
||||||
|
The filename is owned by GFileInfo object.
|
||||||
|
So, the function `get_file_name` duplicates the string to own the newly created one.
|
||||||
|
Closure tag binds the property of the outer tag (GtkLabel) to the filename.
|
||||||
|
|
||||||
The whole program (`list3.c`) is as follows.
|
The whole program (`list3.c`) is as follows.
|
||||||
The program is located in [src/misc](../src/misc) directory.
|
The program is located in [src/misc](../src/misc) directory.
|
||||||
|
@ -498,7 +483,6 @@ The program is located in [src/misc](../src/misc) directory.
|
||||||
66 g_object_unref (app);
|
66 g_object_unref (app);
|
||||||
67 return stat;
|
67 return stat;
|
||||||
68 }
|
68 }
|
||||||
69
|
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
The ui data (xml data above) is used to build the GListItem template at runtime.
|
The ui data (xml data above) is used to build the GListItem template at runtime.
|
||||||
|
|
170
gfm/sec27.md
170
gfm/sec27.md
|
@ -7,7 +7,7 @@ It displays a GListModel as a grid, which is like a square tessellation.
|
||||||
|
|
||||||
![Grid](../image/list4.png)
|
![Grid](../image/list4.png)
|
||||||
|
|
||||||
This is often seen when you use a file browser like nautilus.
|
This is often seen when you use a file browser like GNOME Files (Nautilus).
|
||||||
|
|
||||||
In this section, let's make a very simple file browser `list4`.
|
In this section, let's make a very simple file browser `list4`.
|
||||||
It just shows the files in the current directory.
|
It just shows the files in the current directory.
|
||||||
|
@ -32,9 +32,7 @@ GtkGridView (model property) => GtkSingleSelection (model property) => GtkDirect
|
||||||
|
|
||||||
![DirectoryList](../image/directorylist.png)
|
![DirectoryList](../image/directorylist.png)
|
||||||
|
|
||||||
The following is the part of the ui file `list4.ui`.
|
The following is a part of the ui file `list4.ui`.
|
||||||
It defines GtkListView, GtkSingleSelection and GtkDirectoryList.
|
|
||||||
It also defines GtkGridView and GtkSingleSelection.
|
|
||||||
|
|
||||||
~~~xml
|
~~~xml
|
||||||
<object class="GtkListView" id="list">
|
<object class="GtkListView" id="list">
|
||||||
|
@ -59,20 +57,19 @@ It is attributes of GFileInfo such as "standard::name", "standard::icon" and "st
|
||||||
- standard::name is a filename.
|
- standard::name is a filename.
|
||||||
- standard::icon is an icon of the file. It is a GIcon object.
|
- standard::icon is an icon of the file. It is a GIcon object.
|
||||||
- standard::content-type is a content-type.
|
- standard::content-type is a content-type.
|
||||||
Content-type is the same as mime type for the internet technology.
|
Content-type is the same as mime type for the internet.
|
||||||
For example, "text/plain" is a text file, "text/x-csrc" is a C source code and so on.
|
For example, "text/plain" is a text file, "text/x-csrc" is a C source code and so on.
|
||||||
("text/x-csrc"is not registered to IANA media types.
|
("text/x-csrc"is not registered to IANA media types.
|
||||||
Such "x-" subtype is not a standard mime type.)
|
Such "x-" subtype is not a standard mime type.)
|
||||||
Content type is also used by the desktop system.
|
Content type is also used by desktop systems.
|
||||||
|
|
||||||
GtkGridView has the same structure as GtkListView.
|
GtkGridView uses the same GtkSingleSelection instance (`singleselection`).
|
||||||
But it is enough to specify its model property to `singleselection` which is the identification of the GtkSingleSelection.
|
So, its model property is set with it.
|
||||||
Therefore the description for GtkGridView is very short.
|
|
||||||
|
|
||||||
## Ui file of the window
|
## Ui file of the window
|
||||||
|
|
||||||
Look at the screenshot of `list4` at the top of this section.
|
The window is built with the following ui file.
|
||||||
The widgets are built with the following ui file.
|
(See the screenshot at the beginning of this section).
|
||||||
|
|
||||||
~~~xml
|
~~~xml
|
||||||
1 <?xml version="1.0" encoding="UTF-8"?>
|
1 <?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
@ -136,7 +133,7 @@ The widgets are built with the following ui file.
|
||||||
59 <property name="model">
|
59 <property name="model">
|
||||||
60 <object class="GtkSingleSelection" id="singleselection">
|
60 <object class="GtkSingleSelection" id="singleselection">
|
||||||
61 <property name="model">
|
61 <property name="model">
|
||||||
62 <object class="GtkDirectoryList" id="directorylist">
|
62 <object class="GtkDirectoryList" id="directory_list">
|
||||||
63 <property name="attributes">standard::name,standard::icon,standard::content-type</property>
|
63 <property name="attributes">standard::name,standard::icon,standard::content-type</property>
|
||||||
64 </object>
|
64 </object>
|
||||||
65 </property>
|
65 </property>
|
||||||
|
@ -151,25 +148,24 @@ The widgets are built with the following ui file.
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
The file consists of two parts.
|
The file consists of two parts.
|
||||||
The first part begins at the third line and ends at the 57th line.
|
The first part begins at the line 3 and ends at line 57.
|
||||||
This part is the widgets from the top level window to the scrolled window.
|
This part is the widgets from the top level window to the scrolled window.
|
||||||
It also includes two buttons.
|
It also includes two buttons.
|
||||||
The second part begins at the 58th line and ends at the 71st line.
|
The second part begins at line 58 and ends at line 71.
|
||||||
This is the part of GtkListView and GtkGridView.
|
This is the part of GtkListView and GtkGridView.
|
||||||
They are described in the previous section.
|
|
||||||
|
|
||||||
- 13-17, 42-46: Two labels are dummy labels.
|
- 13-17, 42-46: Two labels are dummy labels.
|
||||||
They just work as a space to put the two buttons at the appropriate position.
|
They just work as a space to put the two buttons at the appropriate position.
|
||||||
- 19-41: GtkButton `btnlist` and `btngrid`.
|
- 18-41: GtkButton `btnlist` and `btngrid`.
|
||||||
These two buttons work as selection buttons to switch from list to grid and vice versa.
|
These two buttons work as selection buttons to switch from list to grid and vice versa.
|
||||||
These two buttons are connected to a stateful action `win.view`.
|
These two buttons are connected to a stateful action `win.view`.
|
||||||
This action is stateful and has a parameter.
|
This action has a parameter.
|
||||||
Such action consists of prefix, action name and parameter.
|
Such action consists of prefix, action name and parameter.
|
||||||
The prefix of the action is `win`, which means the action belongs to the top level window.
|
The prefix of the action is `win`, which means the action belongs to the top level window.
|
||||||
So, a prefix gives the scope of the action.
|
The prefix gives the scope of the action.
|
||||||
The action name is `view`.
|
The action name is `view`.
|
||||||
The parameters are `list` or `grid`, which show the state of the action.
|
The parameters are `list` or `grid`, which show the state of the action.
|
||||||
A parameter is also called a target, because it is a target to which the buttons are clicked on to change the action state.
|
A parameter is also called a target, because it is a target to which the action changes its state.
|
||||||
We often write the detailed action like "win.view::list" or "win.view::grid".
|
We often write the detailed action like "win.view::list" or "win.view::grid".
|
||||||
- 21-22: The properties "action-name" and "action-target" belong to GtkActionable interface.
|
- 21-22: The properties "action-name" and "action-target" belong to GtkActionable interface.
|
||||||
GtkButton implements GtkActionable.
|
GtkButton implements GtkActionable.
|
||||||
|
@ -186,13 +182,13 @@ GtkImage has a "resource" property.
|
||||||
It is a GResource and GtkImage reads an image data from the resource and sets the image.
|
It is a GResource and GtkImage reads an image data from the resource and sets the image.
|
||||||
This resource is built from 24x24-sized png image data, which is an original icon.
|
This resource is built from 24x24-sized png image data, which is an original icon.
|
||||||
- 50-53: GtkScrolledWindow.
|
- 50-53: GtkScrolledWindow.
|
||||||
Its child widget will be GtkListView or GtkGridView.
|
Its child widget will be set with GtkListView or GtkGridView.
|
||||||
|
|
||||||
The action `view` is created, connected to the "activate" signal handler and inserted to the window (action map) as follows.
|
The action `view` is created, connected to the "activate" signal handler and inserted to the window (action map) as follows.
|
||||||
|
|
||||||
~~~C
|
~~~C
|
||||||
act_view = g_simple_action_new_stateful ("view", g_variant_type_new("s"), g_variant_new_string ("list"));
|
act_view = g_simple_action_new_stateful ("view", g_variant_type_new("s"), g_variant_new_string ("list"));
|
||||||
g_signal_connect (act_view, "activate", G_CALLBACK (view_activated), scr); /* scr is the GtkScrolledWindow object */
|
g_signal_connect (act_view, "activate", G_CALLBACK (view_activated), NULL);
|
||||||
g_action_map_add_action (G_ACTION_MAP (win), G_ACTION (act_view));
|
g_action_map_add_action (G_ACTION_MAP (win), G_ACTION (act_view));
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
|
@ -300,10 +296,10 @@ $ cd list4; diff factory_list.ui factory_grid.ui
|
||||||
> <property name="xalign">0.5</property>
|
> <property name="xalign">0.5</property>
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
Each view item has two properties, "gicon" property of GtkImage and "label" property of GtkLabel.
|
Two properties "gicon" (property of GtkImage) and "label" (property of GtkLabel) are in the ui files above.
|
||||||
Because GFileInfo doesn't have properties correspond to icon or filename, the factory uses closure tag to bind "gicon" and "label" properties to GFileInfo information.
|
Because GFileInfo doesn't have properties correspond to icon or filename, the factory uses closure tag to bind "gicon" and "label" properties to GFileInfo information.
|
||||||
A function `get_icon` gets GIcon the GFileInfo object has.
|
A function `get_icon` gets GIcon from the GFileInfo object.
|
||||||
And a function `get_file_name` gets a filename the GFileInfo object has.
|
And a function `get_file_name` gets a filename from the GFileInfo object.
|
||||||
|
|
||||||
~~~C
|
~~~C
|
||||||
1 GIcon *
|
1 GIcon *
|
||||||
|
@ -328,11 +324,12 @@ And a function `get_file_name` gets a filename the GFileInfo object has.
|
||||||
20 }
|
20 }
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
One important thing is view items own the instance or string.
|
One important thing is the ownership of the return values.
|
||||||
It is achieved by `g_object_ref` to increase the reference count by one, or `strdup` to create a copy of the string.
|
When GtkExpression (closure tag creates a GtkCClosureExpression -- a child class of GtkExpression) is evaluated,
|
||||||
The object or string will be automatically freed in unbinding process when the view item is recycled.
|
the value is owned by the caller.
|
||||||
|
So, `g_obect_ref` or `g_strdup` is necessary.
|
||||||
|
|
||||||
## An activate signal handler of the action
|
## An activate signal handler of the button action
|
||||||
|
|
||||||
An activate signal handler `view_activate` switches the view.
|
An activate signal handler `view_activate` switches the view.
|
||||||
It does two things.
|
It does two things.
|
||||||
|
@ -342,24 +339,23 @@ It does two things.
|
||||||
|
|
||||||
~~~C
|
~~~C
|
||||||
1 static void
|
1 static void
|
||||||
2 view_activated(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
|
2 view_activated(GSimpleAction *action, GVariant *parameter) {
|
||||||
3 GtkScrolledWindow *scr = GTK_SCROLLED_WINDOW (user_data);
|
3 const char *view = g_variant_get_string (parameter, NULL);
|
||||||
4 const char *view = g_variant_get_string (parameter, NULL);
|
4 const char *other;
|
||||||
5 const char *other;
|
5 char *css;
|
||||||
6 char *css;
|
6
|
||||||
7
|
7 if (strcmp (view, "list") == 0) {
|
||||||
8 if (strcmp (view, "list") == 0) {
|
8 other = "grid";
|
||||||
9 other = "grid";
|
9 gtk_scrolled_window_set_child (scr, GTK_WIDGET (list));
|
||||||
10 gtk_scrolled_window_set_child (scr, list);
|
10 }else {
|
||||||
11 }else {
|
11 other = "list";
|
||||||
12 other = "list";
|
12 gtk_scrolled_window_set_child (scr, GTK_WIDGET (grid));
|
||||||
13 gtk_scrolled_window_set_child (scr, grid);
|
13 }
|
||||||
14 }
|
14 css = g_strdup_printf ("button#btn%s {background: silver;} button#btn%s {background: white;}", view, other);
|
||||||
15 css = g_strdup_printf ("button#btn%s {background: silver;} button#btn%s {background: white;}", view, other);
|
15 gtk_css_provider_load_from_data (provider, css, -1);
|
||||||
16 gtk_css_provider_load_from_data (provider, css, -1);
|
16 g_free (css);
|
||||||
17 g_free (css);
|
17 g_action_change_state (G_ACTION (action), parameter);
|
||||||
18 g_action_change_state (G_ACTION (action), parameter);
|
18 }
|
||||||
19 }
|
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
The second parameter of this handler is the target of the clicked button.
|
The second parameter of this handler is the target of the clicked button.
|
||||||
|
@ -368,17 +364,17 @@ Its type is GVariant.
|
||||||
- If `btnlist` has been clicked, then `parameter` is a GVariant of the string "list".
|
- If `btnlist` has been clicked, then `parameter` is a GVariant of the string "list".
|
||||||
- If `btngrid` has been clicked, then `parameter` is a GVariant of the string "grid".
|
- If `btngrid` has been clicked, then `parameter` is a GVariant of the string "grid".
|
||||||
|
|
||||||
The third parameter `user_data` points GtkScrolledWindow, which is set in the `g_signal_connect` function.
|
The third parameter `user_data` points NULL and it is ignored here.
|
||||||
|
|
||||||
- 4: `g_variant_get_string` gets the string from the GVariant variable.
|
- 3: `g_variant_get_string` gets the string from the GVariant variable.
|
||||||
- 8-14: Sets the child of `scr`.
|
- 7-13: Sets the child of `scr`.
|
||||||
The function `gtk_scrolled_window_set_child` decreases the reference count of the old child by one.
|
The function `gtk_scrolled_window_set_child` decreases the reference count of the old child by one.
|
||||||
And it increases the reference count of the new child by one.
|
And it increases the reference count of the new child by one.
|
||||||
- 15-17: Sets the CSS of the buttons.
|
- 14-16: Sets the CSS for the buttons.
|
||||||
The background of the clicked button will be silver color and the other button will be white.
|
The background of the clicked button will be silver color and the other button will be white.
|
||||||
- 18: Changes the state of the action.
|
- 17: Changes the state of the action.
|
||||||
|
|
||||||
## Activate signal of GtkListView and GtkGridView
|
## Activate signal on GtkListView and GtkGridView
|
||||||
|
|
||||||
Views (GtkListView and GtkGridView) have an "activate" signal.
|
Views (GtkListView and GtkGridView) have an "activate" signal.
|
||||||
It is emitted when an item in the view is double clicked or the enter key is pressed.
|
It is emitted when an item in the view is double clicked or the enter key is pressed.
|
||||||
|
@ -406,10 +402,10 @@ grid_activate (GtkGridView *grid, int position, gpointer user_data) {
|
||||||
g_signal_connect (GTK_GRID_VIEW (grid), "activate", G_CALLBACK (grid_activate), NULL);
|
g_signal_connect (GTK_GRID_VIEW (grid), "activate", G_CALLBACK (grid_activate), NULL);
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
The second parameter of the handlers is the position of the item (GFileInfo) of the GListModel.
|
The second parameter of each handler is the position of the item (GFileInfo) of the GListModel.
|
||||||
So you can get the item with `g_list_model_get_item` function.
|
So you can get the item with `g_list_model_get_item` function.
|
||||||
|
|
||||||
## Content type and launching an application
|
### Content type and application launch
|
||||||
|
|
||||||
The function `launch_tfe_with_file` gets a file from the GFileInfo instance.
|
The function `launch_tfe_with_file` gets a file from the GFileInfo instance.
|
||||||
If the file is a text file, it launches `tfe` with the file.
|
If the file is a text file, it launches `tfe` with the file.
|
||||||
|
@ -433,52 +429,54 @@ Content type can be got with `g_file_info_get_content_type` function.
|
||||||
11 if (! info)
|
11 if (! info)
|
||||||
12 return;
|
12 return;
|
||||||
13 content_type = g_file_info_get_content_type (info);
|
13 content_type = g_file_info_get_content_type (info);
|
||||||
14 g_print ("%s\n", content_type); /* This line can be commented out if unnecessary */
|
14 #ifdef debug
|
||||||
15 if (! content_type)
|
15 g_print ("%s\n", content_type);
|
||||||
16 return;
|
16 #endif
|
||||||
17 for (i=0;i<5;++i) {
|
17 if (! content_type)
|
||||||
18 if (content_type[i] != text_type[i])
|
18 return;
|
||||||
19 return;
|
19 for (i=0;i<5;++i) { /* compare the first 5 characters */
|
||||||
20 }
|
20 if (content_type[i] != text_type[i])
|
||||||
21 appinfo = g_app_info_create_from_commandline ("tfe", "tfe", G_APP_INFO_CREATE_NONE, &err);
|
21 return;
|
||||||
22 if (err) {
|
22 }
|
||||||
23 g_printerr ("%s\n", err->message);
|
23 appinfo = g_app_info_create_from_commandline ("tfe", "tfe", G_APP_INFO_CREATE_NONE, &err);
|
||||||
24 g_error_free (err);
|
24 if (err) {
|
||||||
25 return;
|
25 g_printerr ("%s\n", err->message);
|
||||||
26 }
|
26 g_error_free (err);
|
||||||
27 err = NULL;
|
27 return;
|
||||||
28 file = g_file_new_for_path (g_file_info_get_name (info));
|
28 }
|
||||||
29 files = g_list_append (files, file);
|
29 err = NULL;
|
||||||
30 if (! (g_app_info_launch (appinfo, files, NULL, &err))) {
|
30 file = g_file_new_for_path (g_file_info_get_name (info));
|
||||||
31 g_printerr ("%s\n", err->message);
|
31 files = g_list_append (files, file);
|
||||||
32 g_error_free (err);
|
32 if (! (g_app_info_launch (appinfo, files, NULL, &err))) {
|
||||||
33 }
|
33 g_printerr ("%s\n", err->message);
|
||||||
34 g_list_free_full (files, g_object_unref);
|
34 g_error_free (err);
|
||||||
35 g_object_unref (appinfo);
|
35 }
|
||||||
36 }
|
36 g_list_free_full (files, g_object_unref);
|
||||||
|
37 g_object_unref (appinfo);
|
||||||
|
38 }
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
- 13: Gets the content type of the file from GFileInfo.
|
- 13: Gets the content type of the file from GFileInfo.
|
||||||
- 14: Prints the content type.
|
- 14-16: Prints the content type if "debug" is defined.
|
||||||
This is only useful to know a content type of a file.
|
This is only useful to know a content type of a file.
|
||||||
You can delete it if unnecessary.
|
If you don't want this, delete or uncomment the definition `#define debug 1` iat line 6 in the source file.
|
||||||
- 17-20: If the content type doesn't begin with "text/", then it returns.
|
- 17-22: If no content type or the content type doesn't begin with "text/",the function returns.
|
||||||
- 21: Creates GAppInfo object of `tfe` application.
|
- 23: Creates GAppInfo object of `tfe` application.
|
||||||
GAppInfo is an interface and the variable `appinfo` points a GDesktopAppInfo instance.
|
GAppInfo is an interface and the variable `appinfo` points a GDesktopAppInfo instance.
|
||||||
GAppInfo is a collection of information of an application.
|
GAppInfo is a collection of information of applications.
|
||||||
- 30: Launches the application (`tfe`) with an argument `file`.
|
- 32: Launches the application (`tfe`) with an argument `file`.
|
||||||
`g_app_info_launch` has four parameters.
|
`g_app_info_launch` has four parameters.
|
||||||
The first parameter is GAppInfo object.
|
The first parameter is GAppInfo object.
|
||||||
The second parameter is a list of GFile objects.
|
The second parameter is a list of GFile objects.
|
||||||
In this function, only one GFile instance is given to `tfe`, but you can give more arguments.
|
In this function, only one GFile instance is given to `tfe`, but you can give more arguments.
|
||||||
The third parameter is GAppLaunchContext, but this program gives NULL instead.
|
The third parameter is GAppLaunchContext, but this program gives NULL instead.
|
||||||
The last parameter is the pointer to the pointer to a GError.
|
The last parameter is the pointer to the pointer to a GError.
|
||||||
- 34: `g_list_free_full` frees the memories used by the list and items.
|
- 36: `g_list_free_full` frees the memories used by the list and items.
|
||||||
|
|
||||||
If your distribution supports GTK 4, using `g_app_info_launch_default_for_uri` is convenient.
|
If your distribution supports GTK 4, using `g_app_info_launch_default_for_uri` is convenient.
|
||||||
The function automatically determines the default application from the file and launches it.
|
The function automatically determines the default application from the file and launches it.
|
||||||
For example, if the file is text, then it launches gedit with the file.
|
For example, if the file is text, then it launches gedit with the file.
|
||||||
Such functionality comes from desktop.
|
Such feature comes from desktop.
|
||||||
|
|
||||||
## Compilation and execution
|
## Compilation and execution
|
||||||
|
|
||||||
|
@ -511,7 +509,7 @@ The following shows a part of the new ui file (`list5.ui`).
|
||||||
<property name="model">
|
<property name="model">
|
||||||
<object class="GtkSingleSelection" id="singleselection">
|
<object class="GtkSingleSelection" id="singleselection">
|
||||||
<property name="model">
|
<property name="model">
|
||||||
<object class="GtkDirectoryList" id="directorylist">
|
<object class="GtkDirectoryList" id="directory_list">
|
||||||
<property name="attributes">standard::name,standard::icon,standard::content-type</property>
|
<property name="attributes">standard::name,standard::icon,standard::content-type</property>
|
||||||
</object>
|
</object>
|
||||||
</property>
|
</property>
|
||||||
|
|
1131
gfm/sec28.md
1131
gfm/sec28.md
File diff suppressed because it is too large
Load diff
299
gfm/sec29.md
299
gfm/sec29.md
|
@ -1,4 +1,4 @@
|
||||||
Up: [Readme.md](../Readme.md), Prev: [Section 28](sec28.md)
|
Up: [README.md](../README.md), Prev: [Section 28](sec28.md)
|
||||||
|
|
||||||
# GtkColumnView
|
# GtkColumnView
|
||||||
|
|
||||||
|
@ -13,11 +13,11 @@ Each column is GtkColumnViewColumn.
|
||||||
The property points a GtkSelectionModel object.
|
The property points a GtkSelectionModel object.
|
||||||
- Each GtkColumnViewColumn has "factory" property.
|
- Each GtkColumnViewColumn has "factory" property.
|
||||||
The property points a GtkListItemFactory (GtkSignalListItemFactory or GtkBuilderListItemFactory).
|
The property points a GtkListItemFactory (GtkSignalListItemFactory or GtkBuilderListItemFactory).
|
||||||
- The factory connects GtkListItem, which belongs to GtkColumnViewColumn, and items of GtkSelectionModel.
|
- The factory connects GtkListItem and items of GtkSelectionModel.
|
||||||
And the factory builds the descendants widgets of GtkColumnView to display the item on the display.
|
And the factory builds the descendant widgets of GtkColumnView to display the item on the display.
|
||||||
This process is the same as the one in GtkListView.
|
This process is the same as the one in GtkListView.
|
||||||
|
|
||||||
The following diagram shows the image how it works.
|
The following diagram shows how it works.
|
||||||
|
|
||||||
![ColumnView](../image/column.png)
|
![ColumnView](../image/column.png)
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ In addition, the example uses GtkSortListModel and GtkSorter to sort the informa
|
||||||
|
|
||||||
## column.ui
|
## column.ui
|
||||||
|
|
||||||
Ui file specifies whole widgets and their structure.
|
Ui file specifies widgets and list item templates.
|
||||||
|
|
||||||
~~~xml
|
~~~xml
|
||||||
1 <?xml version="1.0" encoding="UTF-8"?>
|
1 <?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
@ -39,15 +39,15 @@ Ui file specifies whole widgets and their structure.
|
||||||
5 <property name="default-width">800</property>
|
5 <property name="default-width">800</property>
|
||||||
6 <property name="default-height">600</property>
|
6 <property name="default-height">600</property>
|
||||||
7 <child>
|
7 <child>
|
||||||
8 <object class="GtkScrolledWindow" id="scr">
|
8 <object class="GtkScrolledWindow">
|
||||||
9 <property name="hexpand">TRUE</property>
|
9 <property name="hexpand">TRUE</property>
|
||||||
10 <property name="vexpand">TRUE</property>
|
10 <property name="vexpand">TRUE</property>
|
||||||
11 <child>
|
11 <child>
|
||||||
12 <object class="GtkColumnView" id="columnview">
|
12 <object class="GtkColumnView" id="columnview">
|
||||||
13 <property name="model">
|
13 <property name="model">
|
||||||
14 <object class="GtkSingleSelection" id="singleselection">
|
14 <object class="GtkNoSelection">
|
||||||
15 <property name="model">
|
15 <property name="model">
|
||||||
16 <object class="GtkSortListModel" id="sortlist">
|
16 <object class="GtkSortListModel">
|
||||||
17 <property name="model">
|
17 <property name="model">
|
||||||
18 <object class="GtkDirectoryList" id="directorylist">
|
18 <object class="GtkDirectoryList" id="directorylist">
|
||||||
19 <property name="attributes">standard::name,standard::icon,standard::size,time::modified</property>
|
19 <property name="attributes">standard::name,standard::icon,standard::size,time::modified</property>
|
||||||
|
@ -61,7 +61,7 @@ Ui file specifies whole widgets and their structure.
|
||||||
27 </object>
|
27 </object>
|
||||||
28 </property>
|
28 </property>
|
||||||
29 <child>
|
29 <child>
|
||||||
30 <object class="GtkColumnViewColumn" id="column1">
|
30 <object class="GtkColumnViewColumn">
|
||||||
31 <property name="title">Name</property>
|
31 <property name="title">Name</property>
|
||||||
32 <property name="expand">TRUE</property>
|
32 <property name="expand">TRUE</property>
|
||||||
33 <property name="factory">
|
33 <property name="factory">
|
||||||
|
@ -102,7 +102,7 @@ Ui file specifies whole widgets and their structure.
|
||||||
68 </object>
|
68 </object>
|
||||||
69 </property>
|
69 </property>
|
||||||
70 <property name="sorter">
|
70 <property name="sorter">
|
||||||
71 <object class="GtkStringSorter" id="sorter_name">
|
71 <object class="GtkStringSorter">
|
||||||
72 <property name="expression">
|
72 <property name="expression">
|
||||||
73 <closure type="gchararray" function="get_file_name">
|
73 <closure type="gchararray" function="get_file_name">
|
||||||
74 </closure>
|
74 </closure>
|
||||||
|
@ -112,7 +112,7 @@ Ui file specifies whole widgets and their structure.
|
||||||
78 </object>
|
78 </object>
|
||||||
79 </child>
|
79 </child>
|
||||||
80 <child>
|
80 <child>
|
||||||
81 <object class="GtkColumnViewColumn" id="column2">
|
81 <object class="GtkColumnViewColumn">
|
||||||
82 <property name="title">Size</property>
|
82 <property name="title">Size</property>
|
||||||
83 <property name="factory">
|
83 <property name="factory">
|
||||||
84 <object class="GtkBuilderListItemFactory">
|
84 <object class="GtkBuilderListItemFactory">
|
||||||
|
@ -125,7 +125,7 @@ Ui file specifies whole widgets and their structure.
|
||||||
91 <property name="hexpand">TRUE</property>
|
91 <property name="hexpand">TRUE</property>
|
||||||
92 <property name="xalign">0</property>
|
92 <property name="xalign">0</property>
|
||||||
93 <binding name="label">
|
93 <binding name="label">
|
||||||
94 <closure type="gchararray" function="get_file_size_factory">
|
94 <closure type="gint64" function="get_file_size_factory">
|
||||||
95 <lookup name="item">GtkListItem</lookup>
|
95 <lookup name="item">GtkListItem</lookup>
|
||||||
96 </closure>
|
96 </closure>
|
||||||
97 </binding>
|
97 </binding>
|
||||||
|
@ -137,7 +137,7 @@ Ui file specifies whole widgets and their structure.
|
||||||
103 </object>
|
103 </object>
|
||||||
104 </property>
|
104 </property>
|
||||||
105 <property name="sorter">
|
105 <property name="sorter">
|
||||||
106 <object class="GtkNumericSorter" id="sorter_size">
|
106 <object class="GtkNumericSorter">
|
||||||
107 <property name="expression">
|
107 <property name="expression">
|
||||||
108 <closure type="gint64" function="get_file_size">
|
108 <closure type="gint64" function="get_file_size">
|
||||||
109 </closure>
|
109 </closure>
|
||||||
|
@ -148,7 +148,7 @@ Ui file specifies whole widgets and their structure.
|
||||||
114 </object>
|
114 </object>
|
||||||
115 </child>
|
115 </child>
|
||||||
116 <child>
|
116 <child>
|
||||||
117 <object class="GtkColumnViewColumn" id="column3">
|
117 <object class="GtkColumnViewColumn">
|
||||||
118 <property name="title">Date modified</property>
|
118 <property name="title">Date modified</property>
|
||||||
119 <property name="factory">
|
119 <property name="factory">
|
||||||
120 <object class="GtkBuilderListItemFactory">
|
120 <object class="GtkBuilderListItemFactory">
|
||||||
|
@ -173,7 +173,7 @@ Ui file specifies whole widgets and their structure.
|
||||||
139 </object>
|
139 </object>
|
||||||
140 </property>
|
140 </property>
|
||||||
141 <property name="sorter">
|
141 <property name="sorter">
|
||||||
142 <object class="GtkNumericSorter" id="sorter_datetime_modified">
|
142 <object class="GtkNumericSorter">
|
||||||
143 <property name="expression">
|
143 <property name="expression">
|
||||||
144 <closure type="gint64" function="get_file_unixtime_modified">
|
144 <closure type="gint64" function="get_file_unixtime_modified">
|
||||||
145 </closure>
|
145 </closure>
|
||||||
|
@ -191,18 +191,18 @@ Ui file specifies whole widgets and their structure.
|
||||||
157 </interface>
|
157 </interface>
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
- 3-12: Widget parent-child relationship is GtkApplicationWindow => GtkScrolledWindow => GtkColumnView.
|
- 3-12: GtkApplicationWindow has a child widget GtkScrolledWindow.
|
||||||
|
GtkScrolledWindoww has a child widget GtkColumnView.
|
||||||
- 12-18: GtkColumnView has "model" property.
|
- 12-18: GtkColumnView has "model" property.
|
||||||
It points GtkSelectionModel interface.
|
It points GtkSelectionModel interface.
|
||||||
In this ui file, GtkSingleSelection is used as GtkSelectionModel.
|
GtkNoSelection class is used as GtkSelectionModel.
|
||||||
GtkSingleSelection is an object that implements GtkSelectionModel.
|
|
||||||
And again, it has "model" property.
|
And again, it has "model" property.
|
||||||
It points GtkSortListModel.
|
It points GtkSortListModel.
|
||||||
This list model supports sorting the list.
|
This list model supports sorting the list.
|
||||||
It will be explained in the later subsection.
|
It will be explained in the later subsection.
|
||||||
And it also has "model" property.
|
And it also has "model" property.
|
||||||
It points GtkDirectoryList.
|
It points GtkDirectoryList.
|
||||||
Therefore, the chain is: GtkColumnView => GtkSingleSelection => GtkSortListModel => GtkDirectoryList.
|
Therefore, the chain is: GtkColumnView => GtkNoSelection => GtkSortListModel => GtkDirectoryList.
|
||||||
- 18-20: GtkDirectoryList.
|
- 18-20: GtkDirectoryList.
|
||||||
It is a list of GFileInfo, which holds information of files under a directory.
|
It is a list of GFileInfo, which holds information of files under a directory.
|
||||||
It has "attributes" property.
|
It has "attributes" property.
|
||||||
|
@ -213,30 +213,27 @@ It specifies what attributes is kept in each GFileInfo.
|
||||||
- "time::modified" is the date and time the file was last modified.
|
- "time::modified" is the date and time the file was last modified.
|
||||||
- 29-79: The first GtkColumnViewColumn object.
|
- 29-79: The first GtkColumnViewColumn object.
|
||||||
There are four properties, "title", "expand", factory" and "sorter".
|
There are four properties, "title", "expand", factory" and "sorter".
|
||||||
- 31: Sets the "title" property with "Name".
|
- 31: Sets the "title" property to "Name".
|
||||||
This is the title on the header of the column.
|
This is the title on the header of the column.
|
||||||
- 32: Sets the "expand" property to TRUE to allow the column to expand as much as possible.
|
- 32: Sets the "expand" property to TRUE to allow the column to expand as much as possible.
|
||||||
(See the image above).
|
(See the image above).
|
||||||
- 33- 69: Sets the "factory" property with GtkBuilderListItemFactory.
|
- 33- 69: Sets the "factory" property to GtkBuilderListItemFactory.
|
||||||
The factory has "bytes" property which holds a ui string to define a template to build GtkListItem composite widget.
|
The factory has "bytes" property which holds a ui string to define a template to build GtkListItem composite widget.
|
||||||
The CDATA section (line 36-66) is the ui string to put into the "bytes" property.
|
The CDATA section (line 36-66) is the ui string to put into the "bytes" property.
|
||||||
The contents are the same as the ui file `factory_list.ui` in the section 27.
|
The contents are the same as the ui file `factory_list.ui` in the section 27.
|
||||||
- 70-77: Sets the "sorter" property with GtkStringSorter object.
|
- 70-77: Sets the "sorter" property to GtkStringSorter object.
|
||||||
This object provides a sorter that compares strings.
|
This object provides a sorter that compares strings.
|
||||||
It has "expression" property which is set with GtkExpression.
|
It has "expression" property.
|
||||||
A closure tag with a string type function `get_file_name` is used here.
|
A closure tag with a string type function `get_file_name` is used here.
|
||||||
The function will be explained later.
|
The function will be explained later.
|
||||||
- 80-115: The second GtkColumnViewColumn object.
|
- 80-115: The second GtkColumnViewColumn object.
|
||||||
Its "title", "factory" and "sorter" properties are set.
|
Its sorter property is set to GtkNumericSorter.
|
||||||
GtkNumericSorter is used.
|
|
||||||
- 116-151: The third GtkColumnViewColumn object.
|
- 116-151: The third GtkColumnViewColumn object.
|
||||||
Its "title", "factory" and "sorter" properties are set.
|
Its sorter property is set to GtkNumericSorter.
|
||||||
GtkNumericSorter is used.
|
|
||||||
|
|
||||||
## GtkSortListModel and GtkSorter
|
## GtkSortListModel and GtkSorter
|
||||||
|
|
||||||
GtkSortListModel is a list model that sorts its elements according to a GtkSorter.
|
GtkSortListModel is a list model that sorts its elements according to a GtkSorter instance assigned to the "sorter" property.
|
||||||
It has "sorter" property that is set with GtkSorter.
|
|
||||||
The property is bound to "sorter" property of GtkColumnView in line 22 to 24.
|
The property is bound to "sorter" property of GtkColumnView in line 22 to 24.
|
||||||
|
|
||||||
~~~xml
|
~~~xml
|
||||||
|
@ -255,21 +252,25 @@ If the user clicks the header of another column, then the "sorter" property of t
|
||||||
|
|
||||||
The binding above makes a indirect connection between the "sorter" property of GtkSortListModel and the "sorter" property of each column.
|
The binding above makes a indirect connection between the "sorter" property of GtkSortListModel and the "sorter" property of each column.
|
||||||
|
|
||||||
|
GtkSorter compares two items (GObject or its descendant).
|
||||||
GtkSorter has several child objects.
|
GtkSorter has several child objects.
|
||||||
|
|
||||||
- GtkStringSorter compares strings.
|
- GtkStringSorter compares strings taken from the items.
|
||||||
- GtkNumericSorter compares numbers.
|
- GtkNumericSorter compares numbers taken from the items.
|
||||||
- GtkCustomSorter uses a callback to compare.
|
- GtkCustomSorter uses a callback to compare.
|
||||||
- GtkMultiSorter combines multiple sorters.
|
- GtkMultiSorter combines multiple sorters.
|
||||||
|
|
||||||
The example uses GtkStringSorter and GtkNumericSorter.
|
The example uses GtkStringSorter and GtkNumericSorter.
|
||||||
|
|
||||||
GtkStringSorter uses GtkExpression to get the strings from the objects.
|
GtkStringSorter uses GtkExpression to get the strings from the items (objects).
|
||||||
The GtkExpression is stored in the "expression" property of GtkStringSorter.
|
The GtkExpression is stored in the "expression" property of the GtkStringSorter.
|
||||||
For example, in the ui file above, the GtkExpression is in the line 71 to 76.
|
When GtkStringSorter compares two items, it evaluates the expression by calling `gtk_expression_evaluate` function.
|
||||||
|
It assigns each item to the second argument ('this' object) of the function.
|
||||||
|
|
||||||
|
In the ui file above, the GtkExpression is in the line 71 to 76.
|
||||||
|
|
||||||
~~~xml
|
~~~xml
|
||||||
<object class="GtkStringSorter" id="sorter_name">
|
<object class="GtkStringSorter">
|
||||||
<property name="expression">
|
<property name="expression">
|
||||||
<closure type="gchararray" function="get_file_name">
|
<closure type="gchararray" function="get_file_name">
|
||||||
</closure>
|
</closure>
|
||||||
|
@ -282,24 +283,23 @@ The GtkExpression calls `get_file_name` function when it is evaluated.
|
||||||
~~~C
|
~~~C
|
||||||
1 char *
|
1 char *
|
||||||
2 get_file_name (GFileInfo *info) {
|
2 get_file_name (GFileInfo *info) {
|
||||||
3 g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
|
3 return G_IS_FILE_INFO (info) ? g_strdup(g_file_info_get_name (info)) : NULL;
|
||||||
4
|
4 }
|
||||||
5 return g_strdup(g_file_info_get_name (info));
|
|
||||||
6 }
|
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
The function is given the item (GFileInfo) of the GtkSortListModel as an argument (`this` object).
|
The function is given the item (GFileInfo) of the GtkSortListModel as an argument (`this` object).
|
||||||
|
But you need to be careful that it can be NULL while the list item is being recycled.
|
||||||
|
So, `G_IS_FILE_INFO (info)` is always necessary in callback functions.
|
||||||
The function retrieves a filename from `info`.
|
The function retrieves a filename from `info`.
|
||||||
The string is owned by `info` so it is necessary to duplicate it.
|
The string is owned by `info` so it is necessary to duplicate it.
|
||||||
And it returns the copied string.
|
And it returns the copied string.
|
||||||
The string will be owned by the expression.
|
|
||||||
|
|
||||||
GtkNumericSorter compares numbers.
|
GtkNumericSorter compares numbers.
|
||||||
It is used in the line 106 to 112 and line 142 to 148.
|
It is used in the line 106 to 112 and line 142 to 148.
|
||||||
The lines from 106 to 112 is:
|
The lines from 106 to 112 is:
|
||||||
|
|
||||||
~~~xml
|
~~~xml
|
||||||
<object class="GtkNumericSorter" id="sorter_size">
|
<object class="GtkNumericSorter">
|
||||||
<property name="expression">
|
<property name="expression">
|
||||||
<closure type="gint64" function="get_file_size">
|
<closure type="gint64" function="get_file_size">
|
||||||
</closure>
|
</closure>
|
||||||
|
@ -313,10 +313,8 @@ The closure tag specifies a callback function `get_file_size`.
|
||||||
~~~C
|
~~~C
|
||||||
1 goffset
|
1 goffset
|
||||||
2 get_file_size (GFileInfo *info) {
|
2 get_file_size (GFileInfo *info) {
|
||||||
3 g_return_val_if_fail (G_IS_FILE_INFO (info), -1);
|
3 return G_IS_FILE_INFO (info) ? g_file_info_get_size (info): -1;
|
||||||
4
|
4 }
|
||||||
5 return g_file_info_get_size (info);
|
|
||||||
6 }
|
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
It just returns the size of `info`.
|
It just returns the size of `info`.
|
||||||
|
@ -340,13 +338,11 @@ The closure tag specifies a callback function `get_file_unixtime_modified`.
|
||||||
~~~C
|
~~~C
|
||||||
1 gint64
|
1 gint64
|
||||||
2 get_file_unixtime_modified (GFileInfo *info) {
|
2 get_file_unixtime_modified (GFileInfo *info) {
|
||||||
3 g_return_val_if_fail (G_IS_FILE_INFO (info), -1);
|
3 GDateTime *dt;
|
||||||
4
|
4
|
||||||
5 GDateTime *dt;
|
5 dt = G_IS_FILE_INFO (info) ? g_file_info_get_modification_date_time (info) : NULL;
|
||||||
6
|
6 return dt ? g_date_time_to_unix (dt) : -1;
|
||||||
7 dt = g_file_info_get_modification_date_time (info);
|
7 }
|
||||||
8 return g_date_time_to_unix (dt);
|
|
||||||
9 }
|
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
It gets the modification date and time (GDateTime type) of `info`.
|
It gets the modification date and time (GDateTime type) of `info`.
|
||||||
|
@ -357,6 +353,7 @@ It returns the unix time (gint64 type).
|
||||||
## column.c
|
## column.c
|
||||||
|
|
||||||
`column.c` is as follows.
|
`column.c` is as follows.
|
||||||
|
It is simple and short thanks to `column.ui`.
|
||||||
|
|
||||||
~~~C
|
~~~C
|
||||||
1 #include <gtk/gtk.h>
|
1 #include <gtk/gtk.h>
|
||||||
|
@ -365,132 +362,97 @@ It returns the unix time (gint64 type).
|
||||||
4 GIcon *
|
4 GIcon *
|
||||||
5 get_icon_factory (GtkListItem *item, GFileInfo *info) {
|
5 get_icon_factory (GtkListItem *item, GFileInfo *info) {
|
||||||
6 GIcon *icon;
|
6 GIcon *icon;
|
||||||
7 if (! G_IS_FILE_INFO (info))
|
7
|
||||||
8 return NULL;
|
8 /* g_file_info_get_icon can return NULL */
|
||||||
9 else {
|
9 icon = G_IS_FILE_INFO (info) ? g_file_info_get_icon (info) : NULL;
|
||||||
10 icon = g_file_info_get_icon (info);
|
10 return icon ? g_object_ref (icon) : NULL;
|
||||||
11 g_object_ref (icon);
|
11 }
|
||||||
12 return icon;
|
12
|
||||||
13 }
|
13 char *
|
||||||
14 }
|
14 get_file_name_factory (GtkListItem *item, GFileInfo *info) {
|
||||||
15
|
15 return G_IS_FILE_INFO (info) ? g_strdup (g_file_info_get_name (info)) : NULL;
|
||||||
16 char *
|
16 }
|
||||||
17 get_file_name_factory (GtkListItem *item, GFileInfo *info) {
|
17
|
||||||
18 if (! G_IS_FILE_INFO (info))
|
18 /* goffset is defined as gint64 */
|
||||||
19 return NULL;
|
19 /* It is used for file offsets. */
|
||||||
20 else
|
20 goffset
|
||||||
21 return g_strdup (g_file_info_get_name (info));
|
21 get_file_size_factory (GtkListItem *item, GFileInfo *info) {
|
||||||
22 }
|
22 return G_IS_FILE_INFO (info) ? g_file_info_get_size (info) : -1;
|
||||||
23
|
23 }
|
||||||
24 char *
|
24
|
||||||
25 get_file_size_factory (GtkListItem *item, GFileInfo *info) {
|
25 char *
|
||||||
26 /* goffset is gint64 */
|
26 get_file_time_modified_factory (GtkListItem *item, GFileInfo *info) {
|
||||||
27 goffset size;
|
27 GDateTime *dt;
|
||||||
28
|
28
|
||||||
29 if (! G_IS_FILE_INFO (info))
|
29 /* g_file_info_get_modification_date_time can return NULL */
|
||||||
30 return NULL;
|
30 dt = G_IS_FILE_INFO (info) ? g_file_info_get_modification_date_time (info) : NULL;
|
||||||
31 else {
|
31 return dt ? g_date_time_format (dt, "%F") : NULL;
|
||||||
32 size = g_file_info_get_size (info);
|
32 }
|
||||||
33 return g_strdup_printf ("%ld", (long int) size);
|
33
|
||||||
34 }
|
34 /* Functions (closures) for GtkSorter */
|
||||||
35 }
|
35 char *
|
||||||
36
|
36 get_file_name (GFileInfo *info) {
|
||||||
37 char *
|
37 return G_IS_FILE_INFO (info) ? g_strdup(g_file_info_get_name (info)) : NULL;
|
||||||
38 get_file_time_modified_factory (GtkListItem *item, GFileInfo *info) {
|
38 }
|
||||||
39 GDateTime *dt;
|
39
|
||||||
40
|
40 goffset
|
||||||
41 if (! G_IS_FILE_INFO (info))
|
41 get_file_size (GFileInfo *info) {
|
||||||
42 return NULL;
|
42 return G_IS_FILE_INFO (info) ? g_file_info_get_size (info): -1;
|
||||||
43 else {
|
43 }
|
||||||
44 dt = g_file_info_get_modification_date_time (info);
|
44
|
||||||
45 return g_date_time_format (dt, "%F");
|
45 gint64
|
||||||
46 }
|
46 get_file_unixtime_modified (GFileInfo *info) {
|
||||||
47 }
|
47 GDateTime *dt;
|
||||||
48
|
48
|
||||||
49 /* Functions (closures) for GtkSorter */
|
49 dt = G_IS_FILE_INFO (info) ? g_file_info_get_modification_date_time (info) : NULL;
|
||||||
50 char *
|
50 return dt ? g_date_time_to_unix (dt) : -1;
|
||||||
51 get_file_name (GFileInfo *info) {
|
51 }
|
||||||
52 g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
|
52
|
||||||
53
|
53 static void
|
||||||
54 return g_strdup(g_file_info_get_name (info));
|
54 app_activate (GApplication *application) {
|
||||||
55 }
|
55 GtkApplication *app = GTK_APPLICATION (application);
|
||||||
56
|
56 gtk_window_present (gtk_application_get_active_window(app));
|
||||||
57 goffset
|
57 }
|
||||||
58 get_file_size (GFileInfo *info) {
|
58
|
||||||
59 g_return_val_if_fail (G_IS_FILE_INFO (info), -1);
|
59 static void
|
||||||
60
|
60 app_startup (GApplication *application) {
|
||||||
61 return g_file_info_get_size (info);
|
61 GtkApplication *app = GTK_APPLICATION (application);
|
||||||
62 }
|
62 GFile *file;
|
||||||
63
|
63 GtkBuilder *build = gtk_builder_new_from_resource ("/com/github/ToshioCP/column/column.ui");
|
||||||
64 gint64
|
64 GtkWidget *win = GTK_WIDGET (gtk_builder_get_object (build, "win"));
|
||||||
65 get_file_unixtime_modified (GFileInfo *info) {
|
65 GtkDirectoryList *directorylist = GTK_DIRECTORY_LIST (gtk_builder_get_object (build, "directorylist"));
|
||||||
66 g_return_val_if_fail (G_IS_FILE_INFO (info), -1);
|
66 g_object_unref (build);
|
||||||
67
|
67
|
||||||
68 GDateTime *dt;
|
68 gtk_window_set_application (GTK_WINDOW (win), app);
|
||||||
69
|
69
|
||||||
70 dt = g_file_info_get_modification_date_time (info);
|
70 file = g_file_new_for_path (".");
|
||||||
71 return g_date_time_to_unix (dt);
|
71 gtk_directory_list_set_file (directorylist, file);
|
||||||
72 }
|
72 g_object_unref (file);
|
||||||
73
|
73 }
|
||||||
74 /* ----- activate, open, startup handlers ----- */
|
74
|
||||||
75 static void
|
75 #define APPLICATION_ID "com.github.ToshioCP.columnview"
|
||||||
76 app_activate (GApplication *application) {
|
76
|
||||||
77 GtkApplication *app = GTK_APPLICATION (application);
|
77 int
|
||||||
78 GFile *file;
|
78 main (int argc, char **argv) {
|
||||||
79
|
79 GtkApplication *app;
|
||||||
80 GtkBuilder *build = gtk_builder_new_from_resource ("/com/github/ToshioCP/column/column.ui");
|
80 int stat;
|
||||||
81 GtkWidget *win = GTK_WIDGET (gtk_builder_get_object (build, "win"));
|
81
|
||||||
82 GtkDirectoryList *directorylist = GTK_DIRECTORY_LIST (gtk_builder_get_object (build, "directorylist"));
|
82 app = gtk_application_new (APPLICATION_ID, G_APPLICATION_DEFAULT_FLAGS);
|
||||||
83 g_object_unref (build);
|
83
|
||||||
84
|
84 g_signal_connect (app, "startup", G_CALLBACK (app_startup), NULL);
|
||||||
85 gtk_window_set_application (GTK_WINDOW (win), app);
|
85 g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
|
||||||
86
|
86
|
||||||
87 file = g_file_new_for_path (".");
|
87 stat =g_application_run (G_APPLICATION (app), argc, argv);
|
||||||
88 gtk_directory_list_set_file (directorylist, file);
|
88 g_object_unref (app);
|
||||||
89 g_object_unref (file);
|
89 return stat;
|
||||||
90
|
90 }
|
||||||
91 gtk_widget_show (win);
|
91
|
||||||
92 }
|
|
||||||
93
|
|
||||||
94 static void
|
|
||||||
95 app_startup (GApplication *application) {
|
|
||||||
96 }
|
|
||||||
97
|
|
||||||
98 #define APPLICATION_ID "com.github.ToshioCP.columnview"
|
|
||||||
99
|
|
||||||
100 int
|
|
||||||
101 main (int argc, char **argv) {
|
|
||||||
102 GtkApplication *app;
|
|
||||||
103 int stat;
|
|
||||||
104
|
|
||||||
105 app = gtk_application_new (APPLICATION_ID, G_APPLICATION_FLAGS_NONE);
|
|
||||||
106
|
|
||||||
107 g_signal_connect (app, "startup", G_CALLBACK (app_startup), NULL);
|
|
||||||
108 g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
|
|
||||||
109 /* g_signal_connect (app, "open", G_CALLBACK (app_open), NULL);*/
|
|
||||||
110
|
|
||||||
111 stat =g_application_run (G_APPLICATION (app), argc, argv);
|
|
||||||
112 g_object_unref (app);
|
|
||||||
113 return stat;
|
|
||||||
114 }
|
|
||||||
115
|
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
- 4-47: Functions for the closure tag in the "bytes" property of GtkBuilderListItemFactory.
|
|
||||||
These are almost same as the functions in section 26 and 26.
|
|
||||||
- 50-72: Functions for the closure in the expression property of GtkStringSorter or GtkNumericSorter.
|
|
||||||
- 75-92: `app_activate` is an "activate" handler of GApplication.
|
|
||||||
- 80-83: Builds objects with ui resource and gets `win` and `directorylist`.
|
|
||||||
- 85: Sets the application of the top level window with `app`.
|
|
||||||
- 87-89: Sets the file of `directorylist` with "." (current directory).
|
|
||||||
- 94-96: Startup handler.
|
|
||||||
- 98-114: `main` function.
|
|
||||||
|
|
||||||
`exp.c` is simple and short thanks to `exp.ui`.
|
|
||||||
|
|
||||||
## Compilation and execution.
|
## Compilation and execution.
|
||||||
|
|
||||||
All the source files are in [src/column](../src/column) directory.
|
All the source files are in [`src/column`](../src/column) directory.
|
||||||
Change your current directory to the directory and type the following.
|
Change your current directory to the directory and type the following.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
|
@ -509,5 +471,4 @@ If you click the header of another column, then the whole lists are sorted by th
|
||||||
GtkColumnView is very useful and it can manage very big GListModel.
|
GtkColumnView is very useful and it can manage very big GListModel.
|
||||||
It is possible to use it for file list, application list, database frontend and so on.
|
It is possible to use it for file list, application list, database frontend and so on.
|
||||||
|
|
||||||
|
Up: [README.md](../README.md), Prev: [Section 28](sec28.md)
|
||||||
Up: [Readme.md](../Readme.md), Prev: [Section 28](sec28.md)
|
|
||||||
|
|
18
gfm/sec3.md
18
gfm/sec3.md
|
@ -59,9 +59,27 @@ In a broad sense, object has wider meaning than instance.
|
||||||
So, readers should be careful of the contexts to find the meaning of "object".
|
So, readers should be careful of the contexts to find the meaning of "object".
|
||||||
In many cases, object and instance are the same.
|
In many cases, object and instance are the same.
|
||||||
|
|
||||||
|
The function `gtk_application_new` has two parameters.
|
||||||
|
|
||||||
|
- Application ID (com.github.ToshioCP.pr1).
|
||||||
|
It is used to distinguish applications by the system.
|
||||||
|
The format is reverse-DNS.
|
||||||
|
See [GNOME Developer Documentation -- Application ID](https://developer.gnome.org/documentation/tutorials/application-id.html) for further information.
|
||||||
|
|
||||||
|
- Application flag (G\_APPLICATION\_DEFAULT\_FLAGS).
|
||||||
|
If the application runs without any arguments, the flag is G\_APPLICATION\_DEFAULT\_FLAGS.
|
||||||
|
Otherwise, you need other flags.
|
||||||
|
See [GIO API reference](https://docs.gtk.org/gio/flags.ApplicationFlags.html) for further information.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
To compile this, the following command needs to be run.
|
To compile this, the following command needs to be run.
|
||||||
The string `pr1.c` is the filename of the C source code above.
|
The string `pr1.c` is the filename of the C source code above.
|
||||||
|
|
||||||
|
Notice: If your GLib-2.0 version is older than 2.74, use `G_APPLICATION_FLAGS_NONE` instead of `G_APPLICATION_DEFAULT_FLAGS`.
|
||||||
|
It is an old flag replaced by `G_APPLICATION_DEFAULT_FLAGS` and deprecated since version 2.74.
|
||||||
|
However, many distributions use GLib-2.0 version 2.72 or older, for example, Ubuntu 22.04 LTS.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
$ gcc `pkg-config --cflags gtk4` pr1.c `pkg-config --libs gtk4`
|
$ gcc `pkg-config --cflags gtk4` pr1.c `pkg-config --libs gtk4`
|
||||||
~~~
|
~~~
|
||||||
|
|
Loading…
Reference in a new issue