Modify section 10 and 11.

This commit is contained in:
Toshio Sekiya 2021-06-17 20:04:16 +09:00
parent cbd454c85b
commit f4308b83c1
7 changed files with 327 additions and 277 deletions

View file

@ -21,7 +21,7 @@ For example, our source has two things, the definition of TfeTextView and functi
It is a good idea to separate them into two files, `tfetextview.c` and `tfe.c`. It is a good idea to separate them into two files, `tfetextview.c` and `tfe.c`.
- `tfetextview.c` includes the definition and functions of TfeTextView. - `tfetextview.c` includes the definition and functions of TfeTextView.
- `tfe.c` includes functions like `main`, `on_activate`, `on_open` and so on, which relate to GtkApplication and GtkApplicationWindow - `tfe.c` includes functions like `main`, `app_activate`, `app_open` and so on, which relate to GtkApplication and GtkApplicationWindow
Now we have three source files, `tfetextview.c`, `tfe.c` and `tfe3.ui`. Now we have three source files, `tfetextview.c`, `tfe.c` and `tfe3.ui`.
The `3` of `tfe3.ui` is like a version number. The `3` of `tfe3.ui` is like a version number.
@ -29,7 +29,7 @@ Managing version with filenames is one possible idea but it may make bothersome
You need to rewrite filename in each version and it affects to contents of source files that refer to filenames. You need to rewrite filename in each version and it affects to contents of source files that refer to filenames.
So, we should take `3` away from the filename. So, we should take `3` away from the filename.
In `tfe.c` the function `tfe_text_view_new` is invoked to generate TfeTextView. In `tfe.c` the function `tfe_text_view_new` is invoked to create a TfeTextView instance.
But it is defined in `tfetextview.c`, not `tfe.c`. But it is defined in `tfetextview.c`, not `tfe.c`.
The lack of the declaration (not definition) of `tfe_text_view_new` makes error when `tfe.c` is compiled. The lack of the declaration (not definition) of `tfe_text_view_new` makes error when `tfe.c` is compiled.
The declaration is necessary in `tfe.c`. The declaration is necessary in `tfe.c`.
@ -105,12 +105,12 @@ All the source files are listed below.
2 #include "tfetextview.h" 2 #include "tfetextview.h"
3 3
4 static void 4 static void
5 on_activate (GApplication *app, gpointer user_data) { 5 app_activate (GApplication *app, gpointer user_data) {
6 g_print ("You need a filename argument.\n"); 6 g_print ("You need a filename argument.\n");
7 } 7 }
8 8
9 static void 9 static void
10 on_open (GApplication *app, GFile ** files, gint n_files, gchar *hint, gpointer user_data) { 10 app_open (GApplication *app, GFile ** files, gint n_files, gchar *hint, gpointer user_data) {
11 GtkWidget *win; 11 GtkWidget *win;
12 GtkWidget *nb; 12 GtkWidget *nb;
13 GtkWidget *lab; 13 GtkWidget *lab;
@ -146,11 +146,11 @@ All the source files are listed below.
43 nbp = gtk_notebook_get_page (GTK_NOTEBOOK (nb), scr); 43 nbp = gtk_notebook_get_page (GTK_NOTEBOOK (nb), scr);
44 g_object_set (nbp, "tab-expand", TRUE, NULL); 44 g_object_set (nbp, "tab-expand", TRUE, NULL);
45 g_free (filename); 45 g_free (filename);
46 } else { 46 } else if ((filename = g_file_get_path (files[i])) != NULL) {
47 filename = g_file_get_path (files[i]); 47 g_print ("No such file: %s.\n", filename);
48 g_print ("No such file: %s.\n", filename); 48 g_free (filename);
49 g_free (filename); 49 } else
50 } 50 g_print ("No valid file is given\n");
51 } 51 }
52 if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)) > 0) { 52 if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)) > 0) {
53 gtk_widget_show (win); 53 gtk_widget_show (win);
@ -163,9 +163,9 @@ All the source files are listed below.
60 GtkApplication *app; 60 GtkApplication *app;
61 int stat; 61 int stat;
62 62
63 app = gtk_application_new ("com.github.ToshioCP.tfe3", G_APPLICATION_HANDLES_OPEN); 63 app = gtk_application_new ("com.github.ToshioCP.tfe", G_APPLICATION_HANDLES_OPEN);
64 g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); 64 g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
65 g_signal_connect (app, "open", G_CALLBACK (on_open), NULL); 65 g_signal_connect (app, "open", G_CALLBACK (app_open), NULL);
66 stat =g_application_run (G_APPLICATION (app), argc, argv); 66 stat =g_application_run (G_APPLICATION (app), argc, argv);
67 g_object_unref (app); 67 g_object_unref (app);
68 return stat; 68 return stat;
@ -211,7 +211,7 @@ sample.o: sample.c
gcc -o sample.o sample.c gcc -o sample.o sample.c
~~~ ~~~
The sample of Malefile above consists of three elements, `sample.o`, `sample.c` and `gcc -0 sample.o sample.c`. The sample of Malefile above consists of three elements, `sample.o`, `sample.c` and `gcc -o sample.o sample.c`.
- `sample.o` is called target. - `sample.o` is called target.
- `sample.c` is prerequisite. - `sample.c` is prerequisite.
@ -272,7 +272,7 @@ If you don't use Ruby, you don't need to read this subsection.
However, Ruby is really sophisticated and recommendable script language. However, Ruby is really sophisticated and recommendable script language.
- Rakefile controls the behavior of `rake`. - Rakefile controls the behavior of `rake`.
- You can write any ruby code in Rakefile. - You can write any Ruby code in Rakefile.
Rake has task and file task, which is similar to target, prerequisite and recipe in make. Rake has task and file task, which is similar to target, prerequisite and recipe in make.
@ -304,24 +304,24 @@ Rake has task and file task, which is similar to target, prerequisite and recipe
25 end 25 end
~~~ ~~~
What `Rakefile` describes is almost same as `Makefile` in the previous subsection. The contents of the `Rakefile` is almost same as the `Makefile` in the previous subsection.
- 3-6: Defines target file, source file and so on. - 3-6: Defines target file, source file and so on.
- 1, 8: Loads clean library. And defines CLEAN file list. - 1, 8: Loads clean library. And defines CLEAN file list.
The files included by CLEAN will be removed when `rake clean` is typed on the command line. The files included by CLEAN will be removed when `rake clean` is typed on the command line.
- 10: Default target depends on targetfile. - 10: The default target depends on `targetfile`.
Default is the final goal of tasks. The task `default` is the final goal of tasks.
- 12-14: Targetfile depends on objfiles. - 12-14: `targetfile` depends on `objfiles`.
The variable `t` is a task object. The variable `t` is a task object.
- t.name is a target name - `t.name` is a target name
- t.prerequisites is an array of prerequisites. - `t.prerequisites` is an array of prerequisites.
- t.source is the first element of prerequisites. - `t.source` is the first element of prerequisites.
- sh is a method to give the following string to shell as an argument and execute the shell. - `sh` is a method to give the following string to shell as an argument and executes the shell.
- 16-21: There's a loop by each element of the array of objfiles. Each object depends on corresponding source file. - 16-21: There's a loop by each element of the array of `objfiles`. Each object depends on corresponding source file.
- 23-25: Resource file depends on xml file and ui file. - 23-25: Resource file depends on xml file and ui file.
Rakefile might seem to be difficult for beginners. Rakefile might seem to be difficult for beginners.
But, you can use any ruby syntax in Rakefile, so it is really flexible. But, you can use any Ruby syntax in Rakefile, so it is really flexible.
If you practice Ruby and Rakefile, it will be highly productive tools. If you practice Ruby and Rakefile, it will be highly productive tools.
## Meson and ninja ## Meson and ninja
@ -352,16 +352,16 @@ The first parameter is the name of the project and the second is the programming
- 2: `dependency` function defines a dependency that is taken by `pkg-config`. - 2: `dependency` function defines a dependency that is taken by `pkg-config`.
We put `gtk4` as an argument. We put `gtk4` as an argument.
- 5: `import` function imports a module. - 5: `import` function imports a module.
In line 5, gnome module is imported and assigned to the variable `gnome`. In line 5, the gnome module is imported and assigned to the variable `gnome`.
gnome module provides helper tools to build GTK programs. The gnome module provides helper tools to build GTK programs.
- 6: `.compile_resources` is a method of gnome module and compile files to resources under the instruction of xml file. - 6: `.compile_resources` is a method of the gnome module and compiles files to resources under the instruction of xml file.
In line 6, the resource filename is `resources`, which means `resources.c` and `resources.h`, and xml file is `tfe.gresource.xml`. In line 6, the resource filename is `resources`, which means `resources.c` and `resources.h`, and xml file is `tfe.gresource.xml`.
This method generates C source file by default. This method generates C source file by default.
- 8: Defines source files. - 8: Defines source files.
- 10: Executable function generates a target file by building source files. - 10: Executable function generates a target file by compiling source files.
The first parameter is the filename of the target. The following parameters are source files. The first parameter is the filename of the target. The following parameters are source files.
The last parameter has a option `dependencies`. The last parameter is an option `dependencies`.
In line 10 it is `gtkdep` which is defined in line 3. `gtkdep` is used in the compilation.
Now run meson and ninja. Now run meson and ninja.

View file

@ -2,9 +2,9 @@ Up: [Readme.md](../Readme.md), Prev: [Section 10](sec10.md), Next: [Section 12]
# Instance and class # Instance and class
This section and the following four sections are explanations about the next version of the text file editor (tfe). A new version of the text file editor (`tfe`) will be made in this section and the following four sections.
It is tfe5. It is `tfe5`.
It has many changes from the prior version. There are many changes from the prior version.
All the sources are listed in [Section 16](sec16.md). All the sources are listed in [Section 16](sec16.md).
They are located in two directories, [src/tfe5](../src/tfe5) and [src/tfetextview](../src/tfetextview). They are located in two directories, [src/tfe5](../src/tfe5) and [src/tfetextview](../src/tfetextview).
@ -37,7 +37,8 @@ After that I will explain:
GObject and its children are objects, which have both class and instance. GObject and its children are objects, which have both class and instance.
First, think about instance of objects. First, think about instance of objects.
Instance is structured memories and described as C language structure. Instance is structured memory.
THe structure is described as C language structure.
The following is a structure of TfeTextView. The following is a structure of TfeTextView.
~~~C ~~~C
@ -52,12 +53,16 @@ struct _TfeTextView {
The members of the structure are: The members of the structure are:
- `parent` is the instance structure of GtkTextView which is the parent object of TfeTextView. - The type of `parent` is GtkTextView which is C structure.
It is declared in `gtktextview.h`.
GtkTextView is the parent of TfeTextView.
- `file` is a pointer to GFile. It can be NULL if no file corresponds to the TfeTextView object. - `file` is a pointer to GFile. It can be NULL if no file corresponds to the TfeTextView object.
Notice the program above is the declaration of the structure, not the definition. Notice the program above is the declaration of the structure, not the definition.
So, no memories are allocated at this moment. So, no memories are allocated at this moment.
They are to be allocated when `tfe_text_view_new` function is invoked. They are to be allocated when `tfe_text_view_new` function is invoked.
The memory allocated with `tfe_text_view_new` is an instance of TfeTextView object.
Therefore, There can be multiple TfeTextView instances if `tfe_text_view_new` is called multiple times.
You can find the declaration of the ancestors of TfeTextView in the source files of GTK and GLib. You can find the declaration of the ancestors of TfeTextView in the source files of GTK and GLib.
The following is extracts from the source files (not exactly the same). The following is extracts from the source files (not exactly the same).
@ -87,7 +92,7 @@ struct _GtkTextView
}; };
~~~ ~~~
In each structure, its parent instance is declared at the top of members. In each structure, its parent is declared at the top of the members.
So, every ancestors is included in the child instance. So, every ancestors is included in the child instance.
This is very important. This is very important.
It guarantees a child widget to inherit all the features from ancestors. It guarantees a child widget to inherit all the features from ancestors.
@ -96,9 +101,9 @@ The structure of `TfeTextView` is like the following diagram.
![The structure of the instance TfeTextView](../image/TfeTextView.png) ![The structure of the instance TfeTextView](../image/TfeTextView.png)
## Generate TfeTextView instance ## Create TfeTextView instance
The function `tfe_text_view_new` generates a new TfeTextView instance. The function `tfe_text_view_new` creates a new TfeTextView instance.
~~~C ~~~C
1 GtkWidget * 1 GtkWidget *
@ -117,8 +122,8 @@ When this function is run, the following procedure is gone through.
Step one through three is done automatically. Step one through three is done automatically.
Step four is done by the function `tfe_text_view_init`. Step four is done by the function `tfe_text_view_init`.
> In the same way, `gtk_text_view_init`, `gtk_widget_init` and `g_object_init` is the initialization functions of GtkTextView, GtkWidget and GObject respectively. In the same way, `gtk_text_view_init`, `gtk_widget_init` and `g_object_init` is the initialization functions of GtkTextView, GtkWidget and GObject respectively.
> You can find them in the GTK or GLib source files. You can find them in the GTK or GLib source files.
~~~C ~~~C
1 static void 1 static void
@ -141,8 +146,8 @@ We need at least two things.
One is functions and the other is class. One is functions and the other is class.
You've already seen many functions. You've already seen many functions.
For example, `tfe_text_view_new` is a function to generate TfeTextView instance. For example, `tfe_text_view_new` is a function to create a TfeTextView instance.
These functions are similar to object methods in object oriented languages such as Java or Ruby. These functions are similar to public object methods in object oriented languages such as Java or Ruby.
Functions are public, which means that they are expected to be used by other objects. Functions are public, which means that they are expected to be used by other objects.
Class comprises mainly pointers to functions. Class comprises mainly pointers to functions.
@ -153,34 +158,34 @@ For example, GObject class is declared in `gobject.h` in GLib source files.
1 typedef struct _GObjectClass GObjectClass; 1 typedef struct _GObjectClass GObjectClass;
2 typedef struct _GObjectClass GInitiallyUnownedClass; 2 typedef struct _GObjectClass GInitiallyUnownedClass;
3 3
4 struct _GObjectClass { 4 struct _GObjectClass
5 GTypeClass g_type_class; 5 {
6 /*< private >*/ 6 GTypeClass g_type_class;
7 GSList *construct_properties; 7 /*< private >*/
8 /*< public >*/ 8 GSList *construct_properties;
9 /* seldom overidden */ 9 /*< public >*/
10 GObject* (*constructor) (GType type, 10 /* seldom overridden */
11 guint n_construct_properties, 11 GObject* (*constructor) (GType type,
12 GObjectConstructParam *construct_properties); 12 guint n_construct_properties,
13 /* overridable methods */ 13 GObjectConstructParam *construct_properties);
14 void (*set_property) (GObject *object, 14 /* overridable methods */
15 guint property_id, 15 void (*set_property) (GObject *object,
16 const GValue *value, 16 guint property_id,
17 GParamSpec *pspec); 17 const GValue *value,
18 void (*get_property) (GObject *object, 18 GParamSpec *pspec);
19 guint property_id, 19 void (*get_property) (GObject *object,
20 GValue *value, 20 guint property_id,
21 GParamSpec *pspec); 21 GValue *value,
22 void (*dispose) (GObject *object); 22 GParamSpec *pspec);
23 void (*finalize) (GObject *object); 23 void (*dispose) (GObject *object);
24 /* seldom overidden */ 24 void (*finalize) (GObject *object);
25 void (*dispatch_properties_changed) (GObject *object, 25 /* seldom overridden */
26 guint n_pspecs, 26 void (*dispatch_properties_changed) (GObject *object,
27 GParamSpec **pspecs); 27 guint n_pspecs,
28 /* signals */ 28 GParamSpec **pspecs);
29 void (*notify) (GObject *object, 29 /* signals */
30 GParamSpec *pspec); 30 void (*notify) (GObject *object,
31 31 GParamSpec *pspec);
32 /* called when done constructing */ 32 /* called when done constructing */
33 void (*constructed) (GObject *object); 33 void (*constructed) (GObject *object);
34 /*< private >*/ 34 /*< private >*/
@ -188,10 +193,11 @@ For example, GObject class is declared in `gobject.h` in GLib source files.
36 /* padding */ 36 /* padding */
37 gpointer pdummy[6]; 37 gpointer pdummy[6];
38 }; 38 };
39
~~~ ~~~
I'd like to explain some of the members. I'd like to explain some of the members.
There's a pointer to the function `dispose` in line 22. There's a pointer to the function `dispose` in line 23.
~~~C ~~~C
void (*dispose) (GObject *object); void (*dispose) (GObject *object);
@ -200,7 +206,7 @@ void (*dispose) (GObject *object);
The declaration is a bit complicated. The declaration is a bit complicated.
The asterisk before the identifier `dispose` means pointer. The asterisk before the identifier `dispose` means pointer.
So, the pointer `dispose` points to a function which has one parameter, which points a GObject structure, and returns no value. So, the pointer `dispose` points to a function which has one parameter, which points a GObject structure, and returns no value.
In the same way, line 23 says `finalize` is a pointer to the function which has one parameter, which points a GObject structure, and returns no value. In the same way, line 24 says `finalize` is a pointer to the function which has one parameter, which points a GObject structure, and returns no value.
~~~C ~~~C
void (*finalize) (GObject *object); void (*finalize) (GObject *object);
@ -208,15 +214,19 @@ void (*finalize) (GObject *object);
Look at the declaration of `_GObjectClass` so that you would find that most of the members are pointers to functions. Look at the declaration of `_GObjectClass` so that you would find that most of the members are pointers to functions.
- 10: A function pointed by `constructor` is called when the instance is generated. It completes the initialization of the instance. - 11: A function pointed by `constructor` is called when the instance is generated. It completes the initialization of the instance.
- 22: A function pointed by `dispose` is called when the instance destructs itself. - 23: A function pointed by `dispose` is called when the instance destructs itself.
Destruction process is divided into two phases. Destruction process is divided into two phases.
The first one is called disposing. The first one is called disposing.
In this phase, the instance releases all the references to other instances. In this phase, the instance releases all the references to other instances.
The second phase is finalizing. The second phase is finalizing.
- 23: A function pointed by `finalize` finishes the destruction process. - 24: A function pointed by `finalize` finishes the destruction process.
- The other pointers point to functions which are called while the instance lives. - The other pointers point to functions which are called while the instance lives.
These functions are called class methods.
The methods are open to its descendants.
But not open to the objects which are not the descendants.
## TfeTextView class ## TfeTextView class
TfeTextView class is a structure and it includes all its ancestors' class in it. TfeTextView class is a structure and it includes all its ancestors' class in it.
@ -227,119 +237,134 @@ Let's look at all the classes from GObject, which is the top level object, to Tf
The following is extracts from the source files (not exactly the same). The following is extracts from the source files (not exactly the same).
~~~C ~~~C
1 struct _GtkWidgetClass { 1 struct _GtkWidgetClass
2 GInitiallyUnownedClass parent_class; 2 {
3 /*< public >*/ 3 GInitiallyUnownedClass parent_class;
4 guint activate_signal; 4
5 /* basics */ 5 /*< public >*/
6 void (* show) (GtkWidget *widget); 6
7 void (* hide) (GtkWidget *widget); 7 /* basics */
8 void (* map) (GtkWidget *widget); 8 void (* show) (GtkWidget *widget);
9 void (* unmap) (GtkWidget *widget); 9 void (* hide) (GtkWidget *widget);
10 void (* realize) (GtkWidget *widget); 10 void (* map) (GtkWidget *widget);
11 void (* unrealize) (GtkWidget *widget); 11 void (* unmap) (GtkWidget *widget);
12 void (* root) (GtkWidget *widget); 12 void (* realize) (GtkWidget *widget);
13 void (* unroot) (GtkWidget *widget); 13 void (* unrealize) (GtkWidget *widget);
14 void (* size_allocate) (GtkWidget *widget, 14 void (* root) (GtkWidget *widget);
15 int width, 15 void (* unroot) (GtkWidget *widget);
16 int height, 16 void (* size_allocate) (GtkWidget *widget,
17 int baseline); 17 int width,
18 void (* state_flags_changed) (GtkWidget *widget, 18 int height,
19 GtkStateFlags previous_state_flags); 19 int baseline);
20 void (* direction_changed) (GtkWidget *widget, 20 void (* state_flags_changed) (GtkWidget *widget,
21 GtkTextDirection previous_direction); 21 GtkStateFlags previous_state_flags);
22 void (* grab_notify) (GtkWidget *widget, 22 void (* direction_changed) (GtkWidget *widget,
23 gboolean was_grabbed); 23 GtkTextDirection previous_direction);
24 /* size requests */ 24
25 GtkSizeRequestMode (* get_request_mode) (GtkWidget *widget); 25 /* size requests */
26 void (* measure) (GtkWidget *widget, 26 GtkSizeRequestMode (* get_request_mode) (GtkWidget *widget);
27 GtkOrientation orientation, 27 void (* measure) (GtkWidget *widget,
28 int for_size, 28 GtkOrientation orientation,
29 int *minimum, 29 int for_size,
30 int *natural, 30 int *minimum,
31 int *minimum_baseline, 31 int *natural,
32 int *natural_baseline); 32 int *minimum_baseline,
33 /* Mnemonics */ 33 int *natural_baseline);
34 gboolean (* mnemonic_activate) (GtkWidget *widget, 34
35 gboolean group_cycling); 35 /* Mnemonics */
36 /* explicit focus */ 36 gboolean (* mnemonic_activate) (GtkWidget *widget,
37 gboolean (* grab_focus) (GtkWidget *widget); 37 gboolean group_cycling);
38 gboolean (* focus) (GtkWidget *widget, 38
39 GtkDirectionType direction); 39 /* explicit focus */
40 void (* set_focus_child) (GtkWidget *widget, 40 gboolean (* grab_focus) (GtkWidget *widget);
41 GtkWidget *child); 41 gboolean (* focus) (GtkWidget *widget,
42 /* keyboard navigation */ 42 GtkDirectionType direction);
43 void (* move_focus) (GtkWidget *widget, 43 void (* set_focus_child) (GtkWidget *widget,
44 GtkDirectionType direction); 44 GtkWidget *child);
45 gboolean (* keynav_failed) (GtkWidget *widget, 45
46 GtkDirectionType direction); 46 /* keyboard navigation */
47 /* accessibility support 47 void (* move_focus) (GtkWidget *widget,
48 */ 48 GtkDirectionType direction);
49 AtkObject * (* get_accessible) (GtkWidget *widget); 49 gboolean (* keynav_failed) (GtkWidget *widget,
50 gboolean (* query_tooltip) (GtkWidget *widget, 50 GtkDirectionType direction);
51 gint x, 51
52 gint y, 52 gboolean (* query_tooltip) (GtkWidget *widget,
53 gboolean keyboard_tooltip, 53 int x,
54 GtkTooltip *tooltip); 54 int y,
55 void (* compute_expand) (GtkWidget *widget, 55 gboolean keyboard_tooltip,
56 gboolean *hexpand_p, 56 GtkTooltip *tooltip);
57 gboolean *vexpand_p); 57
58 void (* css_changed) (GtkWidget *widget, 58 void (* compute_expand) (GtkWidget *widget,
59 GtkCssStyleChange *change); 59 gboolean *hexpand_p,
60 void (* system_setting_changed) (GtkWidget *widget, 60 gboolean *vexpand_p);
61 GtkSystemSetting settings); 61
62 void (* snapshot) (GtkWidget *widget, 62 void (* css_changed) (GtkWidget *widget,
63 GtkSnapshot *snapshot); 63 GtkCssStyleChange *change);
64 gboolean (* contains) (GtkWidget *widget, 64
65 gdouble x, 65 void (* system_setting_changed) (GtkWidget *widget,
66 gdouble y); 66 GtkSystemSetting settings);
67 /*< private >*/ 67
68 GtkWidgetClassPrivate *priv; 68 void (* snapshot) (GtkWidget *widget,
69 gpointer padding[8]; 69 GtkSnapshot *snapshot);
70 }; 70
71 71 gboolean (* contains) (GtkWidget *widget,
72 struct _GtkTextViewClass { 72 double x,
73 GtkWidgetClass parent_class; 73 double y);
74 /*< public >*/ 74
75 void (* move_cursor) (GtkTextView *text_view, 75 /*< private >*/
76 GtkMovementStep step, 76
77 gint count, 77 GtkWidgetClassPrivate *priv;
78 gboolean extend_selection); 78
79 void (* set_anchor) (GtkTextView *text_view); 79 gpointer padding[8];
80 void (* insert_at_cursor) (GtkTextView *text_view, 80 };
81 const gchar *str); 81
82 void (* delete_from_cursor) (GtkTextView *text_view, 82 struct _GtkTextViewClass
83 GtkDeleteType type, 83 {
84 gint count); 84 GtkWidgetClass parent_class;
85 void (* backspace) (GtkTextView *text_view); 85
86 void (* cut_clipboard) (GtkTextView *text_view); 86 /*< public >*/
87 void (* copy_clipboard) (GtkTextView *text_view); 87
88 void (* paste_clipboard) (GtkTextView *text_view); 88 void (* move_cursor) (GtkTextView *text_view,
89 void (* toggle_overwrite) (GtkTextView *text_view); 89 GtkMovementStep step,
90 GtkTextBuffer * (* create_buffer) (GtkTextView *text_view); 90 int count,
91 void (* snapshot_layer) (GtkTextView *text_view, 91 gboolean extend_selection);
92 GtkTextViewLayer layer, 92 void (* set_anchor) (GtkTextView *text_view);
93 GtkSnapshot *snapshot); 93 void (* insert_at_cursor) (GtkTextView *text_view,
94 gboolean (* extend_selection) (GtkTextView *text_view, 94 const char *str);
95 GtkTextExtendSelection granularity, 95 void (* delete_from_cursor) (GtkTextView *text_view,
96 const GtkTextIter *location, 96 GtkDeleteType type,
97 GtkTextIter *start, 97 int count);
98 GtkTextIter *end); 98 void (* backspace) (GtkTextView *text_view);
99 void (* insert_emoji) (GtkTextView *text_view); 99 void (* cut_clipboard) (GtkTextView *text_view);
100 /*< private >*/ 100 void (* copy_clipboard) (GtkTextView *text_view);
101 gpointer padding[8]; 101 void (* paste_clipboard) (GtkTextView *text_view);
102 }; 102 void (* toggle_overwrite) (GtkTextView *text_view);
103 103 GtkTextBuffer * (* create_buffer) (GtkTextView *text_view);
104 /* The following definition is generated by the macro G_DECLARE_FINAL_TYPE */ 104 void (* snapshot_layer) (GtkTextView *text_view,
105 typedef struct { 105 GtkTextViewLayer layer,
106 GtkTextView parent_class; 106 GtkSnapshot *snapshot);
107 } TfeTextViewClass; 107 gboolean (* extend_selection) (GtkTextView *text_view,
108 108 GtkTextExtendSelection granularity,
109 const GtkTextIter *location,
110 GtkTextIter *start,
111 GtkTextIter *end);
112 void (* insert_emoji) (GtkTextView *text_view);
113
114 /*< private >*/
115
116 gpointer padding[8];
117 };
118
119 /* The following definition is generated by the macro G_DECLARE_FINAL_TYPE */
120 typedef struct {
121 GtkTextView parent_class;
122 } TfeTextViewClass;
123
~~~ ~~~
- 105-107: This three lines are generated by the macro G\_DECLARE\_FINAL\_TYPE. - 120-122: This three lines are generated by the macro `G_DECLARE_FINAL_TYPE`.
So, they are not written in either `tfe_text_view.h` or `tfe_text_view.c`. So, they are not written in either `tfe_text_view.h` or `tfe_text_view.c`.
- 2, 73, 106: Each derived class puts its parent class at the first member of its structure. - 3, 84, 121: Each derived class puts its parent class at the first member of its structure.
It is the same as instance structures. It is the same as instance structures.
- Class members in ancestors are open to the descendant class. - Class members in ancestors are open to the descendant class.
So, they can be changed in `tfe_text_view_class_init` function. So, they can be changed in `tfe_text_view_class_init` function.
@ -413,7 +438,7 @@ tfe_text_view_class_init (TfeTextViewClass *class) {
} }
~~~ ~~~
Each ancestors' class has been generated before TfeTextViewClass is generated. Each ancestors' class has been created before TfeTextViewClass is created.
Therefore, there are four classes and each class has a pointer to each dispose handler. Therefore, there are four classes and each class has a pointer to each dispose handler.
Look at the following diagram. Look at the following diagram.
There are four classes -- GObjectClass (GInitiallyUnownedClass), GtkWidgetClass, GtkTextViewClass and TfeTextViewClass. There are four classes -- GObjectClass (GInitiallyUnownedClass), GtkWidgetClass, GtkTextViewClass and TfeTextViewClass.

View file

@ -1,12 +1,13 @@
typedef struct _GObjectClass GObjectClass; typedef struct _GObjectClass GObjectClass;
typedef struct _GObjectClass GInitiallyUnownedClass; typedef struct _GObjectClass GInitiallyUnownedClass;
struct _GObjectClass { struct _GObjectClass
{
GTypeClass g_type_class; GTypeClass g_type_class;
/*< private >*/ /*< private >*/
GSList *construct_properties; GSList *construct_properties;
/*< public >*/ /*< public >*/
/* seldom overidden */ /* seldom overridden */
GObject* (*constructor) (GType type, GObject* (*constructor) (GType type,
guint n_construct_properties, guint n_construct_properties,
GObjectConstructParam *construct_properties); GObjectConstructParam *construct_properties);
@ -21,14 +22,13 @@ struct _GObjectClass {
GParamSpec *pspec); GParamSpec *pspec);
void (*dispose) (GObject *object); void (*dispose) (GObject *object);
void (*finalize) (GObject *object); void (*finalize) (GObject *object);
/* seldom overidden */ /* seldom overridden */
void (*dispatch_properties_changed) (GObject *object, void (*dispatch_properties_changed) (GObject *object,
guint n_pspecs, guint n_pspecs,
GParamSpec **pspecs); GParamSpec **pspecs);
/* signals */ /* signals */
void (*notify) (GObject *object, void (*notify) (GObject *object,
GParamSpec *pspec); GParamSpec *pspec);
/* called when done constructing */ /* called when done constructing */
void (*constructed) (GObject *object); void (*constructed) (GObject *object);
/*< private >*/ /*< private >*/
@ -36,3 +36,4 @@ struct _GObjectClass {
/* padding */ /* padding */
gpointer pdummy[6]; gpointer pdummy[6];
}; };

View file

@ -1,7 +1,9 @@
struct _GtkWidgetClass { struct _GtkWidgetClass
{
GInitiallyUnownedClass parent_class; GInitiallyUnownedClass parent_class;
/*< public >*/ /*< public >*/
guint activate_signal;
/* basics */ /* basics */
void (* show) (GtkWidget *widget); void (* show) (GtkWidget *widget);
void (* hide) (GtkWidget *widget); void (* hide) (GtkWidget *widget);
@ -19,8 +21,7 @@ struct _GtkWidgetClass {
GtkStateFlags previous_state_flags); GtkStateFlags previous_state_flags);
void (* direction_changed) (GtkWidget *widget, void (* direction_changed) (GtkWidget *widget,
GtkTextDirection previous_direction); GtkTextDirection previous_direction);
void (* grab_notify) (GtkWidget *widget,
gboolean was_grabbed);
/* size requests */ /* size requests */
GtkSizeRequestMode (* get_request_mode) (GtkWidget *widget); GtkSizeRequestMode (* get_request_mode) (GtkWidget *widget);
void (* measure) (GtkWidget *widget, void (* measure) (GtkWidget *widget,
@ -30,58 +31,70 @@ struct _GtkWidgetClass {
int *natural, int *natural,
int *minimum_baseline, int *minimum_baseline,
int *natural_baseline); int *natural_baseline);
/* Mnemonics */ /* Mnemonics */
gboolean (* mnemonic_activate) (GtkWidget *widget, gboolean (* mnemonic_activate) (GtkWidget *widget,
gboolean group_cycling); gboolean group_cycling);
/* explicit focus */ /* explicit focus */
gboolean (* grab_focus) (GtkWidget *widget); gboolean (* grab_focus) (GtkWidget *widget);
gboolean (* focus) (GtkWidget *widget, gboolean (* focus) (GtkWidget *widget,
GtkDirectionType direction); GtkDirectionType direction);
void (* set_focus_child) (GtkWidget *widget, void (* set_focus_child) (GtkWidget *widget,
GtkWidget *child); GtkWidget *child);
/* keyboard navigation */ /* keyboard navigation */
void (* move_focus) (GtkWidget *widget, void (* move_focus) (GtkWidget *widget,
GtkDirectionType direction); GtkDirectionType direction);
gboolean (* keynav_failed) (GtkWidget *widget, gboolean (* keynav_failed) (GtkWidget *widget,
GtkDirectionType direction); GtkDirectionType direction);
/* accessibility support
*/
AtkObject * (* get_accessible) (GtkWidget *widget);
gboolean (* query_tooltip) (GtkWidget *widget, gboolean (* query_tooltip) (GtkWidget *widget,
gint x, int x,
gint y, int y,
gboolean keyboard_tooltip, gboolean keyboard_tooltip,
GtkTooltip *tooltip); GtkTooltip *tooltip);
void (* compute_expand) (GtkWidget *widget, void (* compute_expand) (GtkWidget *widget,
gboolean *hexpand_p, gboolean *hexpand_p,
gboolean *vexpand_p); gboolean *vexpand_p);
void (* css_changed) (GtkWidget *widget, void (* css_changed) (GtkWidget *widget,
GtkCssStyleChange *change); GtkCssStyleChange *change);
void (* system_setting_changed) (GtkWidget *widget, void (* system_setting_changed) (GtkWidget *widget,
GtkSystemSetting settings); GtkSystemSetting settings);
void (* snapshot) (GtkWidget *widget, void (* snapshot) (GtkWidget *widget,
GtkSnapshot *snapshot); GtkSnapshot *snapshot);
gboolean (* contains) (GtkWidget *widget, gboolean (* contains) (GtkWidget *widget,
gdouble x, double x,
gdouble y); double y);
/*< private >*/ /*< private >*/
GtkWidgetClassPrivate *priv; GtkWidgetClassPrivate *priv;
gpointer padding[8]; gpointer padding[8];
}; };
struct _GtkTextViewClass { struct _GtkTextViewClass
{
GtkWidgetClass parent_class; GtkWidgetClass parent_class;
/*< public >*/ /*< public >*/
void (* move_cursor) (GtkTextView *text_view, void (* move_cursor) (GtkTextView *text_view,
GtkMovementStep step, GtkMovementStep step,
gint count, int count,
gboolean extend_selection); gboolean extend_selection);
void (* set_anchor) (GtkTextView *text_view); void (* set_anchor) (GtkTextView *text_view);
void (* insert_at_cursor) (GtkTextView *text_view, void (* insert_at_cursor) (GtkTextView *text_view,
const gchar *str); const char *str);
void (* delete_from_cursor) (GtkTextView *text_view, void (* delete_from_cursor) (GtkTextView *text_view,
GtkDeleteType type, GtkDeleteType type,
gint count); int count);
void (* backspace) (GtkTextView *text_view); void (* backspace) (GtkTextView *text_view);
void (* cut_clipboard) (GtkTextView *text_view); void (* cut_clipboard) (GtkTextView *text_view);
void (* copy_clipboard) (GtkTextView *text_view); void (* copy_clipboard) (GtkTextView *text_view);
@ -97,7 +110,9 @@ struct _GtkTextViewClass {
GtkTextIter *start, GtkTextIter *start,
GtkTextIter *end); GtkTextIter *end);
void (* insert_emoji) (GtkTextView *text_view); void (* insert_emoji) (GtkTextView *text_view);
/*< private >*/ /*< private >*/
gpointer padding[8]; gpointer padding[8];
}; };

View file

@ -19,7 +19,7 @@ For example, our source has two things, the definition of TfeTextView and functi
It is a good idea to separate them into two files, `tfetextview.c` and `tfe.c`. It is a good idea to separate them into two files, `tfetextview.c` and `tfe.c`.
- `tfetextview.c` includes the definition and functions of TfeTextView. - `tfetextview.c` includes the definition and functions of TfeTextView.
- `tfe.c` includes functions like `main`, `on_activate`, `on_open` and so on, which relate to GtkApplication and GtkApplicationWindow - `tfe.c` includes functions like `main`, `app_activate`, `app_open` and so on, which relate to GtkApplication and GtkApplicationWindow
Now we have three source files, `tfetextview.c`, `tfe.c` and `tfe3.ui`. Now we have three source files, `tfetextview.c`, `tfe.c` and `tfe3.ui`.
The `3` of `tfe3.ui` is like a version number. The `3` of `tfe3.ui` is like a version number.
@ -27,7 +27,7 @@ Managing version with filenames is one possible idea but it may make bothersome
You need to rewrite filename in each version and it affects to contents of source files that refer to filenames. You need to rewrite filename in each version and it affects to contents of source files that refer to filenames.
So, we should take `3` away from the filename. So, we should take `3` away from the filename.
In `tfe.c` the function `tfe_text_view_new` is invoked to generate TfeTextView. In `tfe.c` the function `tfe_text_view_new` is invoked to create a TfeTextView instance.
But it is defined in `tfetextview.c`, not `tfe.c`. But it is defined in `tfetextview.c`, not `tfe.c`.
The lack of the declaration (not definition) of `tfe_text_view_new` makes error when `tfe.c` is compiled. The lack of the declaration (not definition) of `tfe_text_view_new` makes error when `tfe.c` is compiled.
The declaration is necessary in `tfe.c`. The declaration is necessary in `tfe.c`.
@ -89,7 +89,7 @@ sample.o: sample.c
gcc -o sample.o sample.c gcc -o sample.o sample.c
~~~ ~~~
The sample of Malefile above consists of three elements, `sample.o`, `sample.c` and `gcc -0 sample.o sample.c`. The sample of Malefile above consists of three elements, `sample.o`, `sample.c` and `gcc -o sample.o sample.c`.
- `sample.o` is called target. - `sample.o` is called target.
- `sample.c` is prerequisite. - `sample.c` is prerequisite.
@ -132,7 +132,7 @@ If you don't use Ruby, you don't need to read this subsection.
However, Ruby is really sophisticated and recommendable script language. However, Ruby is really sophisticated and recommendable script language.
- Rakefile controls the behavior of `rake`. - Rakefile controls the behavior of `rake`.
- You can write any ruby code in Rakefile. - You can write any Ruby code in Rakefile.
Rake has task and file task, which is similar to target, prerequisite and recipe in make. Rake has task and file task, which is similar to target, prerequisite and recipe in make.
@ -140,24 +140,24 @@ Rake has task and file task, which is similar to target, prerequisite and recipe
tfe4/Rakefile tfe4/Rakefile
@@@ @@@
What `Rakefile` describes is almost same as `Makefile` in the previous subsection. The contents of the `Rakefile` is almost same as the `Makefile` in the previous subsection.
- 3-6: Defines target file, source file and so on. - 3-6: Defines target file, source file and so on.
- 1, 8: Loads clean library. And defines CLEAN file list. - 1, 8: Loads clean library. And defines CLEAN file list.
The files included by CLEAN will be removed when `rake clean` is typed on the command line. The files included by CLEAN will be removed when `rake clean` is typed on the command line.
- 10: Default target depends on targetfile. - 10: The default target depends on `targetfile`.
Default is the final goal of tasks. The task `default` is the final goal of tasks.
- 12-14: Targetfile depends on objfiles. - 12-14: `targetfile` depends on `objfiles`.
The variable `t` is a task object. The variable `t` is a task object.
- t.name is a target name - `t.name` is a target name
- t.prerequisites is an array of prerequisites. - `t.prerequisites` is an array of prerequisites.
- t.source is the first element of prerequisites. - `t.source` is the first element of prerequisites.
- sh is a method to give the following string to shell as an argument and execute the shell. - `sh` is a method to give the following string to shell as an argument and executes the shell.
- 16-21: There's a loop by each element of the array of objfiles. Each object depends on corresponding source file. - 16-21: There's a loop by each element of the array of `objfiles`. Each object depends on corresponding source file.
- 23-25: Resource file depends on xml file and ui file. - 23-25: Resource file depends on xml file and ui file.
Rakefile might seem to be difficult for beginners. Rakefile might seem to be difficult for beginners.
But, you can use any ruby syntax in Rakefile, so it is really flexible. But, you can use any Ruby syntax in Rakefile, so it is really flexible.
If you practice Ruby and Rakefile, it will be highly productive tools. If you practice Ruby and Rakefile, it will be highly productive tools.
## Meson and ninja ## Meson and ninja
@ -179,16 +179,16 @@ The first parameter is the name of the project and the second is the programming
- 2: `dependency` function defines a dependency that is taken by `pkg-config`. - 2: `dependency` function defines a dependency that is taken by `pkg-config`.
We put `gtk4` as an argument. We put `gtk4` as an argument.
- 5: `import` function imports a module. - 5: `import` function imports a module.
In line 5, gnome module is imported and assigned to the variable `gnome`. In line 5, the gnome module is imported and assigned to the variable `gnome`.
gnome module provides helper tools to build GTK programs. The gnome module provides helper tools to build GTK programs.
- 6: `.compile_resources` is a method of gnome module and compile files to resources under the instruction of xml file. - 6: `.compile_resources` is a method of the gnome module and compiles files to resources under the instruction of xml file.
In line 6, the resource filename is `resources`, which means `resources.c` and `resources.h`, and xml file is `tfe.gresource.xml`. In line 6, the resource filename is `resources`, which means `resources.c` and `resources.h`, and xml file is `tfe.gresource.xml`.
This method generates C source file by default. This method generates C source file by default.
- 8: Defines source files. - 8: Defines source files.
- 10: Executable function generates a target file by building source files. - 10: Executable function generates a target file by compiling source files.
The first parameter is the filename of the target. The following parameters are source files. The first parameter is the filename of the target. The following parameters are source files.
The last parameter has a option `dependencies`. The last parameter is an option `dependencies`.
In line 10 it is `gtkdep` which is defined in line 3. `gtkdep` is used in the compilation.
Now run meson and ninja. Now run meson and ninja.

View file

@ -1,8 +1,8 @@
# Instance and class # Instance and class
This section and the following four sections are explanations about the next version of the text file editor (tfe). A new version of the text file editor (`tfe`) will be made in this section and the following four sections.
It is tfe5. It is `tfe5`.
It has many changes from the prior version. There are many changes from the prior version.
All the sources are listed in [Section 16](sec16.src.md). All the sources are listed in [Section 16](sec16.src.md).
They are located in two directories, [src/tfe5](tfe5) and [src/tfetextview](tfetextview). They are located in two directories, [src/tfe5](tfe5) and [src/tfetextview](tfetextview).
@ -35,7 +35,8 @@ After that I will explain:
GObject and its children are objects, which have both class and instance. GObject and its children are objects, which have both class and instance.
First, think about instance of objects. First, think about instance of objects.
Instance is structured memories and described as C language structure. Instance is structured memory.
THe structure is described as C language structure.
The following is a structure of TfeTextView. The following is a structure of TfeTextView.
~~~C ~~~C
@ -50,12 +51,16 @@ struct _TfeTextView {
The members of the structure are: The members of the structure are:
- `parent` is the instance structure of GtkTextView which is the parent object of TfeTextView. - The type of `parent` is GtkTextView which is C structure.
It is declared in `gtktextview.h`.
GtkTextView is the parent of TfeTextView.
- `file` is a pointer to GFile. It can be NULL if no file corresponds to the TfeTextView object. - `file` is a pointer to GFile. It can be NULL if no file corresponds to the TfeTextView object.
Notice the program above is the declaration of the structure, not the definition. Notice the program above is the declaration of the structure, not the definition.
So, no memories are allocated at this moment. So, no memories are allocated at this moment.
They are to be allocated when `tfe_text_view_new` function is invoked. They are to be allocated when `tfe_text_view_new` function is invoked.
The memory allocated with `tfe_text_view_new` is an instance of TfeTextView object.
Therefore, There can be multiple TfeTextView instances if `tfe_text_view_new` is called multiple times.
You can find the declaration of the ancestors of TfeTextView in the source files of GTK and GLib. You can find the declaration of the ancestors of TfeTextView in the source files of GTK and GLib.
The following is extracts from the source files (not exactly the same). The following is extracts from the source files (not exactly the same).
@ -85,7 +90,7 @@ struct _GtkTextView
}; };
~~~ ~~~
In each structure, its parent instance is declared at the top of members. In each structure, its parent is declared at the top of the members.
So, every ancestors is included in the child instance. So, every ancestors is included in the child instance.
This is very important. This is very important.
It guarantees a child widget to inherit all the features from ancestors. It guarantees a child widget to inherit all the features from ancestors.
@ -94,9 +99,9 @@ The structure of `TfeTextView` is like the following diagram.
![The structure of the instance TfeTextView](../image/TfeTextView.png){width=14.39cm height=2.16cm} ![The structure of the instance TfeTextView](../image/TfeTextView.png){width=14.39cm height=2.16cm}
## Generate TfeTextView instance ## Create TfeTextView instance
The function `tfe_text_view_new` generates a new TfeTextView instance. The function `tfe_text_view_new` creates a new TfeTextView instance.
@@@include @@@include
tfetextview/tfetextview.c tfe_text_view_new tfetextview/tfetextview.c tfe_text_view_new
@ -112,8 +117,8 @@ When this function is run, the following procedure is gone through.
Step one through three is done automatically. Step one through three is done automatically.
Step four is done by the function `tfe_text_view_init`. Step four is done by the function `tfe_text_view_init`.
> In the same way, `gtk_text_view_init`, `gtk_widget_init` and `g_object_init` is the initialization functions of GtkTextView, GtkWidget and GObject respectively. In the same way, `gtk_text_view_init`, `gtk_widget_init` and `g_object_init` is the initialization functions of GtkTextView, GtkWidget and GObject respectively.
> You can find them in the GTK or GLib source files. You can find them in the GTK or GLib source files.
@@@include @@@include
tfetextview/tfetextview.c tfe_text_view_init tfetextview/tfetextview.c tfe_text_view_init
@ -133,8 +138,8 @@ We need at least two things.
One is functions and the other is class. One is functions and the other is class.
You've already seen many functions. You've already seen many functions.
For example, `tfe_text_view_new` is a function to generate TfeTextView instance. For example, `tfe_text_view_new` is a function to create a TfeTextView instance.
These functions are similar to object methods in object oriented languages such as Java or Ruby. These functions are similar to public object methods in object oriented languages such as Java or Ruby.
Functions are public, which means that they are expected to be used by other objects. Functions are public, which means that they are expected to be used by other objects.
Class comprises mainly pointers to functions. Class comprises mainly pointers to functions.
@ -146,7 +151,7 @@ class_gobject.c
@@@ @@@
I'd like to explain some of the members. I'd like to explain some of the members.
There's a pointer to the function `dispose` in line 22. There's a pointer to the function `dispose` in line 23.
~~~C ~~~C
void (*dispose) (GObject *object); void (*dispose) (GObject *object);
@ -155,7 +160,7 @@ void (*dispose) (GObject *object);
The declaration is a bit complicated. The declaration is a bit complicated.
The asterisk before the identifier `dispose` means pointer. The asterisk before the identifier `dispose` means pointer.
So, the pointer `dispose` points to a function which has one parameter, which points a GObject structure, and returns no value. So, the pointer `dispose` points to a function which has one parameter, which points a GObject structure, and returns no value.
In the same way, line 23 says `finalize` is a pointer to the function which has one parameter, which points a GObject structure, and returns no value. In the same way, line 24 says `finalize` is a pointer to the function which has one parameter, which points a GObject structure, and returns no value.
~~~C ~~~C
void (*finalize) (GObject *object); void (*finalize) (GObject *object);
@ -163,15 +168,19 @@ void (*finalize) (GObject *object);
Look at the declaration of `_GObjectClass` so that you would find that most of the members are pointers to functions. Look at the declaration of `_GObjectClass` so that you would find that most of the members are pointers to functions.
- 10: A function pointed by `constructor` is called when the instance is generated. It completes the initialization of the instance. - 11: A function pointed by `constructor` is called when the instance is generated. It completes the initialization of the instance.
- 22: A function pointed by `dispose` is called when the instance destructs itself. - 23: A function pointed by `dispose` is called when the instance destructs itself.
Destruction process is divided into two phases. Destruction process is divided into two phases.
The first one is called disposing. The first one is called disposing.
In this phase, the instance releases all the references to other instances. In this phase, the instance releases all the references to other instances.
The second phase is finalizing. The second phase is finalizing.
- 23: A function pointed by `finalize` finishes the destruction process. - 24: A function pointed by `finalize` finishes the destruction process.
- The other pointers point to functions which are called while the instance lives. - The other pointers point to functions which are called while the instance lives.
These functions are called class methods.
The methods are open to its descendants.
But not open to the objects which are not the descendants.
## TfeTextView class ## TfeTextView class
TfeTextView class is a structure and it includes all its ancestors' class in it. TfeTextView class is a structure and it includes all its ancestors' class in it.
@ -185,9 +194,9 @@ The following is extracts from the source files (not exactly the same).
classes.c classes.c
@@@ @@@
- 105-107: This three lines are generated by the macro G\_DECLARE\_FINAL\_TYPE. - 120-122: This three lines are generated by the macro `G_DECLARE_FINAL_TYPE`.
So, they are not written in either `tfe_text_view.h` or `tfe_text_view.c`. So, they are not written in either `tfe_text_view.h` or `tfe_text_view.c`.
- 2, 73, 106: Each derived class puts its parent class at the first member of its structure. - 3, 84, 121: Each derived class puts its parent class at the first member of its structure.
It is the same as instance structures. It is the same as instance structures.
- Class members in ancestors are open to the descendant class. - Class members in ancestors are open to the descendant class.
So, they can be changed in `tfe_text_view_class_init` function. So, they can be changed in `tfe_text_view_class_init` function.
@ -253,7 +262,7 @@ tfe_text_view_class_init (TfeTextViewClass *class) {
} }
~~~ ~~~
Each ancestors' class has been generated before TfeTextViewClass is generated. Each ancestors' class has been created before TfeTextViewClass is created.
Therefore, there are four classes and each class has a pointer to each dispose handler. Therefore, there are four classes and each class has a pointer to each dispose handler.
Look at the following diagram. Look at the following diagram.
There are four classes -- GObjectClass (GInitiallyUnownedClass), GtkWidgetClass, GtkTextViewClass and TfeTextViewClass. There are four classes -- GObjectClass (GInitiallyUnownedClass), GtkWidgetClass, GtkTextViewClass and TfeTextViewClass.

View file

@ -2,12 +2,12 @@
#include "tfetextview.h" #include "tfetextview.h"
static void static void
on_activate (GApplication *app, gpointer user_data) { app_activate (GApplication *app, gpointer user_data) {
g_print ("You need a filename argument.\n"); g_print ("You need a filename argument.\n");
} }
static void static void
on_open (GApplication *app, GFile ** files, gint n_files, gchar *hint, gpointer user_data) { app_open (GApplication *app, GFile ** files, gint n_files, gchar *hint, gpointer user_data) {
GtkWidget *win; GtkWidget *win;
GtkWidget *nb; GtkWidget *nb;
GtkWidget *lab; GtkWidget *lab;
@ -43,11 +43,11 @@ on_open (GApplication *app, GFile ** files, gint n_files, gchar *hint, gpointer
nbp = gtk_notebook_get_page (GTK_NOTEBOOK (nb), scr); nbp = gtk_notebook_get_page (GTK_NOTEBOOK (nb), scr);
g_object_set (nbp, "tab-expand", TRUE, NULL); g_object_set (nbp, "tab-expand", TRUE, NULL);
g_free (filename); g_free (filename);
} else { } else if ((filename = g_file_get_path (files[i])) != NULL) {
filename = g_file_get_path (files[i]);
g_print ("No such file: %s.\n", filename); g_print ("No such file: %s.\n", filename);
g_free (filename); g_free (filename);
} } else
g_print ("No valid file is given\n");
} }
if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)) > 0) { if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)) > 0) {
gtk_widget_show (win); gtk_widget_show (win);
@ -60,9 +60,9 @@ main (int argc, char **argv) {
GtkApplication *app; GtkApplication *app;
int stat; int stat;
app = gtk_application_new ("com.github.ToshioCP.tfe3", G_APPLICATION_HANDLES_OPEN); app = gtk_application_new ("com.github.ToshioCP.tfe", G_APPLICATION_HANDLES_OPEN);
g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
g_signal_connect (app, "open", G_CALLBACK (on_open), NULL); g_signal_connect (app, "open", G_CALLBACK (app_open), NULL);
stat =g_application_run (G_APPLICATION (app), argc, argv); stat =g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app); g_object_unref (app);
return stat; return stat;