mirror of
https://github.com/ToshioCP/Gtk4-tutorial.git
synced 2024-11-16 19:50:35 +01:00
Add GtkDirecoryList.
This commit is contained in:
parent
8cfc7d4721
commit
126e3624b6
5 changed files with 341 additions and 1 deletions
169
gfm/sec24.md
169
gfm/sec24.md
|
@ -324,4 +324,173 @@ GtkSingleSelection is used, so user can select one item at a time.
|
|||
Because this is a small program, the ui data is given as strings.
|
||||
However, generally, ui file is better than string and using resource compiler is the best choice.
|
||||
|
||||
## GtkDirectoryList
|
||||
|
||||
GtkDirectoryList is a list model containing GFileInfo objects which are information of files under a certain directory.
|
||||
It uses `g_file_enumerate_children_async()` to get the GFileInfo objects.
|
||||
The list model is created by `gtk_directory_list_new` function.
|
||||
|
||||
~~~C
|
||||
GtkDirectoryList *gtk_directory_list_new (const char *attributes, GFile *file);
|
||||
~~~
|
||||
|
||||
`attributes` is a comma separated list of file attributes.
|
||||
File attributes are key-value pairs.
|
||||
A key consists of a namespace and a name.
|
||||
For example, "standard::name" key is the name of a file.
|
||||
"standard" means general file information.
|
||||
"name" means filename.
|
||||
The following table shows some example.
|
||||
|
||||
|key |meaning |
|
||||
|:---------------|:-------------------------------------------------------------------|
|
||||
|standard::type |file type. for example, regular file, directory, symbolic link, etc.|
|
||||
|standard::name |filename |
|
||||
|standard::size |file size in bytes |
|
||||
|access::can-read|read privilege if the user is able to read the file |
|
||||
|time::modified |the time the file was last modified in seconds since the UNIX epoch |
|
||||
|
||||
The current directory is ".".
|
||||
The following program makes GtkDirectoryList `dl` and its contents are GFileInfo objects under the current directory.
|
||||
|
||||
~~~C
|
||||
GFile *file = g_file_new_for_path (".");
|
||||
GtkDirectoryList *dl = gtk_directory_list_new ("standard::name", file);
|
||||
g_object_unref (file);
|
||||
~~~
|
||||
|
||||
It is not so difficult to make file listing program by changing `list2.c` in the previous subsection.
|
||||
One problem is that GInfoFile doesn't have properties.
|
||||
Lookup tag look for a property, so it is useless for looking for a filename from a GFileInfo object.
|
||||
Instead, closure tag is appropriate in this case.
|
||||
Closure tag specifies a function and the type of the return value of the function.
|
||||
|
||||
~~~C
|
||||
char *
|
||||
get_file_name (GtkListItem *item, GFileInfo *info) {
|
||||
if (! G_IS_FILE_INFO (info))
|
||||
return NULL;
|
||||
else
|
||||
return g_strdup (g_file_info_get_name (info));
|
||||
}
|
||||
|
||||
... ...
|
||||
... ...
|
||||
|
||||
"<interface>"
|
||||
"<template class=\"GtkListItem\">"
|
||||
"<property name=\"child\">"
|
||||
"<object class=\"GtkLabel\">"
|
||||
"<binding name=\"label\">"
|
||||
"<closure type=\"gchararray\" function=\"get_file_name\">"
|
||||
"<lookup name=\"item\">GtkListItem</lookup>"
|
||||
"</closure>"
|
||||
"</binding>"
|
||||
"</object>"
|
||||
"</property>"
|
||||
"</template>"
|
||||
"</interface>"
|
||||
~~~
|
||||
|
||||
- "gchararray" is the type of strings.
|
||||
"gchar" is the same as "char" 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.
|
||||
GValue is a generic value and it can contain various type of values.
|
||||
For example, the type can be gboolean, gchar (char), gint (int), gfloat (float), gdouble (double), gchararray (char *) and so on.
|
||||
For the further information, refer to GFileAttribute and GFileInfo section in [GIO API reference](https://developer.gnome.org/gio/stable/).
|
||||
- closure tag has type attribute and function attribute.
|
||||
Function attribute specifies a 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.
|
||||
`<lookup name=\"item\">GtkListItem</lookup>` gives two parameters.
|
||||
The first parameter is GListItem object and the second parameter is item property, which is a GFileInfo object in the GtkDirectoryList Object.
|
||||
- `gtk_file_name` function first check the `info` parameter.
|
||||
Because it can be NULL when GListItem `item` is unbound.
|
||||
If its GFileInfo, then return the filename (copy of the filename).
|
||||
|
||||
The whole program (`list3.c`) is as follows.
|
||||
The program is located in [src/misc](../src/misc) directory.
|
||||
|
||||
~~~C
|
||||
1 #include <gtk/gtk.h>
|
||||
2
|
||||
3 char *
|
||||
4 get_file_name (GtkListItem *item, GFileInfo *info) {
|
||||
5 if (! G_IS_FILE_INFO (info))
|
||||
6 return NULL;
|
||||
7 else
|
||||
8 return g_strdup (g_file_info_get_name (info));
|
||||
9 }
|
||||
10
|
||||
11 /* ----- activate, open, startup handlers ----- */
|
||||
12 static void
|
||||
13 tfe_activate (GApplication *application) {
|
||||
14 GtkApplication *app = GTK_APPLICATION (application);
|
||||
15 GtkWidget *win = gtk_application_window_new (app);
|
||||
16 gtk_window_set_default_size (GTK_WINDOW (win), 600, 400);
|
||||
17 GtkWidget *scr = gtk_scrolled_window_new ();
|
||||
18 gtk_window_set_child (GTK_WINDOW (win), scr);
|
||||
19
|
||||
20 GFile *file = g_file_new_for_path (".");
|
||||
21 GtkDirectoryList *dl = gtk_directory_list_new ("standard::name", file);
|
||||
22 g_object_unref (file);
|
||||
23 GtkNoSelection *ns = gtk_no_selection_new (G_LIST_MODEL (dl));
|
||||
24
|
||||
25 const char *ui_string =
|
||||
26 "<interface>"
|
||||
27 "<template class=\"GtkListItem\">"
|
||||
28 "<property name=\"child\">"
|
||||
29 "<object class=\"GtkLabel\">"
|
||||
30 "<binding name=\"label\">"
|
||||
31 "<closure type=\"gchararray\" function=\"get_file_name\">"
|
||||
32 "<lookup name=\"item\">GtkListItem</lookup>"
|
||||
33 "</closure>"
|
||||
34 "</binding>"
|
||||
35 "</object>"
|
||||
36 "</property>"
|
||||
37 "</template>"
|
||||
38 "</interface>"
|
||||
39 ;
|
||||
40 GBytes *gbytes = g_bytes_new_static (ui_string, strlen (ui_string));
|
||||
41 GtkListItemFactory *factory = gtk_builder_list_item_factory_new_from_bytes (NULL, gbytes);
|
||||
42
|
||||
43 GtkWidget *lv = gtk_list_view_new (GTK_SELECTION_MODEL (ns), factory);
|
||||
44 gtk_list_view_set_enable_rubberband (GTK_LIST_VIEW (lv), TRUE);
|
||||
45 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), lv);
|
||||
46 gtk_widget_show (win);
|
||||
47 }
|
||||
48
|
||||
49 static void
|
||||
50 tfe_startup (GApplication *application) {
|
||||
51 }
|
||||
52
|
||||
53 /* ----- main ----- */
|
||||
54 int
|
||||
55 main (int argc, char **argv) {
|
||||
56 GtkApplication *app;
|
||||
57 int stat;
|
||||
58
|
||||
59 app = gtk_application_new ("com.github.ToshioCP.list2", G_APPLICATION_FLAGS_NONE);
|
||||
60
|
||||
61 g_signal_connect (app, "startup", G_CALLBACK (tfe_startup), NULL);
|
||||
62 g_signal_connect (app, "activate", G_CALLBACK (tfe_activate), NULL);
|
||||
63
|
||||
64 stat =g_application_run (G_APPLICATION (app), argc, argv);
|
||||
65 g_object_unref (app);
|
||||
66 return stat;
|
||||
67 }
|
||||
68
|
||||
~~~
|
||||
|
||||
Compile and execute it.
|
||||
|
||||
~~~
|
||||
$ cd misc
|
||||
$ comp list3
|
||||
$ ./a.out
|
||||
~~~
|
||||
|
||||
![screenshot list3](../image/list3.png)
|
||||
|
||||
|
||||
Up: [Readme.md](../Readme.md), Prev: [Section 23](sec23.md)
|
||||
|
|
BIN
image/list3.png
Normal file
BIN
image/list3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
|
@ -1 +1,2 @@
|
|||
gcc `pkg-config --cflags gtk4` $1.c `pkg-config --libs gtk4`
|
||||
gcc -Wl,--export-dynamic `pkg-config --cflags gtk4` $1.c `pkg-config --libs gtk4`
|
||||
|
||||
|
|
68
src/misc/list3.c
Normal file
68
src/misc/list3.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
#include <gtk/gtk.h>
|
||||
|
||||
char *
|
||||
get_file_name (GtkListItem *item, GFileInfo *info) {
|
||||
if (! G_IS_FILE_INFO (info))
|
||||
return NULL;
|
||||
else
|
||||
return g_strdup (g_file_info_get_name (info));
|
||||
}
|
||||
|
||||
/* ----- activate, open, startup handlers ----- */
|
||||
static void
|
||||
tfe_activate (GApplication *application) {
|
||||
GtkApplication *app = GTK_APPLICATION (application);
|
||||
GtkWidget *win = gtk_application_window_new (app);
|
||||
gtk_window_set_default_size (GTK_WINDOW (win), 600, 400);
|
||||
GtkWidget *scr = gtk_scrolled_window_new ();
|
||||
gtk_window_set_child (GTK_WINDOW (win), scr);
|
||||
|
||||
GFile *file = g_file_new_for_path (".");
|
||||
GtkDirectoryList *dl = gtk_directory_list_new ("standard::name", file);
|
||||
g_object_unref (file);
|
||||
GtkNoSelection *ns = gtk_no_selection_new (G_LIST_MODEL (dl));
|
||||
|
||||
const char *ui_string =
|
||||
"<interface>"
|
||||
"<template class=\"GtkListItem\">"
|
||||
"<property name=\"child\">"
|
||||
"<object class=\"GtkLabel\">"
|
||||
"<binding name=\"label\">"
|
||||
"<closure type=\"gchararray\" function=\"get_file_name\">"
|
||||
"<lookup name=\"item\">GtkListItem</lookup>"
|
||||
"</closure>"
|
||||
"</binding>"
|
||||
"</object>"
|
||||
"</property>"
|
||||
"</template>"
|
||||
"</interface>"
|
||||
;
|
||||
GBytes *gbytes = g_bytes_new_static (ui_string, strlen (ui_string));
|
||||
GtkListItemFactory *factory = gtk_builder_list_item_factory_new_from_bytes (NULL, gbytes);
|
||||
|
||||
GtkWidget *lv = gtk_list_view_new (GTK_SELECTION_MODEL (ns), factory);
|
||||
gtk_list_view_set_enable_rubberband (GTK_LIST_VIEW (lv), TRUE);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), lv);
|
||||
gtk_widget_show (win);
|
||||
}
|
||||
|
||||
static void
|
||||
tfe_startup (GApplication *application) {
|
||||
}
|
||||
|
||||
/* ----- main ----- */
|
||||
int
|
||||
main (int argc, char **argv) {
|
||||
GtkApplication *app;
|
||||
int stat;
|
||||
|
||||
app = gtk_application_new ("com.github.ToshioCP.list2", G_APPLICATION_FLAGS_NONE);
|
||||
|
||||
g_signal_connect (app, "startup", G_CALLBACK (tfe_startup), NULL);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (tfe_activate), NULL);
|
||||
|
||||
stat =g_application_run (G_APPLICATION (app), argc, argv);
|
||||
g_object_unref (app);
|
||||
return stat;
|
||||
}
|
||||
|
102
src/sec24.src.md
102
src/sec24.src.md
|
@ -203,3 +203,105 @@ GtkSingleSelection is used, so user can select one item at a time.
|
|||
|
||||
Because this is a small program, the ui data is given as strings.
|
||||
However, generally, ui file is better than string and using resource compiler is the best choice.
|
||||
|
||||
## GtkDirectoryList
|
||||
|
||||
GtkDirectoryList is a list model containing GFileInfo objects which are information of files under a certain directory.
|
||||
It uses `g_file_enumerate_children_async()` to get the GFileInfo objects.
|
||||
The list model is created by `gtk_directory_list_new` function.
|
||||
|
||||
~~~C
|
||||
GtkDirectoryList *gtk_directory_list_new (const char *attributes, GFile *file);
|
||||
~~~
|
||||
|
||||
`attributes` is a comma separated list of file attributes.
|
||||
File attributes are key-value pairs.
|
||||
A key consists of a namespace and a name.
|
||||
For example, "standard::name" key is the name of a file.
|
||||
"standard" means general file information.
|
||||
"name" means filename.
|
||||
The following table shows some example.
|
||||
|
||||
|key |meaning |
|
||||
|:---------------|:-------------------------------------------------------------------|
|
||||
|standard::type |file type. for example, regular file, directory, symbolic link, etc.|
|
||||
|standard::name |filename |
|
||||
|standard::size |file size in bytes |
|
||||
|access::can-read|read privilege if the user is able to read the file |
|
||||
|time::modified |the time the file was last modified in seconds since the UNIX epoch |
|
||||
|
||||
The current directory is ".".
|
||||
The following program makes GtkDirectoryList `dl` and its contents are GFileInfo objects under the current directory.
|
||||
|
||||
~~~C
|
||||
GFile *file = g_file_new_for_path (".");
|
||||
GtkDirectoryList *dl = gtk_directory_list_new ("standard::name", file);
|
||||
g_object_unref (file);
|
||||
~~~
|
||||
|
||||
It is not so difficult to make file listing program by changing `list2.c` in the previous subsection.
|
||||
One problem is that GInfoFile doesn't have properties.
|
||||
Lookup tag look for a property, so it is useless for looking for a filename from a GFileInfo object.
|
||||
Instead, closure tag is appropriate in this case.
|
||||
Closure tag specifies a function and the type of the return value of the function.
|
||||
|
||||
~~~C
|
||||
char *
|
||||
get_file_name (GtkListItem *item, GFileInfo *info) {
|
||||
if (! G_IS_FILE_INFO (info))
|
||||
return NULL;
|
||||
else
|
||||
return g_strdup (g_file_info_get_name (info));
|
||||
}
|
||||
|
||||
... ...
|
||||
... ...
|
||||
|
||||
"<interface>"
|
||||
"<template class=\"GtkListItem\">"
|
||||
"<property name=\"child\">"
|
||||
"<object class=\"GtkLabel\">"
|
||||
"<binding name=\"label\">"
|
||||
"<closure type=\"gchararray\" function=\"get_file_name\">"
|
||||
"<lookup name=\"item\">GtkListItem</lookup>"
|
||||
"</closure>"
|
||||
"</binding>"
|
||||
"</object>"
|
||||
"</property>"
|
||||
"</template>"
|
||||
"</interface>"
|
||||
~~~
|
||||
|
||||
- "gchararray" is the type of strings.
|
||||
"gchar" is the same as "char" 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.
|
||||
GValue is a generic value and it can contain various type of values.
|
||||
For example, the type can be gboolean, gchar (char), gint (int), gfloat (float), gdouble (double), gchararray (char *) and so on.
|
||||
For the further information, refer to GFileAttribute and GFileInfo section in [GIO API reference](https://developer.gnome.org/gio/stable/).
|
||||
- closure tag has type attribute and function attribute.
|
||||
Function attribute specifies a 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.
|
||||
`<lookup name=\"item\">GtkListItem</lookup>` gives two parameters.
|
||||
The first parameter is GListItem object and the second parameter is item property, which is a GFileInfo object in the GtkDirectoryList Object.
|
||||
- `gtk_file_name` function first check the `info` parameter.
|
||||
Because it can be NULL when GListItem `item` is unbound.
|
||||
If its GFileInfo, then return the filename (copy of the filename).
|
||||
|
||||
The whole program (`list3.c`) is as follows.
|
||||
The program is located in [src/misc](misc) directory.
|
||||
|
||||
@@@include
|
||||
misc/list3.c
|
||||
@@@
|
||||
|
||||
Compile and execute it.
|
||||
|
||||
~~~
|
||||
$ cd misc
|
||||
$ comp list3
|
||||
$ ./a.out
|
||||
~~~
|
||||
|
||||
![screenshot list3](../image/list3.png){width=6.04cm height=4.41cm}
|
||||
|
||||
|
|
Loading…
Reference in a new issue