Merge branch 'matthiasc/for-master' into 'master'

Matthiasc/for master

Closes #2729 and #2730

See merge request GNOME/gtk!1870
This commit is contained in:
Matthias Clasen 2020-05-11 12:51:08 +00:00
commit 9f3fb69dce
81 changed files with 560 additions and 1251 deletions

View File

@ -6,17 +6,17 @@
<title>Getting Started with GTK</title>
<para>GTK is a <ulink url="http://en.wikipedia.org/wiki/Widget_toolkit">
widget toolkit</ulink>. Each user interface created by
GTK consists of widgets. This is implemented in C using
widget toolkit</ulink>. Each user interface created by
GTK consists of widgets. This is implemented in C using
<link linkend="gobject">GObject</link>, an object-oriented framework for C.
Widgets are organized in a hierachy. The window widget is the main container.
The user interface is then built by adding buttons, drop-down menus, input
The user interface is then built by adding buttons, drop-down menus, input
fields, and other widgets to the window.
If you are creating complex user interfaces it is recommended to
use #GtkBuilder and its GTK-specific markup description language, instead of
use GtkBuilder and its GTK-specific markup description language, instead of
assembling the interface manually. You can also use a visual user interface
editor, like <ulink url="https://glade.gnome.org/">Glade</ulink>.</para>
<para>GTK is event-driven. The toolkit listens for events such as
a click on a button, and passes the event to your application.</para>
@ -30,8 +30,8 @@
<section>
<title>Basics</title>
<para>To begin our introduction to GTK, we'll start with a simple
signal-based Gtk application. This program will create an empty 200 × 200 pixel
<para>To begin our introduction to GTK, we'll start with a very simple
application. This program will create an empty 200 × 200 pixel
window.</para>
<informalfigure>
@ -64,68 +64,61 @@
<warning><para>Even if GTK installs multiple header files, only the
top-level <filename>gtk/gtk.h</filename> header can be directly included
by third party code. The compiler will abort with an error if any other
by third-party code. The compiler will abort with an error if any other
header is directly included.</para></warning>
<para>In a GTK application, the purpose of the main() function is to
create a #GtkApplication object and run it. In this example a
#GtkApplication pointer named <varname>app</varname> is called and then
initialized using gtk_application_new().</para>
<para>In a GTK application, the purpose of the main() function is
to create a GtkApplication object and run it. In this example a
GtkApplication pointer named <varname>app</varname> is declared
and then initialized using gtk_application_new().</para>
<para>When creating a #GtkApplication
you need to pick an application identifier (a name)
and input to gtk_application_new() as parameter.
For this example <varname>org.gtk.example</varname> is used
but for choosing an identifier for your application see
<para>When creating a GtkApplication, you need to pick an application
identifier (a name) and pass it to gtk_application_new() as parameter.
For this example <varname>org.gtk.example</varname> is used. For
choosing an identifier for your application, see
<ulink url="https://wiki.gnome.org/HowDoI/ChooseApplicationID">this guide</ulink>.
Lastly gtk_application_new() takes a GApplicationFlags as input for your
Lastly gtk_application_new() takes #GApplicationFlags as input for your
application, if your application would have special needs.
</para>
<para>Next the
<ulink url="https://wiki.gnome.org/HowDoI/GtkApplication">activate signal</ulink>
is connected to the activate() function above the main() functions.
The <varname>activate</varname> signal will be sent
when your application is launched with
g_application_run() on the line below.
The g_application_run() also takes as arguments the command line arguments counter
and the pointer to string array; this allows GTK to parse specific command line
arguments that control the behavior of GTK itself. The parsed arguments
will be removed from the array, leaving the unrecognized ones for your
application to parse.
is connected to the activate() function above the main() function.
The <varname>activate</varname> signal will be emitted when your application
is launched with g_application_run() on the line below. The g_application_run()
call also takes as arguments the command line arguments (the
<varname>argc</varname> count and the <varname>argv</varname> string array).
Your application can override the command line handling, e.g. to open
files passed on the commandline.
</para>
<para>Within g_application_run the activate() signal is sent and
we then proceed into the <function>activate</function>() function of the
application. Inside the activate() function we want to construct
our GTK window, so that a window is shown when the application
is launched. The call to gtk_application_window_new() will
create a new #GtkWindow and store it inside the
<varname>window</varname> pointer. The window will have a frame,
a title bar, and window controls depending on the platform.</para>
<para>Within g_application_run() the activate signal is sent and we then
proceed into the activate() function of the application. This is where we
construct our GTK window, so that a window is shown when the application
is launched. The call to gtk_application_window_new() will create a new
GtkWindow and store it inside the <varname>window</varname> pointer. The
window will have a frame, a title bar, and window controls depending on
the platform.</para>
<para>A window title is set using gtk_window_set_title(). This function
takes a GtkWindow* pointer and a string as input. As our
<varname>window</varname> pointer is a GtkWidget pointer, we need to cast it
to GtkWindow*.
But instead of casting <varname>window</varname> via
<varname>(GtkWindow*)</varname>,
<varname>window</varname> can be cast using the macro
<varname>GTK_WINDOW()</varname>.
<varname>GTK_WINDOW()</varname> will check if the
pointer is an instance of the GtkWindow class, before casting, and emit a
warning if the check fails. More information about this convention
can be found
<varname>window</varname> pointer is a GtkWidget pointer, we need to cast
it to GtkWindow*. But instead of casting <varname>window</varname> via
<varname>(GtkWindow*)</varname>, <varname>window</varname> can be cast
using the macro <varname>GTK_WINDOW()</varname>. <varname>GTK_WINDOW()</varname>
will check if the pointer is an instance of the GtkWindow class, before
casting, and emit a warning if the check fails. More information about
this convention can be found
<ulink url="https://developer.gnome.org/gobject/stable/gtype-conventions.html">
here</ulink>.</para>
<para>Finally the window size is set using gtk_window_set_default_size and
the window is then shown by GTK via gtk_widget_show().</para>
<para>Finally the window size is set using gtk_window_set_default_sizei()
and the window is then shown by GTK via gtk_widget_show().</para>
<para>When you exit the window, by for example pressing the X,
the g_application_run() in the main loop returns with a number
which is saved inside an integer named "status". Afterwards, the
#GtkApplication object is freed from memory with g_object_unref().
GtkApplication object is freed from memory with g_object_unref().
Finally the status integer is returned and the GTK application exits.</para>
<para>While the program is running, GTK is receiving
@ -139,8 +132,12 @@
<para>The following example is slightly more complex, and tries to
showcase some of the capabilities of GTK.</para>
</section>
<section>
<title>Hello, World</title>
<para>In the long tradition of programming languages and libraries,
it is called <emphasis>Hello, World</emphasis>.</para>
this example is called <emphasis>Hello, World</emphasis>.</para>
<informalfigure>
<mediaobject>
@ -163,55 +160,59 @@
<literal>gcc `pkg-config --cflags gtk4` -o example-1 example-1.c `pkg-config --libs gtk4`</literal>
</literallayout>
</para>
</section>
<para>As seen above, example-1.c builds further upon example-0.c by adding a
button to our window, with the label "Hello World". Two new GtkWidget pointers
are declared to accomplish this, <varname>button</varname> and
<varname>button_box</varname>. The button_box variable is created to store a
#GtkBox which is GTK's way of controlling the size and layout of buttons.
The #GtkBox is created and assigned to gtk_box_new() which takes a
#GtkOrientation enum as parameter. The buttons which this box will contain can
either be stored horizontally or vertically but this does not matter in this
particular case as we are dealing with only one button. After initializing
button_box with horizontal orientation, the code adds the button_box widget to the
window widget using gtk_container_add().</para>
<varname>box</varname>. The box variable is created to store a GtkBox, which
is GTK's way of controlling the size and layout of buttons.
</para>
<para>The GtkBox is created with gtk_box_new() which takes a GtkOrientation
enum as parameter. The buttons which this box will contain can either be layed
out horizontally or vertically. This does not matter in this particular case,
as we are dealing with only one button. After initializing box with the newly
created GtkBox, the code adds the box widget to the window widget using
gtk_window_set_child().</para>
<para>Next the <varname>button</varname> variable is initialized in similar manner.
gtk_button_new_with_label() is called which returns a GtkButton to be stored inside
gtk_button_new_with_label() is called which returns a GtkButton to be stored in
<varname>button</varname>. Afterwards <varname>button</varname> is added to
our <varname>button_box</varname>.
Using g_signal_connect the button is connected to a function in our app called
our <varname>box</varname>.
</para>
<para>
Using g_signal_connect(), the button is connected to a function in our app called
print_hello(), so that when the button is clicked, GTK will call this function.
As the print_hello() function does not use any data as input, NULL is passed
to it. print_hello() calls g_print() with the string "Hello World"
which will print Hello World in a terminal if the GTK application was started
from one.</para>
<para>After connecting print_hello(), another signal is connected to the "clicked" state
of the button using g_signal_connect_swapped(). This functions is similar to
<para>After connecting print_hello(), another signal is connected to the "clicked"
state of the button using g_signal_connect_swapped(). This functions is similar to
a g_signal_connect() with the difference lying in how the callback function is
treated. g_signal_connect_swapped() allow you to specify what the callback
treated. g_signal_connect_swapped() allows you to specify what the callback
function should take as parameter by letting you pass it as data. In this case
the function being called back is gtk_widget_destroy() and the <varname>window</varname>
pointer is passed to it. This has the effect that when the button is clicked,
the whole GTK window is destroyed. In contrast if a normal g_signal_connect() were used
to connect the "clicked" signal with gtk_widget_destroy(), then the <varname>button</varname>
itself would have been destroyed, not the window.
More information about creating buttons can be found
the function being called back is gtk_widget_destroy() and the
<varname>window</varname> pointer is passed to it. This has the effect that when
the button is clicked, the whole GTK window is destroyed. In contrast, if a normal
g_signal_connect() were used to connect the "clicked" signal with
gtk_widget_destroy(), then the <varname>button</varname> itself would have been
destroyed, not the window. More information about creating buttons can be found
<ulink url="https://wiki.gnome.org/HowDoI/Buttons">here</ulink>.
</para>
<para>The rest of the code in example-1.c is identical to example-0.c. Next
section will elaborate further on how to add several GtkWidgets to your GTK
application.</para>
</section>
<section>
<title>Packing</title>
<para>When creating an application, you'll want to put more than one widget
inside a window.
When you want to put more than one widget into a window,
inside a window. When you want to put more than one widget into a window,
it becomes important to control how each widget is positioned and sized.
This is where packing comes in.</para>
@ -325,11 +326,11 @@
</para>
<para>GTK includes application support that is built on top of
#GApplication. In this tutorial we'll build a simple application by
GApplication. In this tutorial we'll build a simple application by
starting from scratch, adding more and more pieces over time. Along
the way, we'll learn about #GtkApplication, templates, resources,
application menus, settings, #GtkHeaderBar, #GtkStack, #GtkSearchBar,
#GtkListBox, and more.</para>
the way, we'll learn about GtkApplication, templates, resources,
application menus, settings, GtkHeaderBar, GtkStack, GtkSearchBar,
GtkListBox, and more.</para>
<para>The full, buildable sources for these examples can be found
in the examples/ directory of the GTK source distribution, or
@ -341,7 +342,7 @@
<section>
<title>A trivial application</title>
<para>When using #GtkApplication, the main() function can be very
<para>When using GtkApplication, the main() function can be very
simple. We just call g_application_run() and give it an instance
of our application class.</para>
@ -350,7 +351,7 @@
</informalexample>
<para>All the application logic is in the application class, which
is a subclass of #GtkApplication. Our example does not yet have any
is a subclass of GtkApplication. Our example does not yet have any
interesting functionality. All it does is open a window when it is
activated without arguments, and open the files it is given, if it
is started with arguments.</para>
@ -368,7 +369,7 @@
</informalexample>
<para>Another important class that is part of the application support
in GTK is #GtkApplicationWindow. It is typically subclassed as well.
in GTK is GtkApplicationWindow. It is typically subclassed as well.
Our subclass does not do anything yet, so we will just get an empty
window.</para>
@ -412,11 +413,10 @@
<section>
<title>Populating the window</title>
<para>In this step, we use a #GtkBuilder template to associate a
#GtkBuilder ui file with our application window class.</para>
<para>Our simple ui file puts a #GtkHeaderBar on top of a #GtkStack
widget. The header bar contains a #GtkStackSwitcher, which is a
standalone widget to show a row of 'tabs' for the pages of a #GtkStack.
<para>In this step, we use a GtkBuilder template to associate a
GtkBuilder ui file with our application window class.</para>
<para>Our simple ui file gives the window a title, and puts a GtkStack
widget as the main content.
</para>
<informalexample>
@ -424,7 +424,7 @@
</informalexample>
<para>To make use of this file in our application, we revisit
our #GtkApplicationWindow subclass, and call
our GtkApplicationWindow subclass, and call
gtk_widget_class_set_template_from_resource() from the class init
function to set the ui file as template for this class. We also
add a call to gtk_widget_init_template() in the instance init
@ -453,8 +453,9 @@ example_app_window_class_init (ExampleAppWindowClass *class)
<para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application2/exampleappwin.c">full source</ulink>)</para>
</informalexample>
<para>You may have noticed that we used the <literal>_from_resource(<!-- -->)</literal> variant
of the function that sets a template. Now we need to use <ulink url="https://developer.gnome.org/gio/stable/GResource.html">GLib's resource functionality</ulink>
<para>You may have noticed that we used the <literal>_from_resource()</literal>
variant of the function that sets a template. Now we need to use
<ulink url="https://developer.gnome.org/gio/stable/GResource.html">GLib's resource functionality</ulink>
to include the ui file in the binary. This is commonly done by listing
all resources in a .gresource.xml file, such as this:
</para>
@ -488,15 +489,14 @@ example_app_window_class_init (ExampleAppWindowClass *class)
<para>In this step, we make our application show the content of
all the files that it is given on the commandline.</para>
<para>To this end, we add a member to the struct in application
window subclass and keep a reference to the #GtkStack there.
The first member of the struct should be the parent type from
which the class is derived. Here, ExampleAppWindow is derived
from GtkApplicationWindow.
The gtk_widget_class_bind_template_child() function
arranges things so that after instantiating the template, the
@stack member of the struct will point to the widget of
the same name from the template.</para>
<para>To this end, we add a member to the struct of our application
window subclass and keep a reference to the GtkStack there. The first
member of the struct should be the parent type from which the class is
derived. Here, ExampleAppWindow is derived from GtkApplicationWindow.
The gtk_widget_class_bind_template_child() function arranges things so
that after instantiating the template, the <varname>stack</varname>
member of the struct will point to the widget of the same name from
the template.</para>
<informalexample>
<programlisting><![CDATA[
@ -538,9 +538,9 @@ void
example_app_window_open (ExampleAppWindow *win,
GFile *file)
{
gchar *basename;
char *basename;
GtkWidget *scrolled, *view;
gchar *contents;
char *contents;
gsize length;
basename = g_file_get_basename (file);
@ -551,7 +551,7 @@ example_app_window_open (ExampleAppWindow *win,
view = gtk_text_view_new ();
gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
gtk_scrolled_window (GTK_SCROLLED_WINDOW (scrolled), view);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolled), view);
gtk_stack_add_titled (GTK_STACK (win->stack), scrolled, basename, basename);
if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL))
@ -571,11 +571,14 @@ example_app_window_open (ExampleAppWindow *win,
<para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application3/exampleappwin.c">full source</ulink>)</para>
</informalexample>
<para>Note that we did not have to touch the stack switcher
at all. It gets all its information from the stack that it
belongs to. Here, we are passing the label to show for each
file as the last argument to the gtk_stack_add_titled()
function.</para>
<para>Lastly, we add a GtkStackSwitcher to the titlebar area
in the ui file, and we tell it to display information about our
stack.</para>
<para>The stack switcher gets all its information it needs to
display tabs from the stack that it belongs to. Here, we are
passing the label to show for each file as the last argument to
the gtk_stack_add_titled() function.</para>
<para>Our application is beginning to take shape:</para>
@ -589,25 +592,25 @@ example_app_window_open (ExampleAppWindow *win,
</section>
<section>
<title>An application menu</title>
<title>A menu</title>
<para>An application menu is shown by GNOME shell at the top of the
screen. It is meant to collect infrequently used actions that affect
<para>The menu is shown at the right side of the headerbar.
It is meant to collect infrequently used actions that affect
the whole application.</para>
<para>Just like the window template, we specify our application menu
<para>Just like the window template, we specify our menu
in a ui file, and add it as a resource to our binary.</para>
<informalexample>
<programlisting><xi:include href="@SRC_DIR@/examples/application4/app-menu.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
<programlisting><xi:include href="@SRC_DIR@/examples/application4/gears-menu.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
</informalexample>
<para>To associate the app menu with the application, we have to call
gtk_application_set_app_menu(). Since app menus work by activating
#GActions, we also have to add a suitable set of actions to our
application.</para>
<para>To make the menu appear, we have to load the ui file and
associate the resulting menu model with the menu button that we've
added to the headerbar. Since menus work by activating GActions,
we also have to add a suitable set of actions to our application.</para>
<para>Both of these tasks are best done in the startup() vfunc,
<para>Adding the actions is best done in the startup() vfunc,
which is guaranteed to be called once for each primary application
instance:</para>
<informalexample>
@ -650,11 +653,6 @@ example_app_startup (GApplication *app)
gtk_application_set_accels_for_action (GTK_APPLICATION (app),
"app.quit",
quit_accels);
builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/app-menu.ui");
app_menu = G_MENU_MODEL (gtk_builder_get_object (builder, "appmenu"));
gtk_application_set_app_menu (GTK_APPLICATION (app), app_menu);
g_object_unref (builder);
}
static void
@ -756,8 +754,9 @@ example_app_window_init (ExampleAppWindow *win)
<programlisting><xi:include href="@SRC_DIR@/examples/application6/exampleappprefs.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
</informalexample>
<para>Now we revisit the <literal>preferences_activated(<!-- -->)</literal> function in our
application class, and make it open a new preference dialog.</para>
<para>Now we revisit the <literal>preferences_activated()</literal>
function in our application class, and make it open a new preference
dialog.</para>
<informalexample>
<programlisting><![CDATA[
@ -797,8 +796,8 @@ preferences_activated (GSimpleAction *action,
<title>Adding a search bar</title>
<para>We continue to flesh out the functionality of our application.
For now, we add search. GTK supports this with #GtkSearchEntry and
#GtkSearchBar. The search bar is a widget that can slide in from the
For now, we add search. GTK supports this with GtkSearchEntry and
GtkSearchBar. The search bar is a widget that can slide in from the
top to present a search entry.</para>
<para>We add a toggle button to the header bar, which can be used
@ -833,7 +832,7 @@ search_text_changed (GtkEntry *entry,
return;
tab = gtk_stack_get_visible_child (GTK_STACK (win->stack));
view = gtk_bin_get_child (GTK_BIN (tab));
view = gtk_scrolled_window_get_child (GTK_SCROLLED_WINDOW (tab));
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
/* Very simple-minded search implementation */
@ -879,7 +878,7 @@ example_app_window_init (ExampleAppWindow *win)
<title>Adding a side bar</title>
<para>As another piece of functionality, we are adding a sidebar,
which demonstrates #GtkMenuButton, #GtkRevealer and #GtkListBox.</para>
which demonstrates GtkMenuButton, GtkRevealer and GtkListBox.</para>
<informalexample>
<programlisting><xi:include href="@SRC_DIR@/examples/application8/window.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
@ -897,7 +896,7 @@ example_app_window_init (ExampleAppWindow *win)
</informalexample>
<para>To connect the menuitem to the show-words setting, we use
a #GAction corresponding to the given #GSettings key.</para>
a GAction corresponding to the given GSettings key.</para>
<informalexample>
<programlisting><![CDATA[
@ -940,13 +939,13 @@ example_app_window_init (ExampleAppWindow *win)
<para>Widgets and other objects have many useful properties.</para>
<para>Here we show some ways to use them in new and flexible ways,
by wrapping them in actions with #GPropertyAction or by binding them
with #GBinding.</para>
by wrapping them in actions with GPropertyAction or by binding them
with GBinding.</para>
<para>To set this up, we add two labels to the header bar in our
window template, named @lines_label and @lines, and bind them to
struct members in the private struct, as we've seen a couple of times
by now.</para>
window template, named <varname>lines_label</varname> and
<varname>lines</varname>, and bind them to struct members in the
private struct, as we've seen a couple of times by now.</para>
<para>We add a new "Lines" menu item to the gears menu, which
triggers the show-lines action:</para>
@ -956,13 +955,14 @@ example_app_window_init (ExampleAppWindow *win)
</informalexample>
<para>To make this menu item do something, we create a property
action for the visible property of the @lines label, and add it to the
actions of the window. The effect of this is that the visibility
of the label gets toggled every time the action is activated.</para>
action for the visible property of the <varname>lines</varname> label,
and add it to the actions of the window. The effect of this is that the
visibility of the label gets toggled every time the action is activated.
</para>
<para>Since we want both labels to appear and disappear together,
we bind the visible property of the @lines_label widget to the
same property of the @lines widget.</para>
<para>Since we want both labels to appear and disappear together, we bind
the visible property of the <varname>lines_label</varname> widget to the
same property of the <varname>lines</varname> widget.</para>
<informalexample>
<programlisting>
@ -988,7 +988,7 @@ example_app_window_init (ExampleAppWindow *win)
</informalexample>
<para>We also need a function that counts the lines of the currently
active tab, and updates the @lines label. See the
active tab, and updates the <varname>lines</varname> label. See the
<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application9/exampleappwin.c">full source</ulink>
if you are interested in the details.</para>
@ -1002,35 +1002,6 @@ example_app_window_init (ExampleAppWindow *win)
</mediaobject>
</informalfigure>
</section>
<section>
<title>Header bar</title>
<para>Our application already uses a GtkHeaderBar, but so far it
still gets a 'normal' window titlebar on top of that. This is a
bit redundant, and we will now tell GTK to use the header bar
as replacement for the titlebar. To do so, we move it around to
be a direct child of the window, and set its type to be titlebar.</para>
<informalexample>
<programlisting><xi:include href="@SRC_DIR@/examples/application10/window.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
</informalexample>
<para>A small extra bonus of using a header bar is that we get
a fallback application menu for free. Here is how the
application now looks, if this fallback is used.</para>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="getting-started-app10.png" format="PNG"/>
</imageobject>
</mediaobject>
</informalfigure>
<para>If we set up the window icon for our window, the menu button
will use that instead of the generic placeholder icon you see
here.</para>
</section>
</section>
<section>
@ -1039,9 +1010,9 @@ example_app_window_init (ExampleAppWindow *win)
<para>Many widgets, like buttons, do all their drawing themselves. You
just tell them the label you want to see, and they figure out what font
to use, draw the button outline and focus rectangle, etc. Sometimes, it
is necessary to do some custom drawing. In that case, a #GtkDrawingArea
is necessary to do some custom drawing. In that case, a GtkDrawingArea
might be the right widget to use. It offers a canvas on which you can
draw by connecting to the #GtkWidget::draw signal.
draw by connecting to the ::draw signal.
</para>
<para>The contents of a widget often need to be partially or fully redrawn,
@ -1054,8 +1025,7 @@ example_app_window_init (ExampleAppWindow *win)
<para>The following example shows a ::draw signal handler. It is a bit
more complicated than the previous examples, since it also demonstrates
input event handling by means of ::button-press and ::motion-notify
handlers.</para>
input event handling by means of event controllers.</para>
<informalfigure>
<mediaobject>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 KiB

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

@ -1,3 +1,5 @@
Step 1: A trivial application
To make gnome-shell use the desktop file and icon for this example
while running it uninstalled, do the following:

View File

@ -1,35 +0,0 @@
CC ?= gcc
PKGCONFIG = $(shell which pkg-config)
CFLAGS = $(shell $(PKGCONFIG) --cflags gtk4)
LIBS = $(shell $(PKGCONFIG) --libs gtk4)
GLIB_COMPILE_RESOURCES = $(shell $(PKGCONFIG) --variable=glib_compile_resources gio-2.0)
GLIB_COMPILE_SCHEMAS = $(shell $(PKGCONFIG) --variable=glib_compile_schemas gio-2.0)
SRC = exampleapp.c exampleappwin.c exampleappprefs.c main.c
BUILT_SRC = resources.c
OBJS = $(BUILT_SRC:.c=.o) $(SRC:.c=.o)
all: exampleapp
org.gtk.exampleapp.gschema.valid: org.gtk.exampleapp.gschema.xml
$(GLIB_COMPILE_SCHEMAS) --strict --dry-run --schema-file=$< && mkdir -p $(@D) && touch $@
gschemas.compiled: org.gtk.exampleapp.gschema.valid
$(GLIB_COMPILE_SCHEMAS) .
resources.c: exampleapp.gresource.xml $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=. --generate-dependencies exampleapp.gresource.xml)
$(GLIB_COMPILE_RESOURCES) exampleapp.gresource.xml --target=$@ --sourcedir=. --generate-source
%.o: %.c
$(CC) -c -o $(@F) $(CFLAGS) $<
exampleapp: $(OBJS) gschemas.compiled
$(CC) -o $(@F) $(OBJS) $(LIBS)
clean:
rm -f org.gtk.exampleapp.gschema.valid
rm -f gschemas.compiled
rm -f $(BUILT_SRC)
rm -f $(OBJS)
rm -f exampleapp

View File

@ -1,114 +0,0 @@
#include <gtk/gtk.h>
#include "exampleapp.h"
#include "exampleappwin.h"
#include "exampleappprefs.h"
struct _ExampleApp
{
GtkApplication parent;
};
G_DEFINE_TYPE(ExampleApp, example_app, GTK_TYPE_APPLICATION);
static void
example_app_init (ExampleApp *app)
{
}
static void
preferences_activated (GSimpleAction *action,
GVariant *parameter,
gpointer app)
{
ExampleAppPrefs *prefs;
GtkWindow *win;
win = gtk_application_get_active_window (GTK_APPLICATION (app));
prefs = example_app_prefs_new (EXAMPLE_APP_WINDOW (win));
gtk_window_present (GTK_WINDOW (prefs));
}
static void
quit_activated (GSimpleAction *action,
GVariant *parameter,
gpointer app)
{
g_application_quit (G_APPLICATION (app));
}
static GActionEntry app_entries[] =
{
{ "preferences", preferences_activated, NULL, NULL, NULL },
{ "quit", quit_activated, NULL, NULL, NULL }
};
static void
example_app_startup (GApplication *app)
{
GtkBuilder *builder;
GMenuModel *app_menu;
const gchar *quit_accels[2] = { "<Ctrl>Q", NULL };
G_APPLICATION_CLASS (example_app_parent_class)->startup (app);
g_action_map_add_action_entries (G_ACTION_MAP (app),
app_entries, G_N_ELEMENTS (app_entries),
app);
gtk_application_set_accels_for_action (GTK_APPLICATION (app),
"app.quit",
quit_accels);
builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/app-menu.ui");
app_menu = G_MENU_MODEL (gtk_builder_get_object (builder, "appmenu"));
gtk_application_set_app_menu (GTK_APPLICATION (app), app_menu);
g_object_unref (builder);
}
static void
example_app_activate (GApplication *app)
{
ExampleAppWindow *win;
win = example_app_window_new (EXAMPLE_APP (app));
gtk_window_present (GTK_WINDOW (win));
}
static void
example_app_open (GApplication *app,
GFile **files,
gint n_files,
const gchar *hint)
{
GList *windows;
ExampleAppWindow *win;
int i;
windows = gtk_application_get_windows (GTK_APPLICATION (app));
if (windows)
win = EXAMPLE_APP_WINDOW (windows->data);
else
win = example_app_window_new (EXAMPLE_APP (app));
for (i = 0; i < n_files; i++)
example_app_window_open (win, files[i]);
gtk_window_present (GTK_WINDOW (win));
}
static void
example_app_class_init (ExampleAppClass *class)
{
G_APPLICATION_CLASS (class)->startup = example_app_startup;
G_APPLICATION_CLASS (class)->activate = example_app_activate;
G_APPLICATION_CLASS (class)->open = example_app_open;
}
ExampleApp *
example_app_new (void)
{
return g_object_new (EXAMPLE_APP_TYPE,
"application-id", "org.gtk.exampleapp",
"flags", G_APPLICATION_HANDLES_OPEN,
NULL);
}

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gtk/exampleapp">
<file preprocess="xml-stripblanks">window.ui</file>
<file preprocess="xml-stripblanks">app-menu.ui</file>
<file preprocess="xml-stripblanks">gears-menu.ui</file>
<file preprocess="xml-stripblanks">prefs.ui</file>
</gresource>
</gresources>

View File

@ -1,14 +0,0 @@
#ifndef __EXAMPLEAPP_H
#define __EXAMPLEAPP_H
#include <gtk/gtk.h>
#define EXAMPLE_APP_TYPE (example_app_get_type ())
G_DECLARE_FINAL_TYPE (ExampleApp, example_app, EXAMPLE, APP, GtkApplication)
ExampleApp *example_app_new (void);
#endif /* __EXAMPLEAPP_H */

View File

@ -1,59 +0,0 @@
#include <gtk/gtk.h>
#include "exampleapp.h"
#include "exampleappwin.h"
#include "exampleappprefs.h"
struct _ExampleAppPrefs
{
GtkDialog parent;
GSettings *settings;
GtkWidget *font;
GtkWidget *transition;
};
G_DEFINE_TYPE (ExampleAppPrefs, example_app_prefs, GTK_TYPE_DIALOG)
static void
example_app_prefs_init (ExampleAppPrefs *prefs)
{
gtk_widget_init_template (GTK_WIDGET (prefs));
prefs->settings = g_settings_new ("org.gtk.exampleapp");
g_settings_bind (prefs->settings, "font",
prefs->font, "font",
G_SETTINGS_BIND_DEFAULT);
g_settings_bind (prefs->settings, "transition",
prefs->transition, "active-id",
G_SETTINGS_BIND_DEFAULT);
}
static void
example_app_prefs_dispose (GObject *object)
{
ExampleAppPrefs *prefs;
prefs = EXAMPLE_APP_PREFS (object);
g_clear_object (&prefs->settings);
G_OBJECT_CLASS (example_app_prefs_parent_class)->dispose (object);
}
static void
example_app_prefs_class_init (ExampleAppPrefsClass *class)
{
G_OBJECT_CLASS (class)->dispose = example_app_prefs_dispose;
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/exampleapp/prefs.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppPrefs, font);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppPrefs, transition);
}
ExampleAppPrefs *
example_app_prefs_new (ExampleAppWindow *win)
{
return g_object_new (EXAMPLE_APP_PREFS_TYPE, "transient-for", win, "use-header-bar", TRUE, NULL);
}

View File

@ -1,15 +0,0 @@
#ifndef __EXAMPLEAPPPREFS_H
#define __EXAMPLEAPPPREFS_H
#include <gtk/gtk.h>
#include "exampleappwin.h"
#define EXAMPLE_APP_PREFS_TYPE (example_app_prefs_get_type ())
G_DECLARE_FINAL_TYPE (ExampleAppPrefs, example_app_prefs, EXAMPLE, APP_PREFS, GtkDialog)
ExampleAppPrefs *example_app_prefs_new (ExampleAppWindow *win);
#endif /* __EXAMPLEAPPPREFS_H */

View File

@ -1,295 +0,0 @@
#include <gtk/gtk.h>
#include "exampleapp.h"
#include "exampleappwin.h"
struct _ExampleAppWindow
{
GtkApplicationWindow parent;
GSettings *settings;
GtkWidget *stack;
GtkWidget *search;
GtkWidget *searchbar;
GtkWidget *searchentry;
GtkWidget *gears;
GtkWidget *sidebar;
GtkWidget *words;
GtkWidget *lines;
GtkWidget *lines_label;
};
G_DEFINE_TYPE (ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW)
static void
search_text_changed (GtkEntry *entry,
ExampleAppWindow *win)
{
const gchar *text;
GtkWidget *tab;
GtkWidget *view;
GtkTextBuffer *buffer;
GtkTextIter start, match_start, match_end;
text = gtk_editable_get_text (GTK_EDITABLE (entry));
if (text[0] == '\0')
return;
tab = gtk_stack_get_visible_child (GTK_STACK (win->stack));
view = gtk_scrolled_window_get_child (GTK_SCROLLED_WINDOW (tab));
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
/* Very simple-minded search implementation */
gtk_text_buffer_get_start_iter (buffer, &start);
if (gtk_text_iter_forward_search (&start, text, GTK_TEXT_SEARCH_CASE_INSENSITIVE,
&match_start, &match_end, NULL))
{
gtk_text_buffer_select_range (buffer, &match_start, &match_end);
gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (view), &match_start,
0.0, FALSE, 0.0, 0.0);
}
}
static void
find_word (GtkButton *button,
ExampleAppWindow *win)
{
const gchar *word;
word = gtk_button_get_label (button);
gtk_editable_set_text (GTK_EDITABLE (win->searchentry), word);
}
static void
update_words (ExampleAppWindow *win)
{
GHashTable *strings;
GHashTableIter iter;
GtkWidget *tab, *view, *row;
GtkTextBuffer *buffer;
GtkTextIter start, end;
GList *children, *l;
gchar *word, *key;
tab = gtk_stack_get_visible_child (GTK_STACK (win->stack));
if (tab == NULL)
return;
view = gtk_scrolled_window_get_child (GTK_SCROLLED_WINDOW (tab));
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
strings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
gtk_text_buffer_get_start_iter (buffer, &start);
while (!gtk_text_iter_is_end (&start))
{
while (!gtk_text_iter_starts_word (&start))
{
if (!gtk_text_iter_forward_char (&start))
goto done;
}
end = start;
if (!gtk_text_iter_forward_word_end (&end))
goto done;
word = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
g_hash_table_add (strings, g_utf8_strdown (word, -1));
g_free (word);
start = end;
}
done:
children = gtk_container_get_children (GTK_CONTAINER (win->words));
for (l = children; l; l = l->next)
gtk_container_remove (GTK_CONTAINER (win->words), GTK_WIDGET (l->data));
g_list_free (children);
g_hash_table_iter_init (&iter, strings);
while (g_hash_table_iter_next (&iter, (gpointer *)&key, NULL))
{
row = gtk_button_new_with_label (key);
g_signal_connect (row, "clicked",
G_CALLBACK (find_word), win);
gtk_container_add (GTK_CONTAINER (win->words), row);
}
g_hash_table_unref (strings);
}
static void
update_lines (ExampleAppWindow *win)
{
GtkWidget *tab, *view;
GtkTextBuffer *buffer;
int count;
gchar *lines;
tab = gtk_stack_get_visible_child (GTK_STACK (win->stack));
if (tab == NULL)
return;
view = gtk_scrolled_window_get_child (GTK_SCROLLED_WINDOW (tab));
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
count = gtk_text_buffer_get_line_count (buffer);
lines = g_strdup_printf ("%d", count);
gtk_label_set_text (GTK_LABEL (win->lines), lines);
g_free (lines);
}
static void
visible_child_changed (GObject *stack,
GParamSpec *pspec,
ExampleAppWindow *win)
{
if (gtk_widget_in_destruction (GTK_WIDGET (stack)))
return;
gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (win->searchbar), FALSE);
update_words (win);
update_lines (win);
}
static void
words_changed (GObject *sidebar,
GParamSpec *pspec,
ExampleAppWindow *win)
{
update_words (win);
}
static void
example_app_window_init (ExampleAppWindow *win)
{
GtkBuilder *builder;
GMenuModel *menu;
GAction *action;
gtk_widget_init_template (GTK_WIDGET (win));
win->settings = g_settings_new ("org.gtk.exampleapp");
g_settings_bind (win->settings, "transition",
win->stack, "transition-type",
G_SETTINGS_BIND_DEFAULT);
g_settings_bind (win->settings, "show-words",
win->sidebar, "reveal-child",
G_SETTINGS_BIND_DEFAULT);
g_object_bind_property (win->search, "active",
win->searchbar, "search-mode-enabled",
G_BINDING_BIDIRECTIONAL);
g_signal_connect (win->sidebar, "notify::reveal-child",
G_CALLBACK (words_changed), win);
builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/gears-menu.ui");
menu = G_MENU_MODEL (gtk_builder_get_object (builder, "menu"));
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (win->gears), menu);
g_object_unref (builder);
action = g_settings_create_action (win->settings, "show-words");
g_action_map_add_action (G_ACTION_MAP (win), action);
g_object_unref (action);
action = (GAction*) g_property_action_new ("show-lines", win->lines, "visible");
g_action_map_add_action (G_ACTION_MAP (win), action);
g_object_unref (action);
g_object_bind_property (win->lines, "visible",
win->lines_label, "visible",
G_BINDING_DEFAULT);
g_object_set (gtk_settings_get_default (), "gtk-shell-shows-app-menu", FALSE, NULL);
gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (win), TRUE);
}
static void
example_app_window_dispose (GObject *object)
{
ExampleAppWindow *win;
win = EXAMPLE_APP_WINDOW (object);
g_clear_object (&win->settings);
G_OBJECT_CLASS (example_app_window_parent_class)->dispose (object);
}
static void
example_app_window_class_init (ExampleAppWindowClass *class)
{
G_OBJECT_CLASS (class)->dispose = example_app_window_dispose;
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/exampleapp/window.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, search);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, searchbar);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, searchentry);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, gears);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, words);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, sidebar);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, lines);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, lines_label);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), search_text_changed);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), visible_child_changed);
}
ExampleAppWindow *
example_app_window_new (ExampleApp *app)
{
return g_object_new (EXAMPLE_APP_WINDOW_TYPE, "application", app, NULL);
}
void
example_app_window_open (ExampleAppWindow *win,
GFile *file)
{
gchar *basename;
GtkWidget *scrolled, *view;
gchar *contents;
gsize length;
GtkTextBuffer *buffer;
GtkTextTag *tag;
GtkTextIter start_iter, end_iter;
basename = g_file_get_basename (file);
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE);
view = gtk_text_view_new ();
gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolled), view);
gtk_stack_add_titled (GTK_STACK (win->stack), scrolled, basename, basename);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL))
{
gtk_text_buffer_set_text (buffer, contents, length);
g_free (contents);
}
tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
g_settings_bind (win->settings, "font",
tag, "font",
G_SETTINGS_BIND_DEFAULT);
gtk_text_buffer_get_start_iter (buffer, &start_iter);
gtk_text_buffer_get_end_iter (buffer, &end_iter);
gtk_text_buffer_apply_tag (buffer, tag, &start_iter, &end_iter);
g_free (basename);
gtk_widget_set_sensitive (win->search, TRUE);
update_words (win);
update_lines (win);
}

View File

@ -1,16 +0,0 @@
#ifndef __EXAMPLEAPPWIN_H
#define __EXAMPLEAPPWIN_H
#include <gtk/gtk.h>
#include "exampleapp.h"
#define EXAMPLE_APP_WINDOW_TYPE (example_app_window_get_type ())
G_DECLARE_FINAL_TYPE (ExampleAppWindow, example_app_window, EXAMPLE, APP_WINDOW, GtkApplicationWindow)
ExampleAppWindow *example_app_window_new (ExampleApp *app);
void example_app_window_open (ExampleAppWindow *win,
GFile *file);
#endif /* __EXAMPLEAPPWIN_H */

View File

@ -1,14 +0,0 @@
<interface>
<menu id="menu">
<section>
<item>
<attribute name="label" translatable="yes">_Words</attribute>
<attribute name="action">win.show-words</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Lines</attribute>
<attribute name="action">win.show-lines</attribute>
</item>
</section>
</menu>
</interface>

View File

@ -1,16 +0,0 @@
#include <gtk/gtk.h>
#include "exampleapp.h"
int
main (int argc, char *argv[])
{
/* Since this example is running uninstalled,
* we have to help it find its schema. This
* is *not* necessary in properly installed
* application.
*/
g_setenv ("GSETTINGS_SCHEMA_DIR", ".", FALSE);
return g_application_run (G_APPLICATION (example_app_new ()), argc, argv);
}

View File

@ -1,14 +0,0 @@
app10_resources = gnome.compile_resources('exampleapp10 resources',
'exampleapp.gresource.xml',
source_dir: '.')
app10_schemas = gnome.compile_schemas()
executable('exampleapp10',
'main.c',
'exampleapp.c',
'exampleappwin.c',
'exampleappprefs.c',
app10_resources,
app10_schemas,
dependencies: libgtk_dep)

View File

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<schemalist>
<schema path="/org/gtk/exampleapp/" id="org.gtk.exampleapp">
<key name="font" type="s">
<default>'Monospace 12'</default>
<summary>Font</summary>
<description>The font to be used for content.</description>
</key>
<key name="transition" type="s">
<choices>
<choice value='none'/>
<choice value='crossfade'/>
<choice value='slide-left-right'/>
</choices>
<default>'none'</default>
<summary>Transition</summary>
<description>The transition to use when switching tabs.</description>
</key>
<key name="show-words" type="b">
<default>false</default>
<summary>Show words</summary>
<description>Whether to show a word list in the sidebar</description>
</key>
</schema>
</schemalist>

View File

@ -1,67 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="ExampleAppPrefs" parent="GtkDialog">
<property name="title" translatable="yes">Preferences</property>
<property name="resizable">0</property>
<property name="modal">1</property>
<child internal-child="vbox">
<object class="GtkBox" id="vbox">
<child>
<object class="GtkGrid" id="grid">
<property name="margin-start">6</property>
<property name="margin-end">6</property>
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<property name="row-spacing">12</property>
<property name="column-spacing">6</property>
<child>
<object class="GtkLabel" id="fontlabel">
<property name="label">_Font:</property>
<property name="use-underline">1</property>
<property name="mnemonic-widget">font</property>
<property name="xalign">1</property>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkFontButton" id="font">
<layout>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel" id="transitionlabel">
<property name="label">_Transition:</property>
<property name="use-underline">1</property>
<property name="mnemonic-widget">transition</property>
<property name="xalign">1</property>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkComboBoxText" id="transition">
<items>
<item translatable="yes" id="none">None</item>
<item translatable="yes" id="crossfade">Fade</item>
<item translatable="yes" id="slide-left-right">Slide</item>
</items>
<layout>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@ -1,81 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="ExampleAppWindow" parent="GtkApplicationWindow">
<property name="title" translatable="yes">Example Application</property>
<property name="default-width">600</property>
<property name="default-height">400</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header">
<property name="show-title-buttons">1</property>
<child>
<object class="GtkLabel" id="lines_label">
<property name="visible">0</property>
<property name="label" translatable="yes">Lines:</property>
</object>
</child>
<child>
<object class="GtkLabel" id="lines">
<property name="visible">0</property>
</object>
</child>
<child type="title">
<object class="GtkStackSwitcher" id="tabs">
<property name="stack">stack</property>
</object>
</child>
<child type="end">
<object class="GtkToggleButton" id="search">
<property name="sensitive">0</property>
<property name="icon-name">edit-find-symbolic</property>
</object>
</child>
<child type="end">
<object class="GtkMenuButton" id="gears">
<property name="direction">none</property>
<style>
<class name="image-button"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="content_box">
<property name="orientation">vertical</property>
<child>
<object class="GtkSearchBar" id="searchbar">
<child>
<object class="GtkSearchEntry" id="searchentry">
<signal name="search-changed" handler="search_text_changed"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="hbox">
<child>
<object class="GtkRevealer" id="sidebar">
<property name="transition-type">slide-right</property>
<child>
<object class="GtkScrolledWindow" id="sidebar-sw">
<property name="hscrollbar-policy">never</property>
<child>
<object class="GtkListBox" id="words">
<property name="selection-mode">none</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkStack" id="stack">
<signal name="notify::visible-child" handler="visible_child_changed"/>
</object>
</child>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@ -0,0 +1 @@
Step 2: Populating the window

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="ExampleAppWindow" parent="GtkApplicationWindow">
<property name="title" translatable="yes">Example Application</property>
@ -6,15 +7,6 @@
<child>
<object class="GtkBox" id="content_box">
<property name="orientation">vertical</property>
<child>
<object class="GtkHeaderBar" id="header">
<child type="title">
<object class="GtkStackSwitcher" id="tabs">
<property name="stack">stack</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkStack" id="stack"/>
</child>

View File

@ -0,0 +1 @@
Step 3: Opening files, add a stack switcher

View File

@ -1,20 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="ExampleAppWindow" parent="GtkApplicationWindow">
<property name="title" translatable="yes">Example Application</property>
<property name="default-width">600</property>
<property name="default-height">400</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header">
<property name="show-title-buttons">1</property>
<child type="title">
<object class="GtkStackSwitcher" id="tabs">
<property name="stack">stack</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="content_box">
<property name="orientation">vertical</property>
<child>
<object class="GtkHeaderBar" id="header">
<child type="title">
<object class="GtkStackSwitcher" id="tabs">
<property name="stack">stack</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkStack" id="stack"/>
</child>

View File

@ -0,0 +1 @@
Step 4: Add a menu

View File

@ -39,8 +39,6 @@ static GActionEntry app_entries[] =
static void
example_app_startup (GApplication *app)
{
GtkBuilder *builder;
GMenuModel *app_menu;
const gchar *quit_accels[2] = { "<Ctrl>Q", NULL };
G_APPLICATION_CLASS (example_app_parent_class)->startup (app);
@ -51,11 +49,6 @@ example_app_startup (GApplication *app)
gtk_application_set_accels_for_action (GTK_APPLICATION (app),
"app.quit",
quit_accels);
builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/app-menu.ui");
app_menu = G_MENU_MODEL (gtk_builder_get_object (builder, "appmenu"));
gtk_application_set_app_menu (GTK_APPLICATION (app), app_menu);
g_object_unref (builder);
}
static void

View File

@ -2,6 +2,6 @@
<gresources>
<gresource prefix="/org/gtk/exampleapp">
<file preprocess="xml-stripblanks">window.ui</file>
<file preprocess="xml-stripblanks">app-menu.ui</file>
<file preprocess="xml-stripblanks">gears-menu.ui</file>
</gresource>
</gresources>

View File

@ -8,6 +8,7 @@ struct _ExampleAppWindow
GtkApplicationWindow parent;
GtkWidget *stack;
GtkWidget *gears;
};
G_DEFINE_TYPE (ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW)
@ -15,7 +16,15 @@ G_DEFINE_TYPE (ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW
static void
example_app_window_init (ExampleAppWindow *win)
{
GtkBuilder *builder;
GMenuModel *menu;
gtk_widget_init_template (GTK_WIDGET (win));
builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/gears-menu.ui");
menu = G_MENU_MODEL (gtk_builder_get_object (builder, "menu"));
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (win->gears), menu);
g_object_unref (builder);
}
static void
@ -24,6 +33,7 @@ example_app_window_class_init (ExampleAppWindowClass *class)
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/exampleapp/window.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, gears);
}
ExampleAppWindow *

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="appmenu">
<menu id="menu">
<section>
<item>
<attribute name="label" translatable="yes">_Preferences</attribute>

View File

@ -1,20 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="ExampleAppWindow" parent="GtkApplicationWindow">
<property name="title" translatable="yes">Example Application</property>
<property name="default-width">600</property>
<property name="default-height">400</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header">
<property name="show-title-buttons">1</property>
<child type="title">
<object class="GtkStackSwitcher" id="tabs">
<property name="stack">stack</property>
</object>
</child>
<child type="end">
<object class="GtkMenuButton" id="gears">
<property name="direction">none</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="content_box">
<property name="orientation">vertical</property>
<child>
<object class="GtkHeaderBar" id="header">
<child type="title">
<object class="GtkStackSwitcher" id="tabs">
<property name="stack">stack</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkStack" id="stack"/>
</child>

View File

@ -39,8 +39,6 @@ static GActionEntry app_entries[] =
static void
example_app_startup (GApplication *app)
{
GtkBuilder *builder;
GMenuModel *app_menu;
const gchar *quit_accels[2] = { "<Ctrl>Q", NULL };
G_APPLICATION_CLASS (example_app_parent_class)->startup (app);
@ -51,11 +49,6 @@ example_app_startup (GApplication *app)
gtk_application_set_accels_for_action (GTK_APPLICATION (app),
"app.quit",
quit_accels);
builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/app-menu.ui");
app_menu = G_MENU_MODEL (gtk_builder_get_object (builder, "appmenu"));
gtk_application_set_app_menu (GTK_APPLICATION (app), app_menu);
g_object_unref (builder);
}
static void

View File

@ -2,6 +2,6 @@
<gresources>
<gresource prefix="/org/gtk/exampleapp">
<file preprocess="xml-stripblanks">window.ui</file>
<file preprocess="xml-stripblanks">app-menu.ui</file>
<file preprocess="xml-stripblanks">gears-menu.ui</file>
</gresource>
</gresources>

View File

@ -9,6 +9,7 @@ struct _ExampleAppWindow
GSettings *settings;
GtkWidget *stack;
GtkWidget *gears;
};
G_DEFINE_TYPE (ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW)
@ -16,9 +17,17 @@ G_DEFINE_TYPE (ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW
static void
example_app_window_init (ExampleAppWindow *win)
{
gtk_widget_init_template (GTK_WIDGET (win));
win->settings = g_settings_new ("org.gtk.exampleapp");
GtkBuilder *builder;
GMenuModel *menu;
gtk_widget_init_template (GTK_WIDGET (win));
builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/gears-menu.ui");
menu = G_MENU_MODEL (gtk_builder_get_object (builder, "menu"));
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (win->gears), menu);
g_object_unref (builder);
win->settings = g_settings_new ("org.gtk.exampleapp");
g_settings_bind (win->settings, "transition",
win->stack, "transition-type",
G_SETTINGS_BIND_DEFAULT);
@ -44,6 +53,7 @@ example_app_window_class_init (ExampleAppWindowClass *class)
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/exampleapp/window.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, gears);
}
ExampleAppWindow *

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="appmenu">
<menu id="menu">
<section>
<item>
<attribute name="label" translatable="yes">_Preferences</attribute>

View File

@ -1,20 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="ExampleAppWindow" parent="GtkApplicationWindow">
<property name="title" translatable="yes">Example Application</property>
<property name="default-width">600</property>
<property name="default-height">400</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header">
<property name="show-title-buttons">1</property>
<child type="title">
<object class="GtkStackSwitcher" id="tabs">
<property name="stack">stack</property>
</object>
</child>
<child type="end">
<object class="GtkMenuButton" id="gears">
<property name="direction">none</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="content_box">
<property name="orientation">vertical</property>
<child>
<object class="GtkHeaderBar" id="header">
<child type="title">
<object class="GtkStackSwitcher" id="tabs">
<property name="stack">stack</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkStack" id="stack"/>
</child>

View File

@ -46,8 +46,6 @@ static GActionEntry app_entries[] =
static void
example_app_startup (GApplication *app)
{
GtkBuilder *builder;
GMenuModel *app_menu;
const gchar *quit_accels[2] = { "<Ctrl>Q", NULL };
G_APPLICATION_CLASS (example_app_parent_class)->startup (app);
@ -58,11 +56,6 @@ example_app_startup (GApplication *app)
gtk_application_set_accels_for_action (GTK_APPLICATION (app),
"app.quit",
quit_accels);
builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/app-menu.ui");
app_menu = G_MENU_MODEL (gtk_builder_get_object (builder, "appmenu"));
gtk_application_set_app_menu (GTK_APPLICATION (app), app_menu);
g_object_unref (builder);
}
static void

View File

@ -2,7 +2,7 @@
<gresources>
<gresource prefix="/org/gtk/exampleapp">
<file preprocess="xml-stripblanks">window.ui</file>
<file preprocess="xml-stripblanks">app-menu.ui</file>
<file preprocess="xml-stripblanks">gears-menu.ui</file>
<file preprocess="xml-stripblanks">prefs.ui</file>
</gresource>
</gresources>

View File

@ -9,6 +9,7 @@ struct _ExampleAppWindow
GSettings *settings;
GtkWidget *stack;
GtkWidget *gears;
};
G_DEFINE_TYPE (ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW)
@ -16,7 +17,16 @@ G_DEFINE_TYPE (ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW
static void
example_app_window_init (ExampleAppWindow *win)
{
GtkBuilder *builder;
GMenuModel *menu;
gtk_widget_init_template (GTK_WIDGET (win));
builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/gears-menu.ui");
menu = G_MENU_MODEL (gtk_builder_get_object (builder, "menu"));
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (win->gears), menu);
g_object_unref (builder);
win->settings = g_settings_new ("org.gtk.exampleapp");
g_settings_bind (win->settings, "transition",
@ -44,6 +54,7 @@ example_app_window_class_init (ExampleAppWindowClass *class)
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/exampleapp/window.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, gears);
}
ExampleAppWindow *

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="appmenu">
<menu id="menu">
<section>
<item>
<attribute name="label" translatable="yes">_Preferences</attribute>

View File

@ -4,16 +4,16 @@
<property name="title" translatable="yes">Preferences</property>
<property name="resizable">0</property>
<property name="modal">1</property>
<child internal-child="vbox">
<object class="GtkBox" id="vbox">
<child internal-child="content_area">
<object class="GtkBox" id="content_area">
<child>
<object class="GtkGrid" id="grid">
<property name="margin-start">6</property>
<property name="margin-end">6</property>
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="row-spacing">12</property>
<property name="column-spacing">6</property>
<property name="column-spacing">12</property>
<child>
<object class="GtkLabel" id="fontlabel">
<property name="label">_Font:</property>

View File

@ -1,20 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="ExampleAppWindow" parent="GtkApplicationWindow">
<property name="title" translatable="yes">Example Application</property>
<property name="default-width">600</property>
<property name="default-height">400</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header">
<property name="show-title-buttons">1</property>
<child type="title">
<object class="GtkStackSwitcher" id="tabs">
<property name="stack">stack</property>
</object>
</child>
<child type="end">
<object class="GtkMenuButton" id="gears">
<property name="direction">none</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="content_box">
<property name="orientation">vertical</property>
<child>
<object class="GtkHeaderBar" id="header">
<child type="title">
<object class="GtkStackSwitcher" id="tabs">
<property name="stack">stack</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkStack" id="stack"/>
</child>

View File

@ -0,0 +1 @@
Step 7: A search bar

View File

@ -1,16 +0,0 @@
<interface>
<menu id="appmenu">
<section>
<item>
<attribute name="label" translatable="yes">_Preferences</attribute>
<attribute name="action">app.preferences</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Quit</attribute>
<attribute name="action">app.quit</attribute>
</item>
</section>
</menu>
</interface>

View File

@ -46,8 +46,6 @@ static GActionEntry app_entries[] =
static void
example_app_startup (GApplication *app)
{
GtkBuilder *builder;
GMenuModel *app_menu;
const gchar *quit_accels[2] = { "<Ctrl>Q", NULL };
G_APPLICATION_CLASS (example_app_parent_class)->startup (app);
@ -58,11 +56,6 @@ example_app_startup (GApplication *app)
gtk_application_set_accels_for_action (GTK_APPLICATION (app),
"app.quit",
quit_accels);
builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/app-menu.ui");
app_menu = G_MENU_MODEL (gtk_builder_get_object (builder, "appmenu"));
gtk_application_set_app_menu (GTK_APPLICATION (app), app_menu);
g_object_unref (builder);
}
static void

View File

@ -2,7 +2,7 @@
<gresources>
<gresource prefix="/org/gtk/exampleapp">
<file preprocess="xml-stripblanks">window.ui</file>
<file preprocess="xml-stripblanks">app-menu.ui</file>
<file preprocess="xml-stripblanks">gears-menu.ui</file>
<file preprocess="xml-stripblanks">prefs.ui</file>
</gresource>
</gresources>

View File

@ -9,6 +9,7 @@ struct _ExampleAppWindow
GSettings *settings;
GtkWidget *stack;
GtkWidget *gears;
GtkWidget *search;
GtkWidget *searchbar;
};
@ -59,7 +60,16 @@ visible_child_changed (GObject *stack,
static void
example_app_window_init (ExampleAppWindow *win)
{
GtkBuilder *builder;
GMenuModel *menu;
gtk_widget_init_template (GTK_WIDGET (win));
builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/gears-menu.ui");
menu = G_MENU_MODEL (gtk_builder_get_object (builder, "menu"));
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (win->gears), menu);
g_object_unref (builder);
win->settings = g_settings_new ("org.gtk.exampleapp");
g_settings_bind (win->settings, "transition",
@ -92,6 +102,7 @@ example_app_window_class_init (ExampleAppWindowClass *class)
"/org/gtk/exampleapp/window.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, gears);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, search);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, searchbar);

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="appmenu">
<menu id="menu">
<section>
<item>
<attribute name="label" translatable="yes">_Preferences</attribute>

View File

@ -4,16 +4,16 @@
<property name="title" translatable="yes">Preferences</property>
<property name="resizable">0</property>
<property name="modal">1</property>
<child internal-child="vbox">
<object class="GtkBox" id="vbox">
<child internal-child="content_area">
<object class="GtkBox" id="content_area">
<child>
<object class="GtkGrid" id="grid">
<property name="margin-start">6</property>
<property name="margin-end">6</property>
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="row-spacing">12</property>
<property name="column-spacing">6</property>
<property name="column-spacing">12</property>
<child>
<object class="GtkLabel" id="fontlabel">
<property name="label">_Font:</property>

View File

@ -4,24 +4,30 @@
<property name="title" translatable="yes">Example Application</property>
<property name="default-width">600</property>
<property name="default-height">400</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header">
<property name="show-title-buttons">1</property>
<child type="title">
<object class="GtkStackSwitcher" id="tabs">
<property name="stack">stack</property>
</object>
</child>
<child type="end">
<object class="GtkMenuButton" id="gears">
<property name="direction">none</property>
</object>
</child>
<child type="end">
<object class="GtkToggleButton" id="search">
<property name="sensitive">0</property>
<property name="icon-name">edit-find-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="content_box">
<property name="orientation">vertical</property>
<child>
<object class="GtkHeaderBar" id="header">
<child type="title">
<object class="GtkStackSwitcher" id="tabs">
<property name="stack">stack</property>
</object>
</child>
<child type="end">
<object class="GtkToggleButton" id="search">
<property name="sensitive">0</property>
<property name="icon-name">edit-find-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSearchBar" id="searchbar">
<child>

View File

@ -0,0 +1 @@
Step 8: Adding a sidebar

View File

@ -1,16 +0,0 @@
<interface>
<menu id="appmenu">
<section>
<item>
<attribute name="label" translatable="yes">_Preferences</attribute>
<attribute name="action">app.preferences</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Quit</attribute>
<attribute name="action">app.quit</attribute>
</item>
</section>
</menu>
</interface>

View File

@ -46,8 +46,6 @@ static GActionEntry app_entries[] =
static void
example_app_startup (GApplication *app)
{
GtkBuilder *builder;
GMenuModel *app_menu;
const gchar *quit_accels[2] = { "<Ctrl>Q", NULL };
G_APPLICATION_CLASS (example_app_parent_class)->startup (app);
@ -58,11 +56,6 @@ example_app_startup (GApplication *app)
gtk_application_set_accels_for_action (GTK_APPLICATION (app),
"app.quit",
quit_accels);
builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/app-menu.ui");
app_menu = G_MENU_MODEL (gtk_builder_get_object (builder, "appmenu"));
gtk_application_set_app_menu (GTK_APPLICATION (app), app_menu);
g_object_unref (builder);
}
static void

View File

@ -2,7 +2,6 @@
<gresources>
<gresource prefix="/org/gtk/exampleapp">
<file preprocess="xml-stripblanks">window.ui</file>
<file preprocess="xml-stripblanks">app-menu.ui</file>
<file preprocess="xml-stripblanks">gears-menu.ui</file>
<file preprocess="xml-stripblanks">prefs.ui</file>
</gresource>

View File

@ -9,10 +9,10 @@ struct _ExampleAppWindow
GSettings *settings;
GtkWidget *stack;
GtkWidget *gears;
GtkWidget *search;
GtkWidget *searchbar;
GtkWidget *searchentry;
GtkWidget *gears;
GtkWidget *sidebar;
GtkWidget *words;
};
@ -143,6 +143,12 @@ example_app_window_init (ExampleAppWindow *win)
GAction *action;
gtk_widget_init_template (GTK_WIDGET (win));
builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/gears-menu.ui");
menu = G_MENU_MODEL (gtk_builder_get_object (builder, "menu"));
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (win->gears), menu);
g_object_unref (builder);
win->settings = g_settings_new ("org.gtk.exampleapp");
g_settings_bind (win->settings, "transition",
@ -160,11 +166,6 @@ example_app_window_init (ExampleAppWindow *win)
g_signal_connect (win->sidebar, "notify::reveal-child",
G_CALLBACK (words_changed), win);
builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/gears-menu.ui");
menu = G_MENU_MODEL (gtk_builder_get_object (builder, "menu"));
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (win->gears), menu);
g_object_unref (builder);
action = g_settings_create_action (win->settings, "show-words");
g_action_map_add_action (G_ACTION_MAP (win), action);
g_object_unref (action);
@ -191,10 +192,10 @@ example_app_window_class_init (ExampleAppWindowClass *class)
"/org/gtk/exampleapp/window.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, gears);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, search);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, searchbar);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, searchentry);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, gears);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, words);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, sidebar);

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="menu">
<section>
@ -5,6 +6,16 @@
<attribute name="label" translatable="yes">_Words</attribute>
<attribute name="action">win.show-words</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Preferences</attribute>
<attribute name="action">app.preferences</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Quit</attribute>
<attribute name="action">app.quit</attribute>
</item>
</section>
</menu>
</interface>

View File

@ -4,16 +4,16 @@
<property name="title" translatable="yes">Preferences</property>
<property name="resizable">0</property>
<property name="modal">1</property>
<child internal-child="vbox">
<object class="GtkBox" id="vbox">
<child internal-child="content_area">
<object class="GtkBox" id="content_area">
<child>
<object class="GtkGrid" id="grid">
<property name="margin-start">6</property>
<property name="margin-end">6</property>
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="row-spacing">12</property>
<property name="column-spacing">6</property>
<property name="column-spacing">12</property>
<child>
<object class="GtkLabel" id="fontlabel">
<property name="label">_Font:</property>

View File

@ -4,32 +4,30 @@
<property name="title" translatable="yes">Example Application</property>
<property name="default-width">600</property>
<property name="default-height">400</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header">
<property name="show-title-buttons">1</property>
<child type="title">
<object class="GtkStackSwitcher" id="tabs">
<property name="stack">stack</property>
</object>
</child>
<child type="end">
<object class="GtkToggleButton" id="search">
<property name="sensitive">0</property>
<property name="icon-name">edit-find-symbolic</property>
</object>
</child>
<child type="end">
<object class="GtkMenuButton" id="gears">
<property name="direction">none</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="content_box">
<property name="orientation">vertical</property>
<child>
<object class="GtkHeaderBar" id="header">
<child type="title">
<object class="GtkStackSwitcher" id="tabs">
<property name="stack">stack</property>
</object>
</child>
<child type="end">
<object class="GtkToggleButton" id="search">
<property name="sensitive">0</property>
<property name="icon-name">edit-find-symbolic</property>
</object>
</child>
<child type="end">
<object class="GtkMenuButton" id="gears">
<property name="direction">none</property>
<style>
<class name="image-button"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSearchBar" id="searchbar">
<child>

View File

@ -0,0 +1 @@
Step 9: Using properties

View File

@ -1,16 +0,0 @@
<interface>
<menu id="appmenu">
<section>
<item>
<attribute name="label" translatable="yes">_Preferences</attribute>
<attribute name="action">app.preferences</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Quit</attribute>
<attribute name="action">app.quit</attribute>
</item>
</section>
</menu>
</interface>

View File

@ -46,8 +46,6 @@ static GActionEntry app_entries[] =
static void
example_app_startup (GApplication *app)
{
GtkBuilder *builder;
GMenuModel *app_menu;
const gchar *quit_accels[2] = { "<Ctrl>Q", NULL };
G_APPLICATION_CLASS (example_app_parent_class)->startup (app);
@ -58,11 +56,6 @@ example_app_startup (GApplication *app)
gtk_application_set_accels_for_action (GTK_APPLICATION (app),
"app.quit",
quit_accels);
builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/app-menu.ui");
app_menu = G_MENU_MODEL (gtk_builder_get_object (builder, "appmenu"));
gtk_application_set_app_menu (GTK_APPLICATION (app), app_menu);
g_object_unref (builder);
}
static void

View File

@ -2,7 +2,6 @@
<gresources>
<gresource prefix="/org/gtk/exampleapp">
<file preprocess="xml-stripblanks">window.ui</file>
<file preprocess="xml-stripblanks">app-menu.ui</file>
<file preprocess="xml-stripblanks">gears-menu.ui</file>
<file preprocess="xml-stripblanks">prefs.ui</file>
</gresource>

View File

@ -9,10 +9,10 @@ struct _ExampleAppWindow
GSettings *settings;
GtkWidget *stack;
GtkWidget *gears;
GtkWidget *search;
GtkWidget *searchbar;
GtkWidget *searchentry;
GtkWidget *gears;
GtkWidget *sidebar;
GtkWidget *words;
GtkWidget *lines;
@ -168,6 +168,12 @@ example_app_window_init (ExampleAppWindow *win)
GAction *action;
gtk_widget_init_template (GTK_WIDGET (win));
builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/gears-menu.ui");
menu = G_MENU_MODEL (gtk_builder_get_object (builder, "menu"));
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (win->gears), menu);
g_object_unref (builder);
win->settings = g_settings_new ("org.gtk.exampleapp");
g_settings_bind (win->settings, "transition",
@ -185,11 +191,6 @@ example_app_window_init (ExampleAppWindow *win)
g_signal_connect (win->sidebar, "notify::reveal-child",
G_CALLBACK (words_changed), win);
builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/gears-menu.ui");
menu = G_MENU_MODEL (gtk_builder_get_object (builder, "menu"));
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (win->gears), menu);
g_object_unref (builder);
action = g_settings_create_action (win->settings, "show-words");
g_action_map_add_action (G_ACTION_MAP (win), action);
g_object_unref (action);
@ -224,10 +225,10 @@ example_app_window_class_init (ExampleAppWindowClass *class)
"/org/gtk/exampleapp/window.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, gears);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, search);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, searchbar);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, searchentry);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, gears);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, words);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, sidebar);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, lines);

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="menu">
<section>
@ -9,6 +10,16 @@
<attribute name="label" translatable="yes">_Lines</attribute>
<attribute name="action">win.show-lines</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Preferences</attribute>
<attribute name="action">app.preferences</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Quit</attribute>
<attribute name="action">app.quit</attribute>
</item>
</section>
</menu>
</interface>

View File

@ -4,16 +4,16 @@
<property name="title" translatable="yes">Preferences</property>
<property name="resizable">0</property>
<property name="modal">1</property>
<child internal-child="vbox">
<object class="GtkBox" id="vbox">
<child internal-child="content_area">
<object class="GtkBox" id="content_area">
<child>
<object class="GtkGrid" id="grid">
<property name="margin-start">6</property>
<property name="margin-end">6</property>
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="row-spacing">12</property>
<property name="column-spacing">6</property>
<property name="column-spacing">12</property>
<child>
<object class="GtkLabel" id="fontlabel">
<property name="label">_Font:</property>

View File

@ -4,43 +4,41 @@
<property name="title" translatable="yes">Example Application</property>
<property name="default-width">600</property>
<property name="default-height">400</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header">
<property name="show-title-buttons">1</property>
<child>
<object class="GtkLabel" id="lines_label">
<property name="visible">0</property>
<property name="label" translatable="yes">Lines:</property>
</object>
</child>
<child>
<object class="GtkLabel" id="lines">
<property name="visible">0</property>
</object>
</child>
<child type="title">
<object class="GtkStackSwitcher" id="tabs">
<property name="stack">stack</property>
</object>
</child>
<child type="end">
<object class="GtkToggleButton" id="search">
<property name="sensitive">0</property>
<property name="icon-name">edit-find-symbolic</property>
</object>
</child>
<child type="end">
<object class="GtkMenuButton" id="gears">
<property name="direction">none</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="content_box">
<property name="orientation">vertical</property>
<child>
<object class="GtkHeaderBar" id="header">
<child>
<object class="GtkLabel" id="lines_label">
<property name="visible">0</property>
<property name="label" translatable="yes">Lines:</property>
</object>
</child>
<child>
<object class="GtkLabel" id="lines">
<property name="visible">0</property>
</object>
</child>
<child type="title">
<object class="GtkStackSwitcher" id="tabs">
<property name="stack">stack</property>
</object>
</child>
<child type="end">
<object class="GtkToggleButton" id="search">
<property name="sensitive">0</property>
<property name="icon-name">edit-find-symbolic</property>
</object>
</child>
<child type="end">
<object class="GtkMenuButton" id="gears">
<property name="direction">none</property>
<style>
<class name="image-button"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSearchBar" id="searchbar">
<child>

View File

@ -31,4 +31,3 @@ subdir('application6')
subdir('application7')
subdir('application8')
subdir('application9')
subdir('application10')

View File

@ -797,7 +797,7 @@ gtk_application_window_class_init (GtkApplicationWindowClass *class)
P_("Show a menubar"),
P_("TRUE if the window should show a "
"menubar at the top of the window"),
TRUE, G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
FALSE, G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
g_object_class_install_properties (object_class, N_PROPS, gtk_application_window_properties);
}

View File

@ -387,7 +387,7 @@ gtk_builder_cscope_finalize (GObject *object)
g_clear_pointer (&priv->callbacks, g_hash_table_destroy);
g_clear_pointer (&priv->module, g_module_close);
G_OBJECT_CLASS (gtk_builder_cscope_parent_class)->dispose (object);
G_OBJECT_CLASS (gtk_builder_cscope_parent_class)->finalize (object);
}
static void

View File

@ -41,9 +41,8 @@ typedef struct _GtkMenuButton GtkMenuButton;
* @menu_button: the #GtkMenuButton
*
* User-provided callback function to create a popup for @menu_button on demand.
* This function is called when the popoup of @menu_button is shown, but none has
* been provided via gtk_menu_buton_set_popup(), gtk_menu_button_set_popover()
* or gtk_menu_button_set_menu_model().
* This function is called when the popup of @menu_button is shown, but none has
* been provided via gtk_menu_button_set_popover() or gtk_menu_button_set_menu_model().
*/
typedef void (*GtkMenuButtonCreatePopupFunc) (GtkMenuButton *menu_button,
gpointer user_data);

View File

@ -1278,7 +1278,7 @@ static GtkWidget *
wrap_in_frame (const gchar *label,
GtkWidget *child)
{
GtkWidget *frame, *label_widget;
GtkWidget *box, *label_widget;
gchar *bold_text;
label_widget = gtk_label_new (NULL);
@ -1290,18 +1290,16 @@ wrap_in_frame (const gchar *label,
gtk_label_set_markup (GTK_LABEL (label_widget), bold_text);
g_free (bold_text);
frame = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_frame_set_child (GTK_FRAME (frame), label_widget);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_container_add (GTK_CONTAINER (box), label_widget);
gtk_widget_set_margin_start (child, 12);
gtk_widget_set_halign (child, GTK_ALIGN_FILL);
gtk_widget_set_valign (child, GTK_ALIGN_FILL);
gtk_frame_set_child (GTK_FRAME (frame), child);
gtk_container_add (GTK_CONTAINER (box), child);
gtk_widget_show (frame);
return frame;
return box;
}
static gboolean

View File

@ -8636,6 +8636,9 @@ gtk_text_view_do_popup (GtkTextView *text_view,
model = gtk_text_view_get_menu_model (text_view);
priv->popup_menu = gtk_popover_menu_new_from_model (model);
gtk_css_node_insert_after (gtk_widget_get_css_node (GTK_WIDGET (text_view)),
gtk_widget_get_css_node (priv->popup_menu),
priv->text_window->css_node);
gtk_widget_set_parent (priv->popup_menu, GTK_WIDGET (text_view));
gtk_popover_set_position (GTK_POPOVER (priv->popup_menu), GTK_POS_BOTTOM);

View File

@ -326,7 +326,7 @@ gtk_text_view_child_constructed (GObject *object)
break;
case GTK_TEXT_WINDOW_TEXT:
gtk_css_node_set_name (css_node, g_quark_from_static_string ("text"));
gtk_css_node_set_name (css_node, g_quark_from_static_string ("child"));
break;
case GTK_TEXT_WINDOW_WIDGET:

View File

@ -9968,6 +9968,9 @@ gtk_tree_view_ensure_interactive_directory (GtkTreeView *tree_view)
return;
tree_view->search_popover = gtk_popover_new ();
gtk_css_node_insert_after (gtk_widget_get_css_node (GTK_WIDGET (tree_view)),
gtk_widget_get_css_node (tree_view->search_popover),
tree_view->header_node);
gtk_widget_set_parent (tree_view->search_popover, GTK_WIDGET (tree_view));
gtk_popover_set_autohide (GTK_POPOVER (tree_view->search_popover), FALSE);

View File

@ -926,7 +926,10 @@ gtk_tree_view_column_update_button (GtkTreeViewColumn *tree_column)
if (priv->child)
{
if (current_child != priv->child)
gtk_frame_set_child (GTK_FRAME (frame), priv->child);
{
gtk_container_remove (GTK_CONTAINER (frame), current_child);
gtk_container_add (GTK_CONTAINER (frame), priv->child);
}
}
else
{
@ -934,7 +937,7 @@ gtk_tree_view_column_update_button (GtkTreeViewColumn *tree_column)
{
current_child = gtk_label_new (NULL);
gtk_widget_show (current_child);
gtk_frame_set_child (GTK_FRAME (frame), current_child);
gtk_container_add (GTK_CONTAINER (frame), current_child);
}
g_return_if_fail (GTK_IS_LABEL (current_child));

View File

@ -1,3 +1,4 @@
#include <config.h>
#include <math.h>
#include <pango/pangocairo.h>
#include <gtk/gtk.h>
@ -580,10 +581,10 @@ activate_about (GSimpleAction *action,
};
gtk_show_about_dialog (GTK_WINDOW (main_window),
"name", "Print Test Editor",
"logo-icon-name", "text-editor",
"version", "0.1",
"copyright", "(C) Red Hat, Inc",
"comments", "Program to demonstrate GTK+ printing.",
"logo-icon-name", "text-editor-symbolic",
"version", PACKAGE_VERSION,
"copyright", "© 2006-2020 Red Hat, Inc",
"comments", "Program to demonstrate GTK printing.",
"authors", authors,
NULL);
}
@ -748,7 +749,7 @@ activate (GApplication *app)
update_title (GTK_WINDOW (main_window));
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (main_window), box);
gtk_window_set_child (GTK_WINDOW (main_window), box);
/* Create document */
sw = gtk_scrolled_window_new (NULL, NULL);

View File

@ -34,6 +34,17 @@ main_loop_quit_cb (gpointer data)
return FALSE;
}
static void
show_and_wait (GtkWidget *widget)
{
gboolean done = FALSE;
g_timeout_add (500, main_loop_quit_cb, &done);
gtk_widget_show (widget);
while (!done)
g_main_context_iteration (NULL, FALSE);
}
static void
test_dialog_basic (void)
{
@ -82,6 +93,17 @@ test_about_dialog_basic (void)
gtk_widget_destroy (dialog);
}
static void
test_about_dialog_show (void)
{
GtkWidget *dialog;
dialog = gtk_about_dialog_new ();
g_assert (GTK_IS_ABOUT_DIALOG (dialog));
show_and_wait (dialog);
gtk_widget_destroy (dialog);
}
static void
test_info_bar_basic (void)
{
@ -115,6 +137,17 @@ test_assistant_basic (void)
gtk_widget_destroy (widget);
}
static void
test_assistant_show (void)
{
GtkWidget *widget;
widget = gtk_assistant_new ();
g_assert (GTK_IS_ASSISTANT (widget));
show_and_wait (widget);
gtk_widget_destroy (widget);
}
static void
test_scale_button_basic (void)
{
@ -205,6 +238,18 @@ test_color_chooser_dialog_basic (void)
gtk_widget_destroy (widget);
}
static void
test_color_chooser_dialog_show (void)
{
GtkWidget *widget;
/* This test also tests the internal GtkColorEditor widget */
widget = gtk_color_chooser_dialog_new (NULL, NULL);
g_assert (GTK_IS_COLOR_CHOOSER_DIALOG (widget));
show_and_wait (widget);
gtk_widget_destroy (widget);
}
/* Avoid warnings from GVFS-RemoteVolumeMonitor */
static gboolean
ignore_gvfs_warning (const gchar *log_domain,
@ -268,6 +313,23 @@ test_file_chooser_dialog_basic (void)
gtk_widget_destroy (widget);
}
static void
test_file_chooser_dialog_show (void)
{
GtkWidget *widget;
g_test_log_set_fatal_handler (ignore_gvfs_warning, NULL);
widget = gtk_file_chooser_dialog_new ("The Dialog", NULL,
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
"_OK", GTK_RESPONSE_OK,
NULL);
g_assert (GTK_IS_FILE_CHOOSER_DIALOG (widget));
show_and_wait (widget);
gtk_widget_destroy (widget);
}
static void
test_file_chooser_button_basic (void)
{
@ -315,6 +377,17 @@ test_font_chooser_dialog_basic (void)
gtk_widget_destroy (widget);
}
static void
test_font_chooser_dialog_show (void)
{
GtkWidget *widget;
widget = gtk_font_chooser_dialog_new ("Choose a font !", NULL);
g_assert (GTK_IS_FONT_CHOOSER_DIALOG (widget));
show_and_wait (widget);
gtk_widget_destroy (widget);
}
#ifdef HAVE_UNIX_PRINT_WIDGETS
static void
test_page_setup_unix_dialog_basic (void)
@ -326,6 +399,17 @@ test_page_setup_unix_dialog_basic (void)
gtk_widget_destroy (widget);
}
static void
test_page_setup_unix_dialog_show (void)
{
GtkWidget *widget;
widget = gtk_page_setup_unix_dialog_new ("Setup your Page !", NULL);
g_assert (GTK_IS_PAGE_SETUP_UNIX_DIALOG (widget));
show_and_wait (widget);
gtk_widget_destroy (widget);
}
static void
test_print_unix_dialog_basic (void)
{
@ -335,6 +419,17 @@ test_print_unix_dialog_basic (void)
g_assert (GTK_IS_PRINT_UNIX_DIALOG (widget));
gtk_widget_destroy (widget);
}
static void
test_print_unix_dialog_show (void)
{
GtkWidget *widget;
widget = gtk_print_unix_dialog_new ("Go Print !", NULL);
g_assert (GTK_IS_PRINT_UNIX_DIALOG (widget));
show_and_wait (widget);
gtk_widget_destroy (widget);
}
#endif
int
@ -353,31 +448,40 @@ main (int argc, char **argv)
*/
g_assert (g_setenv ("GTK_WIDGET_ASSERT_COMPONENTS", "1", TRUE));
g_test_add_func ("/Template/GtkDialog/Basic", test_dialog_basic);
g_test_add_func ("/Template/GtkDialog/OverrideProperty", test_dialog_override_property);
g_test_add_func ("/Template/GtkMessageDialog/Basic", test_message_dialog_basic);
g_test_add_func ("/Template/GtkAboutDialog/Basic", test_about_dialog_basic);
g_test_add_func ("/Template/GtkInfoBar/Basic", test_info_bar_basic);
g_test_add_func ("/Template/GtkLockButton/Basic", test_lock_button_basic);
g_test_add_func ("/Template/GtkAssistant/Basic", test_assistant_basic);
g_test_add_func ("/Template/GtkScaleButton/Basic", test_scale_button_basic);
g_test_add_func ("/Template/GtkVolumeButton/Basic", test_volume_button_basic);
g_test_add_func ("/Template/GtkStatusBar/Basic", test_statusbar_basic);
g_test_add_func ("/Template/GtkSearchBar/Basic", test_search_bar_basic);
g_test_add_func ("/Template/GtkActionBar/Basic", test_action_bar_basic);
g_test_add_func ("/Template/GtkAppChooserWidget/Basic", test_app_chooser_widget_basic);
g_test_add_func ("/Template/GtkAppChooserDialog/Basic", test_app_chooser_dialog_basic);
g_test_add_func ("/Template/GtkColorChooserDialog/Basic", test_color_chooser_dialog_basic);
g_test_add_func ("/Template/GtkFileChooserWidget/Basic", test_file_chooser_widget_basic);
g_test_add_func ("/Template/GtkFileChooserDialog/Basic", test_file_chooser_dialog_basic);
g_test_add_func ("/Template/GtkFileChooserButton/Basic", test_file_chooser_button_basic);
g_test_add_func ("/Template/GtkFontButton/Basic", test_font_button_basic);
g_test_add_func ("/Template/GtkFontChooserWidget/Basic", test_font_chooser_widget_basic);
g_test_add_func ("/Template/GtkFontChooserDialog/Basic", test_font_chooser_dialog_basic);
g_test_add_func ("/template/GtkDialog/basic", test_dialog_basic);
g_test_add_func ("/template/GtkDialog/OverrideProperty", test_dialog_override_property);
g_test_add_func ("/template/GtkMessageDialog/basic", test_message_dialog_basic);
g_test_add_func ("/template/GtkAboutDialog/basic", test_about_dialog_basic);
g_test_add_func ("/template/GtkAboutDialog/show", test_about_dialog_show);
g_test_add_func ("/template/GtkInfoBar/basic", test_info_bar_basic);
g_test_add_func ("/template/GtkLockButton/basic", test_lock_button_basic);
g_test_add_func ("/template/GtkAssistant/basic", test_assistant_basic);
g_test_add_func ("/template/GtkAssistant/show", test_assistant_show);
g_test_add_func ("/template/GtkScaleButton/basic", test_scale_button_basic);
g_test_add_func ("/template/GtkVolumeButton/basic", test_volume_button_basic);
g_test_add_func ("/template/GtkStatusBar/basic", test_statusbar_basic);
g_test_add_func ("/template/GtkSearchBar/basic", test_search_bar_basic);
g_test_add_func ("/template/GtkActionBar/basic", test_action_bar_basic);
g_test_add_func ("/template/GtkAppChooserWidget/basic", test_app_chooser_widget_basic);
g_test_add_func ("/template/GtkAppChooserDialog/basic", test_app_chooser_dialog_basic);
g_test_add_func ("/template/GtkColorChooserDialog/basic", test_color_chooser_dialog_basic);
g_test_add_func ("/template/GtkColorChooserDialog/show", test_color_chooser_dialog_show);
g_test_add_func ("/template/GtkFileChooserWidget/basic", test_file_chooser_widget_basic);
g_test_add_func ("/template/GtkFileChooserDialog/basic", test_file_chooser_dialog_basic);
if (0)
g_test_add_func ("/template/GtkFileChooserDialog/show", test_file_chooser_dialog_show);
g_test_add_func ("/template/GtkFileChooserButton/basic", test_file_chooser_button_basic);
g_test_add_func ("/template/GtkFontButton/basic", test_font_button_basic);
g_test_add_func ("/template/GtkFontChooserWidget/basic", test_font_chooser_widget_basic);
g_test_add_func ("/template/GtkFontChooserDialog/basic", test_font_chooser_dialog_basic);
g_test_add_func ("/template/GtkFontChooserDialog/show", test_font_chooser_dialog_show);
#ifdef HAVE_UNIX_PRINT_WIDGETS
g_test_add_func ("/Template/UnixPrint/GtkPageSetupUnixDialog/Basic", test_page_setup_unix_dialog_basic);
g_test_add_func ("/Template/UnixPrint/GtkPrintUnixDialog/Basic", test_print_unix_dialog_basic);
g_test_add_func ("/template/GtkPageSetupUnixDialog/basic", test_page_setup_unix_dialog_basic);
g_test_add_func ("/template/GtkPageSetupUnixDialog/show", test_page_setup_unix_dialog_show);
g_test_add_func ("/template/GtkPrintUnixDialog/basic", test_print_unix_dialog_basic);
if (0)
g_test_add_func ("/template/GtkPrintUnixDialog/show", test_print_unix_dialog_show);
#endif
return g_test_run();

View File

@ -225,7 +225,7 @@ test_row_separator_height (void)
g_assert_cmpint (rect.height, ==, height);
g_assert_cmpint (cell_rect.height, ==, height);
gtk_widget_destroy (tree_view);
gtk_widget_destroy (window);
}
static void