mirror of
https://github.com/ToshioCP/Gtk4-tutorial.git
synced 2025-01-12 20:03:28 +01:00
Indented block is replaced by fenced block. fixed #2.
This commit is contained in:
parent
880dd92c82
commit
7f4442e07a
18 changed files with 456 additions and 296 deletions
12
gfm/sec10.md
12
gfm/sec10.md
|
@ -39,6 +39,7 @@ First, think about instance of objects.
|
||||||
Instance is structured memories and the structure is described as C language structure.
|
Instance is structured memories and the structure is described as C language structure.
|
||||||
The following is a structure of TfeTextView.
|
The following is a structure of TfeTextView.
|
||||||
|
|
||||||
|
~~~C
|
||||||
/* This typedef statement is automaticaly generated by the macro G_DECLARE_FINAL_TYPE */
|
/* This typedef statement is automaticaly generated by the macro G_DECLARE_FINAL_TYPE */
|
||||||
typedef struct _TfeTextView TfeTextView;
|
typedef struct _TfeTextView TfeTextView;
|
||||||
|
|
||||||
|
@ -46,6 +47,7 @@ The following is a structure of TfeTextView.
|
||||||
GtkTextView parent;
|
GtkTextView parent;
|
||||||
GFile *file;
|
GFile *file;
|
||||||
};
|
};
|
||||||
|
~~~
|
||||||
|
|
||||||
The members of the structure are:
|
The members of the structure are:
|
||||||
|
|
||||||
|
@ -59,6 +61,7 @@ They are to be allocated when `tfe_text_view_new` function is invoked.
|
||||||
You can find the declaration of the ancestors of TfeTextView in the sourcefiles of GTK and GLib.
|
You can find the declaration of the ancestors of TfeTextView in the sourcefiles 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).
|
||||||
|
|
||||||
|
~~~C
|
||||||
typedef struct _GObject GObject;
|
typedef struct _GObject GObject;
|
||||||
typedef struct _GObject GInitiallyUnowned;
|
typedef struct _GObject GInitiallyUnowned;
|
||||||
struct _GObject
|
struct _GObject
|
||||||
|
@ -81,6 +84,7 @@ The following is extracts from the source files (not exactly the same).
|
||||||
GtkWidget parent_instance;
|
GtkWidget parent_instance;
|
||||||
GtkTextViewPrivate *priv;
|
GtkTextViewPrivate *priv;
|
||||||
};
|
};
|
||||||
|
~~~
|
||||||
|
|
||||||
In each structure, its parent instance is declared at the top of the members.
|
In each structure, its parent instance 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.
|
||||||
|
@ -199,14 +203,18 @@ For example, GObject class is declared in `gobject.h` in GLib source files.
|
||||||
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 22.
|
||||||
|
|
||||||
|
~~~C
|
||||||
void (*dispose) (GObject *object);
|
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 `disopse` points a function which has one parameter , which points a GObject structure, and returns no value because of void type.
|
So, the pointer `disopse` points a function which has one parameter , which points a GObject structure, and returns no value because of void type.
|
||||||
In the same way, line 23 says `finalize` is a pointer to the function which has one paremeter, 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 paremeter, which points a GObject structure, and returns no value.
|
||||||
|
|
||||||
|
~~~C
|
||||||
void (*finalize) (GObject *object);
|
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.
|
||||||
|
|
||||||
|
@ -398,6 +406,7 @@ In the desposing process, the object uses the pointer in its class to call the h
|
||||||
Therefore, `tfe_text_view_dispose` needs to be registerd in the class when the TfeTextView class is initialized.
|
Therefore, `tfe_text_view_dispose` needs to be registerd in the class when the TfeTextView class is initialized.
|
||||||
The function `tfe_text_view_class_init` is the class initialization function and it is declared in the replacement produced by `G_DEFINE_TYPE` macro.
|
The function `tfe_text_view_class_init` is the class initialization function and it is declared in the replacement produced by `G_DEFINE_TYPE` macro.
|
||||||
|
|
||||||
|
~~~C
|
||||||
static void
|
static void
|
||||||
tfe_text_view_class_init (TfeTextViewClass *class) {
|
tfe_text_view_class_init (TfeTextViewClass *class) {
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||||
|
@ -405,6 +414,7 @@ The function `tfe_text_view_class_init` is the class initialization function and
|
||||||
object_class->dispose = tfe_text_view_dispose;
|
object_class->dispose = tfe_text_view_dispose;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
Each ancestors' class has been generated before TfeTextViewClass is generated.
|
Each ancestors' class has been generated before TfeTextViewClass is generated.
|
||||||
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.
|
||||||
|
@ -418,7 +428,9 @@ Now, look at the `tfe_text_view_dispose` program above.
|
||||||
It first releases the reference to GFile object pointed by `tv->file`.
|
It first releases the reference to GFile object pointed by `tv->file`.
|
||||||
Then it invokes its parent's dispose handler in line 8.
|
Then it invokes its parent's dispose handler in line 8.
|
||||||
|
|
||||||
|
~~~C
|
||||||
G_OBJECT_CLASS (tfe_text_view_parent_class)->dispose (gobject);
|
G_OBJECT_CLASS (tfe_text_view_parent_class)->dispose (gobject);
|
||||||
|
~~~
|
||||||
|
|
||||||
`tfe_text_view_parent_class`,which is made by `G_DEFINE_TYPE` macro, is a pointer that points the parent object class.
|
`tfe_text_view_parent_class`,which is made by `G_DEFINE_TYPE` macro, is a pointer that points the parent object class.
|
||||||
Therefore, `G_OBJECT_CLASS (tfe_text_view_parent_class)->dispose` points the handler `dh3` in the diagram above.
|
Therefore, `G_OBJECT_CLASS (tfe_text_view_parent_class)->dispose` points the handler `dh3` in the diagram above.
|
||||||
|
|
10
gfm/sec11.md
10
gfm/sec11.md
|
@ -45,6 +45,7 @@ This signal is emitted instead of the return value of the function.
|
||||||
Static variable is used to store the signal ID.
|
Static variable is used to store the signal ID.
|
||||||
If you need to register two or more signals, static array is usually used.
|
If you need to register two or more signals, static array is usually used.
|
||||||
|
|
||||||
|
~~~C
|
||||||
enum {
|
enum {
|
||||||
CHANGE_FILE,
|
CHANGE_FILE,
|
||||||
OPEN_RESPONSE,
|
OPEN_RESPONSE,
|
||||||
|
@ -52,6 +53,7 @@ If you need to register two or more signals, static array is usually used.
|
||||||
};
|
};
|
||||||
|
|
||||||
static guint tfe_text_view_signals[NUMBER_OF_SIGNALS];
|
static guint tfe_text_view_signals[NUMBER_OF_SIGNALS];
|
||||||
|
~~~
|
||||||
|
|
||||||
Signal registration codes are written in the class initialization function.
|
Signal registration codes are written in the class initialization function.
|
||||||
|
|
||||||
|
@ -105,8 +107,10 @@ Such fundamental types are described in [GObject API reference](https://develope
|
||||||
|
|
||||||
The handlers are as follows.
|
The handlers are as follows.
|
||||||
|
|
||||||
|
~~~C
|
||||||
void change_file_handler (TfeTextView *tv, gpointer user_data);
|
void change_file_handler (TfeTextView *tv, gpointer user_data);
|
||||||
void open_response_handler (TfeTextView *tv, guint parameter, gpointer user_data);
|
void open_response_handler (TfeTextView *tv, guint parameter, gpointer user_data);
|
||||||
|
~~~
|
||||||
|
|
||||||
- Because "change-file" signal doesn't have parameter, the handler's parameter is TfeTextView object and user data.
|
- Because "change-file" signal doesn't have parameter, the handler's parameter is TfeTextView object and user data.
|
||||||
- Because "open-response" signal has one parameter, the handler's parameter is TfeTextView object, the parameter and user data.
|
- Because "open-response" signal has one parameter, the handler's parameter is TfeTextView object, the parameter and user data.
|
||||||
|
@ -116,6 +120,7 @@ The handlers are as follows.
|
||||||
|
|
||||||
The parameter is defined in `tfetextview.h` because it is public.
|
The parameter is defined in `tfetextview.h` because it is public.
|
||||||
|
|
||||||
|
~~~C
|
||||||
/* "open-response" signal response */
|
/* "open-response" signal response */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -123,6 +128,7 @@ The parameter is defined in `tfetextview.h` because it is public.
|
||||||
TFE_OPEN_RESPONSE_CANCEL,
|
TFE_OPEN_RESPONSE_CANCEL,
|
||||||
TFE_OPEN_RESPONSE_ERROR
|
TFE_OPEN_RESPONSE_ERROR
|
||||||
};
|
};
|
||||||
|
~~~
|
||||||
|
|
||||||
- `TFE_OPEN_RESPONSE_SUCCESS` is set when `tfe_text_view_open` successfully has opend a file and loaded it.
|
- `TFE_OPEN_RESPONSE_SUCCESS` is set when `tfe_text_view_open` successfully has opend a file and loaded it.
|
||||||
- `TFE_OPEN_RESPONSE_CANCEL` is set when the user has canceled to open a file.
|
- `TFE_OPEN_RESPONSE_CANCEL` is set when the user has canceled to open a file.
|
||||||
|
@ -137,9 +143,11 @@ The signals "change-file" is connected to a callback function `file_changed` out
|
||||||
In the same way, the signals "open-response" is connected to a callback function `open_response` outside of TfeTextView object.
|
In the same way, the signals "open-response" is connected to a callback function `open_response` outside of TfeTextView object.
|
||||||
The functions `file_changed` and `open_response` will be explained later.
|
The functions `file_changed` and `open_response` will be explained later.
|
||||||
|
|
||||||
|
~~~C
|
||||||
g_signal_connect (GTK_TEXT_VIEW (tv), "change-file", G_CALLBACK (file_changed), nb);
|
g_signal_connect (GTK_TEXT_VIEW (tv), "change-file", G_CALLBACK (file_changed), nb);
|
||||||
|
|
||||||
g_signal_connect (TFE_TEXT_VIEW (tv), "open-response", G_CALLBACK (open_response), nb);
|
g_signal_connect (TFE_TEXT_VIEW (tv), "open-response", G_CALLBACK (open_response), nb);
|
||||||
|
~~~
|
||||||
|
|
||||||
## Signal emission
|
## Signal emission
|
||||||
|
|
||||||
|
@ -150,10 +158,12 @@ The relationship between the signal and object (type) is made up when the signal
|
||||||
`g_signal_emit` is used to emit the signal.
|
`g_signal_emit` is used to emit the signal.
|
||||||
The following is extract from `tfetexties.c`.
|
The following is extract from `tfetexties.c`.
|
||||||
|
|
||||||
|
~~~C
|
||||||
g_signal_emit (tv, tfe_text_view_signals[CHANGE_FILE], 0);
|
g_signal_emit (tv, tfe_text_view_signals[CHANGE_FILE], 0);
|
||||||
g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_SUCCESS);
|
g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_SUCCESS);
|
||||||
g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_CANCEL);
|
g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_CANCEL);
|
||||||
g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_ERROR);
|
g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_ERROR);
|
||||||
|
~~~
|
||||||
|
|
||||||
- The first argument is the object on which the signal is emitted.
|
- The first argument is the object on which the signal is emitted.
|
||||||
- The second argument is the signal id.
|
- The second argument is the signal id.
|
||||||
|
|
10
gfm/sec12.md
10
gfm/sec12.md
|
@ -60,11 +60,15 @@ Each function will be explained later in this section.
|
||||||
|
|
||||||
TfeTextView Object is generated by `tfe_text_view_new` or `tfe_text_view_new_with_file`.
|
TfeTextView Object is generated by `tfe_text_view_new` or `tfe_text_view_new_with_file`.
|
||||||
|
|
||||||
|
~~~C
|
||||||
GtkWidget *tfe_text_view_new (void);
|
GtkWidget *tfe_text_view_new (void);
|
||||||
|
~~~
|
||||||
|
|
||||||
`tfe_text_view_new` just generates a new TfeTextView object and returns the pointer to the new object.
|
`tfe_text_view_new` just generates a new TfeTextView object and returns the pointer to the new object.
|
||||||
|
|
||||||
|
~~~C
|
||||||
GtkWidget *tfe_text_view_new_with_file (GFile *file);
|
GtkWidget *tfe_text_view_new_with_file (GFile *file);
|
||||||
|
~~~
|
||||||
|
|
||||||
`tfe_text_view_new_with_file` is given a Gfile object as the argument and it loads the file into the GtkTextBuffer object, then returns the pointer to the new object.
|
`tfe_text_view_new_with_file` is given a Gfile object as the argument and it loads the file into the GtkTextBuffer object, then returns the pointer to the new object.
|
||||||
|
|
||||||
|
@ -131,12 +135,16 @@ Return `tv`.
|
||||||
|
|
||||||
Save and saveas functions write the contents in GtkTextBuffer to a file.
|
Save and saveas functions write the contents in GtkTextBuffer to a file.
|
||||||
|
|
||||||
|
~~~C
|
||||||
void tfe_text_view_save (TfeTextView *tv)
|
void tfe_text_view_save (TfeTextView *tv)
|
||||||
|
~~~
|
||||||
|
|
||||||
`save` function writes the contents in GtkTextBuffer to a file specified by `tv->file`.
|
`save` function writes the contents in GtkTextBuffer to a file specified by `tv->file`.
|
||||||
If `tv->file` is NULL, then it shows GtkFileChooserDialog and lets the user to give a file to the program. After that, it saves the contents to the specified file and set the file into `tv->file`.
|
If `tv->file` is NULL, then it shows GtkFileChooserDialog and lets the user to give a file to the program. After that, it saves the contents to the specified file and set the file into `tv->file`.
|
||||||
|
|
||||||
|
~~~C
|
||||||
void tfe_text_view_saveas (TfeTextView *tv)
|
void tfe_text_view_saveas (TfeTextView *tv)
|
||||||
|
~~~
|
||||||
|
|
||||||
`saveas` function uses GtkFileChooserDialog and lets the user to give a new file to the program. Then, the function changes `tv->file` and save the contents to the specified new file.
|
`saveas` function uses GtkFileChooserDialog and lets the user to give a new file to the program. Then, the function changes `tv->file` and save the contents to the specified new file.
|
||||||
|
|
||||||
|
@ -254,7 +262,9 @@ It gets Gfile from GtkFileChooserDialog, save the buffer to the file by calling
|
||||||
Open function shows GtkFileChooserDialog to the user and let them choose a file.
|
Open function shows GtkFileChooserDialog to the user and let them choose a file.
|
||||||
Then read the file and set it to GtkTextBuffer.
|
Then read the file and set it to GtkTextBuffer.
|
||||||
|
|
||||||
|
~~~C
|
||||||
void tfe_text_view_open (TfeTextView *tv, GtkWidget *win);
|
void tfe_text_view_open (TfeTextView *tv, GtkWidget *win);
|
||||||
|
~~~
|
||||||
|
|
||||||
TfeTextView object `tv` has to be generated in advance.
|
TfeTextView object `tv` has to be generated in advance.
|
||||||
This function is usually called just after `tv` has been generated.
|
This function is usually called just after `tv` has been generated.
|
||||||
|
|
|
@ -107,19 +107,25 @@ It implies that CSS can also be apllied to GTK windowing system.
|
||||||
|
|
||||||
The syntax of CSS is as follws.
|
The syntax of CSS is as follws.
|
||||||
|
|
||||||
|
~~~css
|
||||||
selector { color: yellow; padding-top: 10px; ...}
|
selector { color: yellow; padding-top: 10px; ...}
|
||||||
|
~~~
|
||||||
|
|
||||||
Every widget has CSS node.
|
Every widget has CSS node.
|
||||||
For example GtkTextView has `textview` node.
|
For example GtkTextView has `textview` node.
|
||||||
If you want to set style to GtkTextView, set "textview" to the selector.
|
If you want to set style to GtkTextView, set "textview" to the selector.
|
||||||
|
|
||||||
|
~~~css
|
||||||
textview {color: yeallow; ...}
|
textview {color: yeallow; ...}
|
||||||
|
~~~
|
||||||
|
|
||||||
Class, ID and some other things can be applied to the selector like Web CSS. Refer GTK4 API reference for further information.
|
Class, ID and some other things can be applied to the selector like Web CSS. Refer GTK4 API reference for further information.
|
||||||
|
|
||||||
In line 30, the CSS is a string.
|
In line 30, the CSS is a string.
|
||||||
|
|
||||||
|
~~~css
|
||||||
textview {padding: 10px; font-family: monospace; font-size: 12pt;}
|
textview {padding: 10px; font-family: monospace; font-size: 12pt;}
|
||||||
|
~~~
|
||||||
|
|
||||||
- padding is a space between the border and contents.
|
- padding is a space between the border and contents.
|
||||||
This space makes the text easier to read.
|
This space makes the text easier to read.
|
||||||
|
@ -149,6 +155,7 @@ Look at the source file of `startup` handler again.
|
||||||
It is possible to add the provider to the context of GtkTextView instead of GdkDiplay.
|
It is possible to add the provider to the context of GtkTextView instead of GdkDiplay.
|
||||||
To do so, rewrite `tfe_text_view_new`.
|
To do so, rewrite `tfe_text_view_new`.
|
||||||
|
|
||||||
|
~~~C
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
tfe_text_view_new (void) {
|
tfe_text_view_new (void) {
|
||||||
GtkWidget *tv;
|
GtkWidget *tv;
|
||||||
|
@ -164,6 +171,7 @@ To do so, rewrite `tfe_text_view_new`.
|
||||||
|
|
||||||
return tv;
|
return tv;
|
||||||
}
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
CSS set to the context takes precedence over the one set to the display.
|
CSS set to the context takes precedence over the one set to the display.
|
||||||
|
|
||||||
|
|
16
gfm/sec17.md
16
gfm/sec17.md
|
@ -18,6 +18,7 @@ TRUE corresponds to fullscreen and FALSE to non-fullscreen.
|
||||||
The following is an example code to implement a fullscreen menu except the signal handler.
|
The following is an example code to implement a fullscreen menu except the signal handler.
|
||||||
The signal handler will be described after the explanation of this code.
|
The signal handler will be described after the explanation of this code.
|
||||||
|
|
||||||
|
~~~C
|
||||||
static void
|
static void
|
||||||
on_activate (GApplication *app, gpointer user_data) {
|
on_activate (GApplication *app, gpointer user_data) {
|
||||||
... ... ...
|
... ... ...
|
||||||
|
@ -27,6 +28,7 @@ The signal handler will be described after the explanation of this code.
|
||||||
g_signal_connect (act_fullscreen, "change-state", G_CALLBACK (fullscreen_changed), win);
|
g_signal_connect (act_fullscreen, "change-state", G_CALLBACK (fullscreen_changed), win);
|
||||||
... ... ...
|
... ... ...
|
||||||
}
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
- `act_fullscreen` is GSimpleAction.
|
- `act_fullscreen` is GSimpleAction.
|
||||||
It is generated by `g_simple_action_new_stateful`.
|
It is generated by `g_simple_action_new_stateful`.
|
||||||
|
@ -52,6 +54,7 @@ Then, the default behaviour for boolean-stated actions with a NULL parameter typ
|
||||||
|
|
||||||
The following is the "change-state" signal handler.
|
The following is the "change-state" signal handler.
|
||||||
|
|
||||||
|
~~~C
|
||||||
static void
|
static void
|
||||||
fullscreen_changed(GSimpleAction *action, GVariant *value, gpointer win) {
|
fullscreen_changed(GSimpleAction *action, GVariant *value, gpointer win) {
|
||||||
if (g_variant_get_boolean (value))
|
if (g_variant_get_boolean (value))
|
||||||
|
@ -60,6 +63,7 @@ The following is the "change-state" signal handler.
|
||||||
gtk_window_unmaximize (GTK_WINDOW (win));
|
gtk_window_unmaximize (GTK_WINDOW (win));
|
||||||
g_simple_action_set_state (action, value);
|
g_simple_action_set_state (action, value);
|
||||||
}
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
- There are three parameters.
|
- There are three parameters.
|
||||||
The first parameter is the action which emits the "change-state" signal.
|
The first parameter is the action which emits the "change-state" signal.
|
||||||
|
@ -80,11 +84,15 @@ But the way above is the simplest and best.
|
||||||
GVarient can contain boolean, string or other simple type values.
|
GVarient can contain boolean, string or other simple type values.
|
||||||
For example, the following program set TRUE to `value` whose type is GVariant.
|
For example, the following program set TRUE to `value` whose type is GVariant.
|
||||||
|
|
||||||
|
~~~C
|
||||||
GVariant *value = g_variant_new_boolean (TRUE);
|
GVariant *value = g_variant_new_boolean (TRUE);
|
||||||
|
~~~
|
||||||
|
|
||||||
Another example is:
|
Another example is:
|
||||||
|
|
||||||
|
~~~C
|
||||||
GVariant *value2 = g_variant_new_string ("Hello");
|
GVariant *value2 = g_variant_new_string ("Hello");
|
||||||
|
~~~
|
||||||
|
|
||||||
`value2` is a GVariant and it has a string type value "Hello".
|
`value2` is a GVariant and it has a string type value "Hello".
|
||||||
GVariant can contain other types like int16, int32, int64, double and so on.
|
GVariant can contain other types like int16, int32, int64, double and so on.
|
||||||
|
@ -92,12 +100,16 @@ GVariant can contain other types like int16, int32, int64, double and so on.
|
||||||
If you want to get the original value, use g\_variant\_get series functions.
|
If you want to get the original value, use g\_variant\_get series functions.
|
||||||
For example, you can get the boolean value by g\_variant_get_boolean.
|
For example, you can get the boolean value by g\_variant_get_boolean.
|
||||||
|
|
||||||
|
~~~C
|
||||||
gboolean bool = g_variant_get_boolean (value);
|
gboolean bool = g_variant_get_boolean (value);
|
||||||
|
~~~
|
||||||
|
|
||||||
Because `value` has been generated as a boolean type GVariant and `TRUE` value, `bool` equals `TRUE`.
|
Because `value` has been generated as a boolean type GVariant and `TRUE` value, `bool` equals `TRUE`.
|
||||||
In the same way, you can get a string from `value2`
|
In the same way, you can get a string from `value2`
|
||||||
|
|
||||||
|
~~~C
|
||||||
const gchar *str = g_variant_get_string (value2, NULL);
|
const gchar *str = g_variant_get_string (value2, NULL);
|
||||||
|
~~~
|
||||||
|
|
||||||
The second parameter is a pointer to gsize type variable (gsize is defined as unsigned long).
|
The second parameter is a pointer to gsize type variable (gsize is defined as unsigned long).
|
||||||
If it isn't NULL, then the length of the string will be set by the function.
|
If it isn't NULL, then the length of the string will be set by the function.
|
||||||
|
@ -114,6 +126,7 @@ The action has a state which values are "red", "green" and "blue".
|
||||||
The values are string.
|
The values are string.
|
||||||
Those colors are given to the signal handler as a parameter.
|
Those colors are given to the signal handler as a parameter.
|
||||||
|
|
||||||
|
~~~C
|
||||||
static void
|
static void
|
||||||
on_activate (GApplication *app, gpointer user_data) {
|
on_activate (GApplication *app, gpointer user_data) {
|
||||||
... ... ...
|
... ... ...
|
||||||
|
@ -125,6 +138,7 @@ Those colors are given to the signal handler as a parameter.
|
||||||
g_signal_connect (act_color, "activate", G_CALLBACK (color_activated), win);
|
g_signal_connect (act_color, "activate", G_CALLBACK (color_activated), win);
|
||||||
... ... ...
|
... ... ...
|
||||||
}
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
- `act_color` is GSimpleAction.
|
- `act_color` is GSimpleAction.
|
||||||
It is generated by `g_simple_action_new_stateful`.
|
It is generated by `g_simple_action_new_stateful`.
|
||||||
|
@ -150,6 +164,7 @@ Then the default behaviour is to call `g_simple_action_set_state()` to set the s
|
||||||
|
|
||||||
The following is the "activate" signal handler.
|
The following is the "activate" signal handler.
|
||||||
|
|
||||||
|
~~~C
|
||||||
static void
|
static void
|
||||||
color_activated(GSimpleAction *action, GVariant *parameter, gpointer win) {
|
color_activated(GSimpleAction *action, GVariant *parameter, gpointer win) {
|
||||||
gchar *color = g_strdup_printf ("label#lb {background-color: %s;}",
|
gchar *color = g_strdup_printf ("label#lb {background-color: %s;}",
|
||||||
|
@ -158,6 +173,7 @@ The following is the "activate" signal handler.
|
||||||
g_free (color);
|
g_free (color);
|
||||||
g_action_change_state (G_ACTION (action), parameter);
|
g_action_change_state (G_ACTION (action), parameter);
|
||||||
}
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
- There are three parameters.
|
- There are three parameters.
|
||||||
The first parameter is the action which emits the "activate" signal.
|
The first parameter is the action which emits the "activate" signal.
|
||||||
|
|
|
@ -214,8 +214,10 @@ GtkWindow includes GtkWidget at the top of its object.
|
||||||
|
|
||||||
The function `gtk_window_new` is defined as follows.
|
The function `gtk_window_new` is defined as follows.
|
||||||
|
|
||||||
|
~~~C
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
gtk_window_new (void);
|
gtk_window_new (void);
|
||||||
|
~~~
|
||||||
|
|
||||||
By this definition, it returns a pointer to GtkWidget, not GtkWindow.
|
By this definition, it returns a pointer to GtkWidget, not GtkWindow.
|
||||||
It actually generates a new GtkWindow object (not GtkWidget) but returns a pointer to GtkWidget.
|
It actually generates a new GtkWindow object (not GtkWidget) but returns a pointer to GtkWidget.
|
||||||
|
@ -223,11 +225,15 @@ However,the pointer points the GtkWidget and at the same time it also points Gtk
|
||||||
|
|
||||||
If you want to use `win` as a pointer to the GtkWindow, you need to cast it.
|
If you want to use `win` as a pointer to the GtkWindow, you need to cast it.
|
||||||
|
|
||||||
|
~~~C
|
||||||
(GtkWindow *) win
|
(GtkWindow *) win
|
||||||
|
~~~
|
||||||
|
|
||||||
Or you can use `GTK_WINDOW` macro that performs a similar function.
|
Or you can use `GTK_WINDOW` macro that performs a similar function.
|
||||||
|
|
||||||
|
~~~C
|
||||||
GTK_WINDOW (win)
|
GTK_WINDOW (win)
|
||||||
|
~~~
|
||||||
|
|
||||||
This is a recommended way.
|
This is a recommended way.
|
||||||
|
|
||||||
|
@ -235,7 +241,9 @@ This is a recommended way.
|
||||||
|
|
||||||
The function `gtk_window_set_application` is used to connect GtkWidow to GtkApplication.
|
The function `gtk_window_set_application` is used to connect GtkWidow to GtkApplication.
|
||||||
|
|
||||||
|
~~~C
|
||||||
gtk_window_set_application (GTK_WINDOW (win), GTK_APPLICATION (app));
|
gtk_window_set_application (GTK_WINDOW (win), GTK_APPLICATION (app));
|
||||||
|
~~~
|
||||||
|
|
||||||
You need to cast `win` to GtkWindow and `app` to GtkApplication.
|
You need to cast `win` to GtkWindow and `app` to GtkApplication.
|
||||||
`GTK_WINDOW` and `GTK_APPLICATION` macro is appropriate for that.
|
`GTK_WINDOW` and `GTK_APPLICATION` macro is appropriate for that.
|
||||||
|
|
10
gfm/sec6.md
10
gfm/sec6.md
|
@ -22,17 +22,21 @@ It is described in the GIO API reference.
|
||||||
|
|
||||||
When GtkApplication is generated, a flag (its type is GApplicationFlags) is given as an argument.
|
When GtkApplication is generated, a flag (its type is GApplicationFlags) is given as an argument.
|
||||||
|
|
||||||
|
~~~C
|
||||||
GtkApplication *
|
GtkApplication *
|
||||||
gtk_application_new (const gchar *application_id, GApplicationFlags flags);
|
gtk_application_new (const gchar *application_id, GApplicationFlags flags);
|
||||||
|
~~~
|
||||||
|
|
||||||
This flag is described in the GApplication section in GIO API reference.
|
This flag is described in the GApplication section in GIO API reference.
|
||||||
|
|
||||||
|
~~~C
|
||||||
GApplicationFlags' Members
|
GApplicationFlags' Members
|
||||||
|
|
||||||
G_APPLICATION_FLAGS_NONE Default. (No argument allowed)
|
G_APPLICATION_FLAGS_NONE Default. (No argument allowed)
|
||||||
... ... ...
|
... ... ...
|
||||||
G_APPLICATION_HANDLES_OPEN This application handles opening files (in the primary instance).
|
G_APPLICATION_HANDLES_OPEN This application handles opening files (in the primary instance).
|
||||||
... ... ...
|
... ... ...
|
||||||
|
~~~
|
||||||
|
|
||||||
There are ten flags.
|
There are ten flags.
|
||||||
But we only need two of them so far.
|
But we only need two of them so far.
|
||||||
|
@ -47,7 +51,9 @@ The application assumes all the arguments are filenames.
|
||||||
|
|
||||||
Now we use this flag when generating GtkApplication.
|
Now we use this flag when generating GtkApplication.
|
||||||
|
|
||||||
|
~~~C
|
||||||
app = gtk_application_new ("com.github.ToshioCP.tfv3", G_APPLICATION_HANDLES_OPEN);
|
app = gtk_application_new ("com.github.ToshioCP.tfv3", G_APPLICATION_HANDLES_OPEN);
|
||||||
|
~~~
|
||||||
|
|
||||||
### open signal
|
### open signal
|
||||||
|
|
||||||
|
@ -58,11 +64,13 @@ When the application starts, two signals are possible.
|
||||||
|
|
||||||
The handler of open signal is called as follows.
|
The handler of open signal is called as follows.
|
||||||
|
|
||||||
|
~~~C
|
||||||
void user_function (GApplication *application,
|
void user_function (GApplication *application,
|
||||||
gpointer files,
|
gpointer files,
|
||||||
gint n_files,
|
gint n_files,
|
||||||
gchar *hint,
|
gchar *hint,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
|
~~~
|
||||||
|
|
||||||
The parameters are as follows:
|
The parameters are as follows:
|
||||||
|
|
||||||
|
@ -176,6 +184,7 @@ The point is the handler `on_open`.
|
||||||
|
|
||||||
The file reading part of the program is shown again below.
|
The file reading part of the program is shown again below.
|
||||||
|
|
||||||
|
~~~C
|
||||||
if (g_file_load_contents(files[0], NULL, &contents, &length, NULL, NULL)) {
|
if (g_file_load_contents(files[0], NULL, &contents, &length, NULL, NULL)) {
|
||||||
gtk_text_buffer_set_text(tb, contents, length);
|
gtk_text_buffer_set_text(tb, contents, length);
|
||||||
g_free(contents);
|
g_free(contents);
|
||||||
|
@ -188,6 +197,7 @@ The file reading part of the program is shown again below.
|
||||||
g_print ("No such file: %s.\n", filename);
|
g_print ("No such file: %s.\n", filename);
|
||||||
gtk_window_destroy (GTK_WINDOW (win));
|
gtk_window_destroy (GTK_WINDOW (win));
|
||||||
}
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
The function `g_file_load_contents` loads the file contents into a buffer, which is automatically allocated, and set the pointer to the buffer into `contents`.
|
The function `g_file_load_contents` loads the file contents into a buffer, which is automatically allocated, and set the pointer to the buffer into `contents`.
|
||||||
And the length of the buffer is set to `length`.
|
And the length of the buffer is set to `length`.
|
||||||
|
|
|
@ -24,7 +24,9 @@ Using global variables is easy to implement.
|
||||||
Define a sufficient size array of pointers to GFile.
|
Define a sufficient size array of pointers to GFile.
|
||||||
For example,
|
For example,
|
||||||
|
|
||||||
|
~~~C
|
||||||
GFile *f[20];
|
GFile *f[20];
|
||||||
|
~~~
|
||||||
|
|
||||||
And `f[i]` corresponds to i-th GtkNotebookPage.
|
And `f[i]` corresponds to i-th GtkNotebookPage.
|
||||||
However, there are two problems.
|
However, there are two problems.
|
||||||
|
@ -153,7 +155,9 @@ A handler is a C function.
|
||||||
When a function is connected to a certain signal, we call it handler.
|
When a function is connected to a certain signal, we call it handler.
|
||||||
The function `before_close` is invoked when the signal "close-request" is emittd.
|
The function `before_close` is invoked when the signal "close-request" is emittd.
|
||||||
|
|
||||||
|
~~~C
|
||||||
g_signal_connect (win, "close-request", G_CALLBACK (before_close), NULL);
|
g_signal_connect (win, "close-request", G_CALLBACK (before_close), NULL);
|
||||||
|
~~~
|
||||||
|
|
||||||
The argument win is GtkApplicationWindow, in which the signal "close-request" is defined, and before\_close is the handler.
|
The argument win is GtkApplicationWindow, in which the signal "close-request" is defined, and before\_close is the handler.
|
||||||
`G_CALLBACK` cast is necessary for the handler.
|
`G_CALLBACK` cast is necessary for the handler.
|
||||||
|
|
|
@ -268,8 +268,10 @@ So it is an old and widely used program.
|
||||||
Make analyzes Makefile and executes compilers.
|
Make analyzes Makefile and executes compilers.
|
||||||
All instructions are written in Makefile.
|
All instructions are written in Makefile.
|
||||||
|
|
||||||
|
~~~Makefile
|
||||||
sample.o: sample.c
|
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 -0 sample.o sample.c`.
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ First, think about instance of objects.
|
||||||
Instance is structured memories and the structure is described as C language structure.
|
Instance is structured memories and the structure is described as C language structure.
|
||||||
The following is a structure of TfeTextView.
|
The following is a structure of TfeTextView.
|
||||||
|
|
||||||
|
~~~C
|
||||||
/* This typedef statement is automaticaly generated by the macro G_DECLARE_FINAL_TYPE */
|
/* This typedef statement is automaticaly generated by the macro G_DECLARE_FINAL_TYPE */
|
||||||
typedef struct _TfeTextView TfeTextView;
|
typedef struct _TfeTextView TfeTextView;
|
||||||
|
|
||||||
|
@ -44,6 +45,7 @@ The following is a structure of TfeTextView.
|
||||||
GtkTextView parent;
|
GtkTextView parent;
|
||||||
GFile *file;
|
GFile *file;
|
||||||
};
|
};
|
||||||
|
~~~
|
||||||
|
|
||||||
The members of the structure are:
|
The members of the structure are:
|
||||||
|
|
||||||
|
@ -57,6 +59,7 @@ They are to be allocated when `tfe_text_view_new` function is invoked.
|
||||||
You can find the declaration of the ancestors of TfeTextView in the sourcefiles of GTK and GLib.
|
You can find the declaration of the ancestors of TfeTextView in the sourcefiles 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).
|
||||||
|
|
||||||
|
~~~C
|
||||||
typedef struct _GObject GObject;
|
typedef struct _GObject GObject;
|
||||||
typedef struct _GObject GInitiallyUnowned;
|
typedef struct _GObject GInitiallyUnowned;
|
||||||
struct _GObject
|
struct _GObject
|
||||||
|
@ -79,6 +82,7 @@ The following is extracts from the source files (not exactly the same).
|
||||||
GtkWidget parent_instance;
|
GtkWidget parent_instance;
|
||||||
GtkTextViewPrivate *priv;
|
GtkTextViewPrivate *priv;
|
||||||
};
|
};
|
||||||
|
~~~
|
||||||
|
|
||||||
In each structure, its parent instance is declared at the top of the members.
|
In each structure, its parent instance 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.
|
||||||
|
@ -144,14 +148,18 @@ For example, GObject class is declared in `gobject.h` in GLib source files.
|
||||||
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 22.
|
||||||
|
|
||||||
|
~~~C
|
||||||
void (*dispose) (GObject *object);
|
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 `disopse` points a function which has one parameter , which points a GObject structure, and returns no value because of void type.
|
So, the pointer `disopse` points a function which has one parameter , which points a GObject structure, and returns no value because of void type.
|
||||||
In the same way, line 23 says `finalize` is a pointer to the function which has one paremeter, 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 paremeter, which points a GObject structure, and returns no value.
|
||||||
|
|
||||||
|
~~~C
|
||||||
void (*finalize) (GObject *object);
|
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.
|
||||||
|
|
||||||
|
@ -224,6 +232,7 @@ In the desposing process, the object uses the pointer in its class to call the h
|
||||||
Therefore, `tfe_text_view_dispose` needs to be registerd in the class when the TfeTextView class is initialized.
|
Therefore, `tfe_text_view_dispose` needs to be registerd in the class when the TfeTextView class is initialized.
|
||||||
The function `tfe_text_view_class_init` is the class initialization function and it is declared in the replacement produced by `G_DEFINE_TYPE` macro.
|
The function `tfe_text_view_class_init` is the class initialization function and it is declared in the replacement produced by `G_DEFINE_TYPE` macro.
|
||||||
|
|
||||||
|
~~~C
|
||||||
static void
|
static void
|
||||||
tfe_text_view_class_init (TfeTextViewClass *class) {
|
tfe_text_view_class_init (TfeTextViewClass *class) {
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||||
|
@ -231,6 +240,7 @@ The function `tfe_text_view_class_init` is the class initialization function and
|
||||||
object_class->dispose = tfe_text_view_dispose;
|
object_class->dispose = tfe_text_view_dispose;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
Each ancestors' class has been generated before TfeTextViewClass is generated.
|
Each ancestors' class has been generated before TfeTextViewClass is generated.
|
||||||
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.
|
||||||
|
@ -244,7 +254,9 @@ Now, look at the `tfe_text_view_dispose` program above.
|
||||||
It first releases the reference to GFile object pointed by `tv->file`.
|
It first releases the reference to GFile object pointed by `tv->file`.
|
||||||
Then it invokes its parent's dispose handler in line 8.
|
Then it invokes its parent's dispose handler in line 8.
|
||||||
|
|
||||||
|
~~~C
|
||||||
G_OBJECT_CLASS (tfe_text_view_parent_class)->dispose (gobject);
|
G_OBJECT_CLASS (tfe_text_view_parent_class)->dispose (gobject);
|
||||||
|
~~~
|
||||||
|
|
||||||
`tfe_text_view_parent_class`,which is made by `G_DEFINE_TYPE` macro, is a pointer that points the parent object class.
|
`tfe_text_view_parent_class`,which is made by `G_DEFINE_TYPE` macro, is a pointer that points the parent object class.
|
||||||
Therefore, `G_OBJECT_CLASS (tfe_text_view_parent_class)->dispose` points the handler `dh3` in the diagram above.
|
Therefore, `G_OBJECT_CLASS (tfe_text_view_parent_class)->dispose` points the handler `dh3` in the diagram above.
|
||||||
|
|
|
@ -43,6 +43,7 @@ This signal is emitted instead of the return value of the function.
|
||||||
Static variable is used to store the signal ID.
|
Static variable is used to store the signal ID.
|
||||||
If you need to register two or more signals, static array is usually used.
|
If you need to register two or more signals, static array is usually used.
|
||||||
|
|
||||||
|
~~~C
|
||||||
enum {
|
enum {
|
||||||
CHANGE_FILE,
|
CHANGE_FILE,
|
||||||
OPEN_RESPONSE,
|
OPEN_RESPONSE,
|
||||||
|
@ -50,6 +51,7 @@ If you need to register two or more signals, static array is usually used.
|
||||||
};
|
};
|
||||||
|
|
||||||
static guint tfe_text_view_signals[NUMBER_OF_SIGNALS];
|
static guint tfe_text_view_signals[NUMBER_OF_SIGNALS];
|
||||||
|
~~~
|
||||||
|
|
||||||
Signal registration codes are written in the class initialization function.
|
Signal registration codes are written in the class initialization function.
|
||||||
|
|
||||||
|
@ -75,8 +77,10 @@ Such fundamental types are described in [GObject API reference](https://develope
|
||||||
|
|
||||||
The handlers are as follows.
|
The handlers are as follows.
|
||||||
|
|
||||||
|
~~~C
|
||||||
void change_file_handler (TfeTextView *tv, gpointer user_data);
|
void change_file_handler (TfeTextView *tv, gpointer user_data);
|
||||||
void open_response_handler (TfeTextView *tv, guint parameter, gpointer user_data);
|
void open_response_handler (TfeTextView *tv, guint parameter, gpointer user_data);
|
||||||
|
~~~
|
||||||
|
|
||||||
- Because "change-file" signal doesn't have parameter, the handler's parameter is TfeTextView object and user data.
|
- Because "change-file" signal doesn't have parameter, the handler's parameter is TfeTextView object and user data.
|
||||||
- Because "open-response" signal has one parameter, the handler's parameter is TfeTextView object, the parameter and user data.
|
- Because "open-response" signal has one parameter, the handler's parameter is TfeTextView object, the parameter and user data.
|
||||||
|
@ -86,6 +90,7 @@ The handlers are as follows.
|
||||||
|
|
||||||
The parameter is defined in `tfetextview.h` because it is public.
|
The parameter is defined in `tfetextview.h` because it is public.
|
||||||
|
|
||||||
|
~~~C
|
||||||
/* "open-response" signal response */
|
/* "open-response" signal response */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -93,6 +98,7 @@ The parameter is defined in `tfetextview.h` because it is public.
|
||||||
TFE_OPEN_RESPONSE_CANCEL,
|
TFE_OPEN_RESPONSE_CANCEL,
|
||||||
TFE_OPEN_RESPONSE_ERROR
|
TFE_OPEN_RESPONSE_ERROR
|
||||||
};
|
};
|
||||||
|
~~~
|
||||||
|
|
||||||
- `TFE_OPEN_RESPONSE_SUCCESS` is set when `tfe_text_view_open` successfully has opend a file and loaded it.
|
- `TFE_OPEN_RESPONSE_SUCCESS` is set when `tfe_text_view_open` successfully has opend a file and loaded it.
|
||||||
- `TFE_OPEN_RESPONSE_CANCEL` is set when the user has canceled to open a file.
|
- `TFE_OPEN_RESPONSE_CANCEL` is set when the user has canceled to open a file.
|
||||||
|
@ -107,9 +113,11 @@ The signals "change-file" is connected to a callback function `file_changed` out
|
||||||
In the same way, the signals "open-response" is connected to a callback function `open_response` outside of TfeTextView object.
|
In the same way, the signals "open-response" is connected to a callback function `open_response` outside of TfeTextView object.
|
||||||
The functions `file_changed` and `open_response` will be explained later.
|
The functions `file_changed` and `open_response` will be explained later.
|
||||||
|
|
||||||
|
~~~C
|
||||||
g_signal_connect (GTK_TEXT_VIEW (tv), "change-file", G_CALLBACK (file_changed), nb);
|
g_signal_connect (GTK_TEXT_VIEW (tv), "change-file", G_CALLBACK (file_changed), nb);
|
||||||
|
|
||||||
g_signal_connect (TFE_TEXT_VIEW (tv), "open-response", G_CALLBACK (open_response), nb);
|
g_signal_connect (TFE_TEXT_VIEW (tv), "open-response", G_CALLBACK (open_response), nb);
|
||||||
|
~~~
|
||||||
|
|
||||||
## Signal emission
|
## Signal emission
|
||||||
|
|
||||||
|
@ -120,10 +128,12 @@ The relationship between the signal and object (type) is made up when the signal
|
||||||
`g_signal_emit` is used to emit the signal.
|
`g_signal_emit` is used to emit the signal.
|
||||||
The following is extract from `tfetexties.c`.
|
The following is extract from `tfetexties.c`.
|
||||||
|
|
||||||
|
~~~C
|
||||||
g_signal_emit (tv, tfe_text_view_signals[CHANGE_FILE], 0);
|
g_signal_emit (tv, tfe_text_view_signals[CHANGE_FILE], 0);
|
||||||
g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_SUCCESS);
|
g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_SUCCESS);
|
||||||
g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_CANCEL);
|
g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_CANCEL);
|
||||||
g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_ERROR);
|
g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_ERROR);
|
||||||
|
~~~
|
||||||
|
|
||||||
- The first argument is the object on which the signal is emitted.
|
- The first argument is the object on which the signal is emitted.
|
||||||
- The second argument is the signal id.
|
- The second argument is the signal id.
|
||||||
|
|
|
@ -23,11 +23,15 @@ Each function will be explained later in this section.
|
||||||
|
|
||||||
TfeTextView Object is generated by `tfe_text_view_new` or `tfe_text_view_new_with_file`.
|
TfeTextView Object is generated by `tfe_text_view_new` or `tfe_text_view_new_with_file`.
|
||||||
|
|
||||||
|
~~~C
|
||||||
GtkWidget *tfe_text_view_new (void);
|
GtkWidget *tfe_text_view_new (void);
|
||||||
|
~~~
|
||||||
|
|
||||||
`tfe_text_view_new` just generates a new TfeTextView object and returns the pointer to the new object.
|
`tfe_text_view_new` just generates a new TfeTextView object and returns the pointer to the new object.
|
||||||
|
|
||||||
|
~~~C
|
||||||
GtkWidget *tfe_text_view_new_with_file (GFile *file);
|
GtkWidget *tfe_text_view_new_with_file (GFile *file);
|
||||||
|
~~~
|
||||||
|
|
||||||
`tfe_text_view_new_with_file` is given a Gfile object as the argument and it loads the file into the GtkTextBuffer object, then returns the pointer to the new object.
|
`tfe_text_view_new_with_file` is given a Gfile object as the argument and it loads the file into the GtkTextBuffer object, then returns the pointer to the new object.
|
||||||
|
|
||||||
|
@ -69,12 +73,16 @@ Return `tv`.
|
||||||
|
|
||||||
Save and saveas functions write the contents in GtkTextBuffer to a file.
|
Save and saveas functions write the contents in GtkTextBuffer to a file.
|
||||||
|
|
||||||
|
~~~C
|
||||||
void tfe_text_view_save (TfeTextView *tv)
|
void tfe_text_view_save (TfeTextView *tv)
|
||||||
|
~~~
|
||||||
|
|
||||||
`save` function writes the contents in GtkTextBuffer to a file specified by `tv->file`.
|
`save` function writes the contents in GtkTextBuffer to a file specified by `tv->file`.
|
||||||
If `tv->file` is NULL, then it shows GtkFileChooserDialog and lets the user to give a file to the program. After that, it saves the contents to the specified file and set the file into `tv->file`.
|
If `tv->file` is NULL, then it shows GtkFileChooserDialog and lets the user to give a file to the program. After that, it saves the contents to the specified file and set the file into `tv->file`.
|
||||||
|
|
||||||
|
~~~C
|
||||||
void tfe_text_view_saveas (TfeTextView *tv)
|
void tfe_text_view_saveas (TfeTextView *tv)
|
||||||
|
~~~
|
||||||
|
|
||||||
`saveas` function uses GtkFileChooserDialog and lets the user to give a new file to the program. Then, the function changes `tv->file` and save the contents to the specified new file.
|
`saveas` function uses GtkFileChooserDialog and lets the user to give a new file to the program. Then, the function changes `tv->file` and save the contents to the specified new file.
|
||||||
|
|
||||||
|
@ -121,7 +129,9 @@ It gets Gfile from GtkFileChooserDialog, save the buffer to the file by calling
|
||||||
Open function shows GtkFileChooserDialog to the user and let them choose a file.
|
Open function shows GtkFileChooserDialog to the user and let them choose a file.
|
||||||
Then read the file and set it to GtkTextBuffer.
|
Then read the file and set it to GtkTextBuffer.
|
||||||
|
|
||||||
|
~~~C
|
||||||
void tfe_text_view_open (TfeTextView *tv, GtkWidget *win);
|
void tfe_text_view_open (TfeTextView *tv, GtkWidget *win);
|
||||||
|
~~~
|
||||||
|
|
||||||
TfeTextView object `tv` has to be generated in advance.
|
TfeTextView object `tv` has to be generated in advance.
|
||||||
This function is usually called just after `tv` has been generated.
|
This function is usually called just after `tv` has been generated.
|
||||||
|
|
|
@ -56,19 +56,25 @@ It implies that CSS can also be apllied to GTK windowing system.
|
||||||
|
|
||||||
The syntax of CSS is as follws.
|
The syntax of CSS is as follws.
|
||||||
|
|
||||||
|
~~~css
|
||||||
selector { color: yellow; padding-top: 10px; ...}
|
selector { color: yellow; padding-top: 10px; ...}
|
||||||
|
~~~
|
||||||
|
|
||||||
Every widget has CSS node.
|
Every widget has CSS node.
|
||||||
For example GtkTextView has `textview` node.
|
For example GtkTextView has `textview` node.
|
||||||
If you want to set style to GtkTextView, set "textview" to the selector.
|
If you want to set style to GtkTextView, set "textview" to the selector.
|
||||||
|
|
||||||
|
~~~css
|
||||||
textview {color: yeallow; ...}
|
textview {color: yeallow; ...}
|
||||||
|
~~~
|
||||||
|
|
||||||
Class, ID and some other things can be applied to the selector like Web CSS. Refer GTK4 API reference for further information.
|
Class, ID and some other things can be applied to the selector like Web CSS. Refer GTK4 API reference for further information.
|
||||||
|
|
||||||
In line 30, the CSS is a string.
|
In line 30, the CSS is a string.
|
||||||
|
|
||||||
|
~~~css
|
||||||
textview {padding: 10px; font-family: monospace; font-size: 12pt;}
|
textview {padding: 10px; font-family: monospace; font-size: 12pt;}
|
||||||
|
~~~
|
||||||
|
|
||||||
- padding is a space between the border and contents.
|
- padding is a space between the border and contents.
|
||||||
This space makes the text easier to read.
|
This space makes the text easier to read.
|
||||||
|
@ -98,6 +104,7 @@ Look at the source file of `startup` handler again.
|
||||||
It is possible to add the provider to the context of GtkTextView instead of GdkDiplay.
|
It is possible to add the provider to the context of GtkTextView instead of GdkDiplay.
|
||||||
To do so, rewrite `tfe_text_view_new`.
|
To do so, rewrite `tfe_text_view_new`.
|
||||||
|
|
||||||
|
~~~C
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
tfe_text_view_new (void) {
|
tfe_text_view_new (void) {
|
||||||
GtkWidget *tv;
|
GtkWidget *tv;
|
||||||
|
@ -113,6 +120,7 @@ To do so, rewrite `tfe_text_view_new`.
|
||||||
|
|
||||||
return tv;
|
return tv;
|
||||||
}
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
CSS set to the context takes precedence over the one set to the display.
|
CSS set to the context takes precedence over the one set to the display.
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ TRUE corresponds to fullscreen and FALSE to non-fullscreen.
|
||||||
The following is an example code to implement a fullscreen menu except the signal handler.
|
The following is an example code to implement a fullscreen menu except the signal handler.
|
||||||
The signal handler will be described after the explanation of this code.
|
The signal handler will be described after the explanation of this code.
|
||||||
|
|
||||||
|
~~~C
|
||||||
static void
|
static void
|
||||||
on_activate (GApplication *app, gpointer user_data) {
|
on_activate (GApplication *app, gpointer user_data) {
|
||||||
... ... ...
|
... ... ...
|
||||||
|
@ -25,6 +26,7 @@ The signal handler will be described after the explanation of this code.
|
||||||
g_signal_connect (act_fullscreen, "change-state", G_CALLBACK (fullscreen_changed), win);
|
g_signal_connect (act_fullscreen, "change-state", G_CALLBACK (fullscreen_changed), win);
|
||||||
... ... ...
|
... ... ...
|
||||||
}
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
- `act_fullscreen` is GSimpleAction.
|
- `act_fullscreen` is GSimpleAction.
|
||||||
It is generated by `g_simple_action_new_stateful`.
|
It is generated by `g_simple_action_new_stateful`.
|
||||||
|
@ -50,6 +52,7 @@ Then, the default behaviour for boolean-stated actions with a NULL parameter typ
|
||||||
|
|
||||||
The following is the "change-state" signal handler.
|
The following is the "change-state" signal handler.
|
||||||
|
|
||||||
|
~~~C
|
||||||
static void
|
static void
|
||||||
fullscreen_changed(GSimpleAction *action, GVariant *value, gpointer win) {
|
fullscreen_changed(GSimpleAction *action, GVariant *value, gpointer win) {
|
||||||
if (g_variant_get_boolean (value))
|
if (g_variant_get_boolean (value))
|
||||||
|
@ -58,6 +61,7 @@ The following is the "change-state" signal handler.
|
||||||
gtk_window_unmaximize (GTK_WINDOW (win));
|
gtk_window_unmaximize (GTK_WINDOW (win));
|
||||||
g_simple_action_set_state (action, value);
|
g_simple_action_set_state (action, value);
|
||||||
}
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
- There are three parameters.
|
- There are three parameters.
|
||||||
The first parameter is the action which emits the "change-state" signal.
|
The first parameter is the action which emits the "change-state" signal.
|
||||||
|
@ -78,11 +82,15 @@ But the way above is the simplest and best.
|
||||||
GVarient can contain boolean, string or other simple type values.
|
GVarient can contain boolean, string or other simple type values.
|
||||||
For example, the following program set TRUE to `value` whose type is GVariant.
|
For example, the following program set TRUE to `value` whose type is GVariant.
|
||||||
|
|
||||||
|
~~~C
|
||||||
GVariant *value = g_variant_new_boolean (TRUE);
|
GVariant *value = g_variant_new_boolean (TRUE);
|
||||||
|
~~~
|
||||||
|
|
||||||
Another example is:
|
Another example is:
|
||||||
|
|
||||||
|
~~~C
|
||||||
GVariant *value2 = g_variant_new_string ("Hello");
|
GVariant *value2 = g_variant_new_string ("Hello");
|
||||||
|
~~~
|
||||||
|
|
||||||
`value2` is a GVariant and it has a string type value "Hello".
|
`value2` is a GVariant and it has a string type value "Hello".
|
||||||
GVariant can contain other types like int16, int32, int64, double and so on.
|
GVariant can contain other types like int16, int32, int64, double and so on.
|
||||||
|
@ -90,12 +98,16 @@ GVariant can contain other types like int16, int32, int64, double and so on.
|
||||||
If you want to get the original value, use g\_variant\_get series functions.
|
If you want to get the original value, use g\_variant\_get series functions.
|
||||||
For example, you can get the boolean value by g\_variant_get_boolean.
|
For example, you can get the boolean value by g\_variant_get_boolean.
|
||||||
|
|
||||||
|
~~~C
|
||||||
gboolean bool = g_variant_get_boolean (value);
|
gboolean bool = g_variant_get_boolean (value);
|
||||||
|
~~~
|
||||||
|
|
||||||
Because `value` has been generated as a boolean type GVariant and `TRUE` value, `bool` equals `TRUE`.
|
Because `value` has been generated as a boolean type GVariant and `TRUE` value, `bool` equals `TRUE`.
|
||||||
In the same way, you can get a string from `value2`
|
In the same way, you can get a string from `value2`
|
||||||
|
|
||||||
|
~~~C
|
||||||
const gchar *str = g_variant_get_string (value2, NULL);
|
const gchar *str = g_variant_get_string (value2, NULL);
|
||||||
|
~~~
|
||||||
|
|
||||||
The second parameter is a pointer to gsize type variable (gsize is defined as unsigned long).
|
The second parameter is a pointer to gsize type variable (gsize is defined as unsigned long).
|
||||||
If it isn't NULL, then the length of the string will be set by the function.
|
If it isn't NULL, then the length of the string will be set by the function.
|
||||||
|
@ -112,6 +124,7 @@ The action has a state which values are "red", "green" and "blue".
|
||||||
The values are string.
|
The values are string.
|
||||||
Those colors are given to the signal handler as a parameter.
|
Those colors are given to the signal handler as a parameter.
|
||||||
|
|
||||||
|
~~~C
|
||||||
static void
|
static void
|
||||||
on_activate (GApplication *app, gpointer user_data) {
|
on_activate (GApplication *app, gpointer user_data) {
|
||||||
... ... ...
|
... ... ...
|
||||||
|
@ -123,6 +136,7 @@ Those colors are given to the signal handler as a parameter.
|
||||||
g_signal_connect (act_color, "activate", G_CALLBACK (color_activated), win);
|
g_signal_connect (act_color, "activate", G_CALLBACK (color_activated), win);
|
||||||
... ... ...
|
... ... ...
|
||||||
}
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
- `act_color` is GSimpleAction.
|
- `act_color` is GSimpleAction.
|
||||||
It is generated by `g_simple_action_new_stateful`.
|
It is generated by `g_simple_action_new_stateful`.
|
||||||
|
@ -148,6 +162,7 @@ Then the default behaviour is to call `g_simple_action_set_state()` to set the s
|
||||||
|
|
||||||
The following is the "activate" signal handler.
|
The following is the "activate" signal handler.
|
||||||
|
|
||||||
|
~~~C
|
||||||
static void
|
static void
|
||||||
color_activated(GSimpleAction *action, GVariant *parameter, gpointer win) {
|
color_activated(GSimpleAction *action, GVariant *parameter, gpointer win) {
|
||||||
gchar *color = g_strdup_printf ("label#lb {background-color: %s;}",
|
gchar *color = g_strdup_printf ("label#lb {background-color: %s;}",
|
||||||
|
@ -156,6 +171,7 @@ The following is the "activate" signal handler.
|
||||||
g_free (color);
|
g_free (color);
|
||||||
g_action_change_state (G_ACTION (action), parameter);
|
g_action_change_state (G_ACTION (action), parameter);
|
||||||
}
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
- There are three parameters.
|
- There are three parameters.
|
||||||
The first parameter is the action which emits the "activate" signal.
|
The first parameter is the action which emits the "activate" signal.
|
||||||
|
|
|
@ -169,8 +169,10 @@ GtkWindow includes GtkWidget at the top of its object.
|
||||||
|
|
||||||
The function `gtk_window_new` is defined as follows.
|
The function `gtk_window_new` is defined as follows.
|
||||||
|
|
||||||
|
~~~C
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
gtk_window_new (void);
|
gtk_window_new (void);
|
||||||
|
~~~
|
||||||
|
|
||||||
By this definition, it returns a pointer to GtkWidget, not GtkWindow.
|
By this definition, it returns a pointer to GtkWidget, not GtkWindow.
|
||||||
It actually generates a new GtkWindow object (not GtkWidget) but returns a pointer to GtkWidget.
|
It actually generates a new GtkWindow object (not GtkWidget) but returns a pointer to GtkWidget.
|
||||||
|
@ -178,11 +180,15 @@ However,the pointer points the GtkWidget and at the same time it also points Gtk
|
||||||
|
|
||||||
If you want to use `win` as a pointer to the GtkWindow, you need to cast it.
|
If you want to use `win` as a pointer to the GtkWindow, you need to cast it.
|
||||||
|
|
||||||
|
~~~C
|
||||||
(GtkWindow *) win
|
(GtkWindow *) win
|
||||||
|
~~~
|
||||||
|
|
||||||
Or you can use `GTK_WINDOW` macro that performs a similar function.
|
Or you can use `GTK_WINDOW` macro that performs a similar function.
|
||||||
|
|
||||||
|
~~~C
|
||||||
GTK_WINDOW (win)
|
GTK_WINDOW (win)
|
||||||
|
~~~
|
||||||
|
|
||||||
This is a recommended way.
|
This is a recommended way.
|
||||||
|
|
||||||
|
@ -190,7 +196,9 @@ This is a recommended way.
|
||||||
|
|
||||||
The function `gtk_window_set_application` is used to connect GtkWidow to GtkApplication.
|
The function `gtk_window_set_application` is used to connect GtkWidow to GtkApplication.
|
||||||
|
|
||||||
|
~~~C
|
||||||
gtk_window_set_application (GTK_WINDOW (win), GTK_APPLICATION (app));
|
gtk_window_set_application (GTK_WINDOW (win), GTK_APPLICATION (app));
|
||||||
|
~~~
|
||||||
|
|
||||||
You need to cast `win` to GtkWindow and `app` to GtkApplication.
|
You need to cast `win` to GtkWindow and `app` to GtkApplication.
|
||||||
`GTK_WINDOW` and `GTK_APPLICATION` macro is appropriate for that.
|
`GTK_WINDOW` and `GTK_APPLICATION` macro is appropriate for that.
|
||||||
|
|
|
@ -20,17 +20,21 @@ It is described in the GIO API reference.
|
||||||
|
|
||||||
When GtkApplication is generated, a flag (its type is GApplicationFlags) is given as an argument.
|
When GtkApplication is generated, a flag (its type is GApplicationFlags) is given as an argument.
|
||||||
|
|
||||||
|
~~~C
|
||||||
GtkApplication *
|
GtkApplication *
|
||||||
gtk_application_new (const gchar *application_id, GApplicationFlags flags);
|
gtk_application_new (const gchar *application_id, GApplicationFlags flags);
|
||||||
|
~~~
|
||||||
|
|
||||||
This flag is described in the GApplication section in GIO API reference.
|
This flag is described in the GApplication section in GIO API reference.
|
||||||
|
|
||||||
|
~~~C
|
||||||
GApplicationFlags' Members
|
GApplicationFlags' Members
|
||||||
|
|
||||||
G_APPLICATION_FLAGS_NONE Default. (No argument allowed)
|
G_APPLICATION_FLAGS_NONE Default. (No argument allowed)
|
||||||
... ... ...
|
... ... ...
|
||||||
G_APPLICATION_HANDLES_OPEN This application handles opening files (in the primary instance).
|
G_APPLICATION_HANDLES_OPEN This application handles opening files (in the primary instance).
|
||||||
... ... ...
|
... ... ...
|
||||||
|
~~~
|
||||||
|
|
||||||
There are ten flags.
|
There are ten flags.
|
||||||
But we only need two of them so far.
|
But we only need two of them so far.
|
||||||
|
@ -45,7 +49,9 @@ The application assumes all the arguments are filenames.
|
||||||
|
|
||||||
Now we use this flag when generating GtkApplication.
|
Now we use this flag when generating GtkApplication.
|
||||||
|
|
||||||
|
~~~C
|
||||||
app = gtk_application_new ("com.github.ToshioCP.tfv3", G_APPLICATION_HANDLES_OPEN);
|
app = gtk_application_new ("com.github.ToshioCP.tfv3", G_APPLICATION_HANDLES_OPEN);
|
||||||
|
~~~
|
||||||
|
|
||||||
### open signal
|
### open signal
|
||||||
|
|
||||||
|
@ -56,11 +62,13 @@ When the application starts, two signals are possible.
|
||||||
|
|
||||||
The handler of open signal is called as follows.
|
The handler of open signal is called as follows.
|
||||||
|
|
||||||
|
~~~C
|
||||||
void user_function (GApplication *application,
|
void user_function (GApplication *application,
|
||||||
gpointer files,
|
gpointer files,
|
||||||
gint n_files,
|
gint n_files,
|
||||||
gchar *hint,
|
gchar *hint,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
|
~~~
|
||||||
|
|
||||||
The parameters are as follows:
|
The parameters are as follows:
|
||||||
|
|
||||||
|
@ -117,6 +125,7 @@ The point is the handler `on_open`.
|
||||||
|
|
||||||
The file reading part of the program is shown again below.
|
The file reading part of the program is shown again below.
|
||||||
|
|
||||||
|
~~~C
|
||||||
if (g_file_load_contents(files[0], NULL, &contents, &length, NULL, NULL)) {
|
if (g_file_load_contents(files[0], NULL, &contents, &length, NULL, NULL)) {
|
||||||
gtk_text_buffer_set_text(tb, contents, length);
|
gtk_text_buffer_set_text(tb, contents, length);
|
||||||
g_free(contents);
|
g_free(contents);
|
||||||
|
@ -129,6 +138,7 @@ The file reading part of the program is shown again below.
|
||||||
g_print ("No such file: %s.\n", filename);
|
g_print ("No such file: %s.\n", filename);
|
||||||
gtk_window_destroy (GTK_WINDOW (win));
|
gtk_window_destroy (GTK_WINDOW (win));
|
||||||
}
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
The function `g_file_load_contents` loads the file contents into a buffer, which is automatically allocated, and set the pointer to the buffer into `contents`.
|
The function `g_file_load_contents` loads the file contents into a buffer, which is automatically allocated, and set the pointer to the buffer into `contents`.
|
||||||
And the length of the buffer is set to `length`.
|
And the length of the buffer is set to `length`.
|
||||||
|
|
|
@ -22,7 +22,9 @@ Using global variables is easy to implement.
|
||||||
Define a sufficient size array of pointers to GFile.
|
Define a sufficient size array of pointers to GFile.
|
||||||
For example,
|
For example,
|
||||||
|
|
||||||
|
~~~C
|
||||||
GFile *f[20];
|
GFile *f[20];
|
||||||
|
~~~
|
||||||
|
|
||||||
And `f[i]` corresponds to i-th GtkNotebookPage.
|
And `f[i]` corresponds to i-th GtkNotebookPage.
|
||||||
However, there are two problems.
|
However, there are two problems.
|
||||||
|
@ -151,7 +153,9 @@ A handler is a C function.
|
||||||
When a function is connected to a certain signal, we call it handler.
|
When a function is connected to a certain signal, we call it handler.
|
||||||
The function `before_close` is invoked when the signal "close-request" is emittd.
|
The function `before_close` is invoked when the signal "close-request" is emittd.
|
||||||
|
|
||||||
|
~~~C
|
||||||
g_signal_connect (win, "close-request", G_CALLBACK (before_close), NULL);
|
g_signal_connect (win, "close-request", G_CALLBACK (before_close), NULL);
|
||||||
|
~~~
|
||||||
|
|
||||||
The argument win is GtkApplicationWindow, in which the signal "close-request" is defined, and before\_close is the handler.
|
The argument win is GtkApplicationWindow, in which the signal "close-request" is defined, and before\_close is the handler.
|
||||||
`G_CALLBACK` cast is necessary for the handler.
|
`G_CALLBACK` cast is necessary for the handler.
|
||||||
|
|
|
@ -78,8 +78,10 @@ So it is an old and widely used program.
|
||||||
Make analyzes Makefile and executes compilers.
|
Make analyzes Makefile and executes compilers.
|
||||||
All instructions are written in Makefile.
|
All instructions are written in Makefile.
|
||||||
|
|
||||||
|
~~~Makefile
|
||||||
sample.o: sample.c
|
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 -0 sample.o sample.c`.
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue