mirror of
https://github.com/ToshioCP/Gtk4-tutorial.git
synced 2025-01-12 20:03:28 +01:00
Modify section 10 and 11.
This commit is contained in:
parent
cbd454c85b
commit
f4308b83c1
7 changed files with 327 additions and 277 deletions
60
gfm/sec10.md
60
gfm/sec10.md
|
@ -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.
|
||||||
|
|
||||||
|
|
343
gfm/sec11.md
343
gfm/sec11.md
|
@ -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,45 +158,46 @@ 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 >*/
|
||||||
35 gsize flags;
|
35 gsize flags;
|
||||||
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.
|
||||||
|
|
|
@ -1,38 +1,39 @@
|
||||||
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);
|
||||||
/* overridable methods */
|
/* overridable methods */
|
||||||
void (*set_property) (GObject *object,
|
void (*set_property) (GObject *object,
|
||||||
guint property_id,
|
guint property_id,
|
||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec);
|
GParamSpec *pspec);
|
||||||
void (*get_property) (GObject *object,
|
void (*get_property) (GObject *object,
|
||||||
guint property_id,
|
guint property_id,
|
||||||
GValue *value,
|
GValue *value,
|
||||||
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 >*/
|
||||||
gsize flags;
|
gsize flags;
|
||||||
/* padding */
|
/* padding */
|
||||||
gpointer pdummy[6];
|
gpointer pdummy[6];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
@ -89,15 +102,17 @@ struct _GtkTextViewClass {
|
||||||
void (* toggle_overwrite) (GtkTextView *text_view);
|
void (* toggle_overwrite) (GtkTextView *text_view);
|
||||||
GtkTextBuffer * (* create_buffer) (GtkTextView *text_view);
|
GtkTextBuffer * (* create_buffer) (GtkTextView *text_view);
|
||||||
void (* snapshot_layer) (GtkTextView *text_view,
|
void (* snapshot_layer) (GtkTextView *text_view,
|
||||||
GtkTextViewLayer layer,
|
GtkTextViewLayer layer,
|
||||||
GtkSnapshot *snapshot);
|
GtkSnapshot *snapshot);
|
||||||
gboolean (* extend_selection) (GtkTextView *text_view,
|
gboolean (* extend_selection) (GtkTextView *text_view,
|
||||||
GtkTextExtendSelection granularity,
|
GtkTextExtendSelection granularity,
|
||||||
const GtkTextIter *location,
|
const GtkTextIter *location,
|
||||||
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];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue