mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-23 20:30:15 +00:00
Drop no-longer-used migration docs
This commit is contained in:
parent
cf752786f3
commit
83f5e4868c
@ -1,64 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<chapter id="gtk-migrating-ClientSideWindows">
|
||||
|
||||
<title>Migrating to client-side windows</title>
|
||||
|
||||
<para>
|
||||
In version 2.18, GDK has been changed to use client-side windows. This
|
||||
means that there is no longer a 1-1 correspondence between #GdkWindows
|
||||
and windows in the underlying window system. In particular, it is no
|
||||
longer correct to assume that each window has an associated XID.
|
||||
Code that makes this assumption can sometimes be fixed by calling
|
||||
gdk_window_ensure_native() on the windows in question.
|
||||
Calling gdk_x11_window_get_xid() (or GDK_WINDOW_XID()) from the
|
||||
X11-specific API on a non-native window will explicitly call
|
||||
gdk_window_ensure_native(), so old code using this will continue to
|
||||
work. A small gotcha is that the GDK_WINDOW_XID() call is no longer a
|
||||
trivial accessor for the XID of the window, and thus must not be called
|
||||
from another thread without taking locking precautions.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
GDK looks for the <envar>GDK_NATIVE_WINDOWS</envar> environment variable
|
||||
and makes all windows native if it is set. It also tries to be more
|
||||
compatible with the way prior versions worked in some other ways.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Some applications assume that they can just operate on the X windows
|
||||
corresponding to their GDK windows without ever telling GDK. One
|
||||
example that we've seen is changing the child window stacking order
|
||||
using XRestackWindows(). Fixing this properly requires to fix the code
|
||||
to use GDK functions to achieve whatever it is trying to achieve.
|
||||
To make this easier in the case of stacking order changes, we've added
|
||||
a gdk_window_restack() function.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
One change that can cause problems for some applications is that GDK
|
||||
is more aggressive about optimizing away expose events. Code that does
|
||||
more than just repainting exposed areas in response to expose events
|
||||
may be affected by this.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Problems can also occur when using cairo for drawing. One thing that can
|
||||
go wrong is clip handling. You may not use cairo_reset_clip() on a
|
||||
cairo_t on a cairo context created via gdk_cairo_create() or passed to
|
||||
the GtkWidget::draw signal.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Due to a weird API in XClearArea the gdk_window_clear_area() call handled
|
||||
a specified width or height of zero to mean "to end of window" for
|
||||
non-double-buffered drawing. This has been changed to be consistent with
|
||||
the docs and what happens in the double-buffered case. All code in GTK+
|
||||
that relied on this has been fixed, but it is possible (although unlikely)
|
||||
that third party applications rely on this. If you need to do this, just
|
||||
implement it yourself using gdk_drawable_get_size().
|
||||
</para>
|
||||
|
||||
</chapter>
|
@ -1,98 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<chapter id="gtk-migrating-GtkAboutDialog">
|
||||
|
||||
<title>Migrating from GnomeAbout to GtkAboutDialog</title>
|
||||
|
||||
<para>
|
||||
Since version 2.6, GTK+ provides the #GtkAboutDialog widget as a
|
||||
replacement for the <structname>GnomeAbout</structname> dialog in
|
||||
the libgnomeui library.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
#GtkAboutDialog supports all features found in <structname>GnomeAbout</structname>.
|
||||
The <structname>GtkAboutDialog</structname> API is bigger, since it follows
|
||||
the GTK+ policy to have getters and setters for all widget properties,
|
||||
but it isn't much more complex than <structname>GnomeAbout</structname>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To convert an application that uses <structname>GnomeAbout</structname> to
|
||||
<structname>GtkAboutDialog</structname>, as a first step, replace calls
|
||||
like
|
||||
<informalexample><programlisting>
|
||||
const gchar *documentors[] = {
|
||||
"Documenter 1",
|
||||
"Documenter 2",
|
||||
NULL
|
||||
};
|
||||
|
||||
const gchar *documentors[] = {
|
||||
"Author 1",
|
||||
"Author 2",
|
||||
NULL
|
||||
};
|
||||
|
||||
GtkWidget *about = gnome_about_new ("GNOME Test Program", VERSION,
|
||||
"(C) 1998-2001 The Free Software Foundation",
|
||||
"Program to display GNOME functions.",
|
||||
authors,
|
||||
documenters,
|
||||
_("translator-credits"),
|
||||
"logo.png");
|
||||
</programlisting></informalexample>
|
||||
by something like
|
||||
<informalexample><programlisting>
|
||||
GdkPixbuf *logo = gdk_pixbuf_new_from_file ("logo.png", NULL);
|
||||
GtkWidget *about = g_object_new (GTK_TYPE_ABOUT_DIALOG,
|
||||
"name", "GNOME Test Program",
|
||||
"version", VERSION,
|
||||
"copyright", "(C) 1998-2001 The Free Software Foundation",
|
||||
"comments", "Program to display GNOME functions.",
|
||||
"authors", authors,
|
||||
"documenters", documenters,
|
||||
"translator-credits", _("translator-credits"),
|
||||
"logo", logo,
|
||||
NULL);
|
||||
g_object_unref (pixbuf);
|
||||
</programlisting></informalexample>
|
||||
If the g_object_new() construction scares you, you can also use
|
||||
gtk_about_dialog_new() to construct the dialog and then use the
|
||||
setters for the individual properties.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Once you are done with the initial conversion, you may want to look into
|
||||
using some of the features of <structname>GtkAboutDialog</structname>
|
||||
which are not present in <structname>GnomeAbout</structname>.
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
You can specify license information with the
|
||||
#GtkAboutDialog:license property
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
You can add separate credits for artists with the
|
||||
#GtkAboutDialog:artists property
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
You can add a pointer to the website of your application, using the
|
||||
#GtkAboutDialog:website and #GtkAboutDialog:website-label properties.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
If your credits contain email addresses or URLs, you can turn them
|
||||
into clickable links using gtk_about_dialog_set_email_hook() and
|
||||
gtk_about_dialog_set_url_hook().
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
<!--
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
|
||||
End:
|
||||
-->
|
@ -1,445 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<chapter id="gtk-migrating-GtkAction">
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Federico</firstname>
|
||||
<surname>Mena-Quintero</surname>
|
||||
<affiliation>
|
||||
<address>
|
||||
<email>federico@ximian.com</email>
|
||||
</address>
|
||||
</affiliation>
|
||||
</author>
|
||||
</chapterinfo>
|
||||
|
||||
<title>Migrating from old menu and toolbar systems to GtkAction</title>
|
||||
|
||||
<para>
|
||||
Prior to GTK+ 2.4, there were several APIs in use to create menus
|
||||
and toolbars. GTK+ itself included #GtkItemFactory, which was
|
||||
historically used in the GIMP; libgnomeui provided the gnome-ui
|
||||
set of macros; libbonoboui provided a complex mechanism to do menu
|
||||
merging across embedded components. GTK+ 2.4 includes a system
|
||||
for creating menus and toolbars, with merging of items, based
|
||||
around the #GtkAction mechanism.
|
||||
</para>
|
||||
|
||||
<section id="actions-and-action-groups">
|
||||
<title>Actions and Action Groups</title>
|
||||
|
||||
<para>
|
||||
A #GtkAction represents an operation that the user can perform from
|
||||
the menus and toolbars of an application. It is similar to "verbs"
|
||||
in other menu systems. A #GtkAction has a name, which is its identifier,
|
||||
and it can have several widgets that represent it in the user interface.
|
||||
For example, an action for <symbol>EditCopy</symbol> can have a menu item
|
||||
as well as a toolbar button associated to it. If there is nothing selected
|
||||
in the document, the application can simply de-sensitize the
|
||||
<symbol>EditCopy</symbol> action; this will cause both the menu
|
||||
item and the toolbar button to be de-sensitized automatically.
|
||||
Similarly, whenever the user selects the menu item or the
|
||||
toolbar button associated to the <symbol>EditCopy</symbol>
|
||||
action, the corresponding #GtkAction object will emit an
|
||||
"activate" signal.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
#GtkActionGroup is simply a group of #GtkAction objects. An
|
||||
application may want to have several groups: one for global
|
||||
actions such as "new document", "about", and "exit"; then one
|
||||
group for each open document with actions specific to the
|
||||
document, such as "cut", "copy", "paste", and "print".
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Normal actions are simply commands, such as
|
||||
<symbol>FileSave</symbol> or <symbol>EditCopy</symbol>.
|
||||
Toggle actions can be active or inactive, such as
|
||||
<symbol>FormatBold</symbol> or <symbol>ViewShowRulers</symbol>.
|
||||
Radio actions define a set of items for which one and only one
|
||||
can be active at a time, for example, {
|
||||
<symbol>ViewHighQuality</symbol>,
|
||||
<symbol>ViewNormalQuality</symbol>,
|
||||
<symbol>ViewLowQuality</symbol> }.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="ui-manager">
|
||||
<title>User Interface Manager Object</title>
|
||||
|
||||
<para>
|
||||
#GtkUIManager is an object that can construct menu and toolbar widgets
|
||||
from an XML description. These widgets are in turn associated to
|
||||
corresponding actions and action groups.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
#GtkUIManager supports merging of menus and toolbars for applications
|
||||
that have multiple components, each with separate sets of commands.
|
||||
For example, a word processor that can embed images may want to have
|
||||
toolbar buttons for Bold and Italic when the cursor is on a text
|
||||
block, but Crop and Brightness/Contrast buttons when the cursor
|
||||
is on an image. These actions, which change depending on the
|
||||
state of the application, can be merged and de-merged from a
|
||||
#GtkUIManager as appropriate.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="migrating-gnomeuiinfo">
|
||||
<title>Migrating from GnomeUIInfo</title>
|
||||
|
||||
<para>
|
||||
Prior to GTK+ 2.4, some applications used the GnomeUIInfo
|
||||
mechanism from
|
||||
<filename><libgnomeui/gnome-app-helper.h></filename> to
|
||||
define their menus and toolbars. With it, a program decleres an
|
||||
array of <structname>GnomeUIInfo</structname> structures, which
|
||||
contain information for menu or toolbar items such as their
|
||||
label, icon, and accelerator key. Then, one calls
|
||||
gnome_app_fill_menu() or gnome_app_fill_toolbar(), or one of the
|
||||
related functions, to create the appropriate widgets based on
|
||||
these structures.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
A downside of this API is that the same structures are used to
|
||||
pass back pointers to the widgets that got created. This means
|
||||
that the structures cannot simply be kept around if the program
|
||||
requires multiple instances of the user interface (e.g. several
|
||||
windows); each new invocation of gnome_app_fill_menu() would
|
||||
overwrite the widget fields of the structures.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Another disadvantage is that there is no automatic way to
|
||||
synchronize the state of related controls. If there are toolbar
|
||||
toogle buttons for "Bold", "Italic", "Underline", and also
|
||||
corresponding menu items under "Format/Bold", etc., one has to
|
||||
synchronize their toggled states by hand whenever the user
|
||||
selects any one of them.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Finally, there is no way to do menu and toolbar merging for
|
||||
applications that require embedded components.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To convert an application that uses GnomeUIInfo into the new
|
||||
GtkAction mechanism, you need to do several things:
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Separate your existing GnomeUIInfo entries into normal
|
||||
actions, toggle actions, and radio actions, and then create
|
||||
a separate array of #GtkActionEntry structures
|
||||
for each group. This will allow you to create the necessary
|
||||
#GtkActionGroup objects. Note that this does not describe
|
||||
the actual "shape" that your menus and toolbars will have;
|
||||
it simply defines the set of commands that will appear in them.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Create an XML description of your menus and toolbars for use
|
||||
with #GtkUIManager. This defines the actual shape of the menus
|
||||
and toolbars.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Port the code that uses gnome-app and gnome-app-helper to
|
||||
#GtkAction and #GtkUIManager.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If your GnomeUIInfo entries use GNOME_APP_PIXMAP_DATA or
|
||||
GNOME_APP_PIXMAP_FILENAME for pixmaps, you have to create a
|
||||
#GtkIconFactory, add it to the list of default factories, then
|
||||
create a #GtkIconSet for each of your own icons. Add the sets to
|
||||
the factory, and use the id in the #GtkActionEntry like a regular
|
||||
GTK+ stock id.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<example id="gnomeuiinfo-example">
|
||||
<title>GnomeUIInfo Example</title>
|
||||
|
||||
<para>
|
||||
The following code shows a declaration of a simple menu bar to
|
||||
be used with gnome_app_fill_menu() or similar. The menu hierarchy i
|
||||
looks like this:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><guimenu>File</guimenu></para>
|
||||
<simplelist>
|
||||
<member><guimenuitem>Open</guimenuitem></member>
|
||||
<member><guimenuitem>—</guimenuitem></member>
|
||||
<member><guimenuitem>Exit</guimenuitem></member>
|
||||
</simplelist>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><guimenu>View</guimenu></para>
|
||||
<simplelist>
|
||||
<member><guimenuitem>Zoom In</guimenuitem></member>
|
||||
<member><guimenuitem>Zoom Out</guimenuitem></member>
|
||||
<member><guimenuitem>—</guimenuitem></member>
|
||||
<member><guimenuitem>[ ] Full Screen</guimenuitem></member>
|
||||
<member><guimenuitem>—</guimenuitem></member>
|
||||
<member><guimenuitem>( ) High Quality</guimenuitem></member>
|
||||
<member><guimenuitem>( ) Normal Quality</guimenuitem></member>
|
||||
<member><guimenuitem>( ) Low Quality</guimenuitem></member>
|
||||
</simplelist>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<programlisting>
|
||||
static GnomeUIInfo file_menu_items[] = {
|
||||
{ GNOME_APP_UI_ITEM, "_Open", "Open a file",
|
||||
open_callback, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GTK_STOCK_OPEN,
|
||||
'o', GDK_CONTROL_MASK, NULL },
|
||||
{ GNOME_APP_UI_SEPARATOR },
|
||||
{ GNOME_APP_UI_ITEM, "E_xit", "Exit the program",
|
||||
exit_callback, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GTK_STOCK_QUIT,
|
||||
'q', GDK_CONTROL_MASK, NULL},
|
||||
{ GNOME_APP_UI_ENDOFINFO }
|
||||
};
|
||||
|
||||
static GnomeUIInfo view_radio_items[] = {
|
||||
{ GNOME_APP_UI_ITEM, "_High Quality", "Display images in high quality, slow mode",
|
||||
high_quality_callback, NULL, NULL, GNOME_APP_PIXMAP_FILENAME, "high-quality.png",
|
||||
0, 0, NULL },
|
||||
{ GNOME_APP_UI_ITEM, "_Normal Quality", "Display images in normal quality",
|
||||
normal_quality_callback, NULL, NULL, GNOME_APP_PIXMAP_FILENAME, "normal-quality.png",
|
||||
0, 0, NULL },
|
||||
{ GNOME_APP_UI_ITEM, "_Low Quality", "Display images in low quality, fast mode",
|
||||
low_quality_callback, NULL, NULL, GNOME_APP_PIXMAP_FILENAME, "low-quality.png",
|
||||
0, 0, NULL },
|
||||
{ GNOME_APP_UI_ENDOFINFO }
|
||||
};
|
||||
|
||||
static GnomeUIInfo view_menu_items[] = {
|
||||
{ GNOME_APP_UI_ITEM, "Zoom _In", "Zoom into the image",
|
||||
zoom_in_callback, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GTK_STOCK_ZOOM_IN,
|
||||
GDK_PLUS, 0, NULL },
|
||||
{ GNOME_APP_UI_ITEM, "Zoom _Out", "Zoom away from the image",
|
||||
zoom_out_callback, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GTK_STOCK_ZOOM_OUT,
|
||||
GDK_MINUS, 0, NULL },
|
||||
{ GNOME_APP_UI_SEPARATOR },
|
||||
{ GNOME_APP_UI_TOGGLEITEM, "_Full Screen", "Switch between full screen and windowed mode",
|
||||
full_screen_callback, NULL, NULL, GNOME_APP_PIXMAP_NONE, NULL,
|
||||
GDK_F11, 0, NULL },
|
||||
{ GNOME_APP_UI_SEPARATOR },
|
||||
{ GNOME_APP_UI_RADIOITEMS, NULL, NULL, view_radio_items },
|
||||
{ GNOME_APP_UI_ENDOFINFO }
|
||||
};
|
||||
|
||||
static GnomeUIInfo menubar[] = {
|
||||
{ GNOME_APP_UI_SUBTREE, "_File", NULL, file_menu_items },
|
||||
{ GNOME_APP_UI_SUBTREE, "_View", NULL, view_menu_items },
|
||||
{ GNOME_APP_UI_ENDOFINFO }
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<example id="gnomeuiinfo-action-entries">
|
||||
<title><structname>GtkActionEntry</structname> Structures</title>
|
||||
|
||||
<para>
|
||||
The following code is the set of actions that are present in
|
||||
the <link linkend="gnomeuiinfo-example">previous
|
||||
example</link>. Note that the toggle and radio entries are
|
||||
separate from normal actions. Also, note that #GtkActionEntry
|
||||
structures take key names in the format of gtk_accelerator_parse()
|
||||
rather than key values plus modifiers; you will have to convert these
|
||||
values by hand. For example, %GDK_F11 with no modifiers is equivalent
|
||||
to a key name of <literal>"F11"</literal>. Likewise, <literal>"o"</literal>
|
||||
with %GDK_CONTROL_MASK is equivalent to <literal>"<ontrol>O"</literal>.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
/* Normal items */
|
||||
static const GtkActionEntry entries[] = {
|
||||
{ "FileMenu", NULL, "_File" },
|
||||
{ "ViewMenu", NULL, "_View" },
|
||||
{ "Open", GTK_STOCK_OPEN, "_Open", "<control>O", "Open a file", open_action_callback },
|
||||
{ "Exit", GTK_STOCK_QUIT, "E_xit", "<control>Q", "Exit the program", exit_action_callback },
|
||||
{ "ZoomIn", GTK_STOCK_ZOOM_IN, "Zoom _In", "plus", "Zoom into the image", zoom_in_action_callback },
|
||||
{ "ZoomOut", GTK_STOCK_ZOOM_OUT, "Zoom _Out", "minus", "Zoom away from the image", zoom_out_action_callback },
|
||||
};
|
||||
|
||||
/* Toggle items */
|
||||
static const GtkToggleActionEntry toggle_entries[] = {
|
||||
{ "FullScreen", NULL, "_Full Screen", "F11", "Switch between full screen and windowed mode", full_screen_action_callback, FALSE }
|
||||
};
|
||||
|
||||
/* Radio items */
|
||||
static const GtkRadioActionEntry radio_entries[] = {
|
||||
{ "HighQuality", "my-stock-high-quality", "_High Quality", NULL, "Display images in high quality, slow mode", 0 },
|
||||
{ "NormalQuality", "my-stock-normal-quality", "_Normal Quality", NULL, "Display images in normal quality", 1 },
|
||||
{ "LowQuality", "my-stock-low-quality", "_Low Quality", NULL, "Display images in low quality, fast mode", 2 }
|
||||
};
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<example id="gnomeuiinfo-xml">
|
||||
<title>XML Description</title>
|
||||
|
||||
<para>
|
||||
After extracting the actions, you will need to create an XML
|
||||
description of the actual layout of your menus and toolbars
|
||||
for use with #GtkUIManager. The following code shows a simple
|
||||
menu bar that corresponds to the <link linkend="gnomeuiinfo-example">previous
|
||||
example</link>. Note that the <guimenu>File</guimenu> and
|
||||
<guimenu>View</guimenu> menus have their names specified in
|
||||
the <link linkend="gnomeuiinfo-action-entries">action
|
||||
entries</link>, not in the XML itself. This is because the
|
||||
XML description only contains <emphasis>identifiers</emphasis>
|
||||
for the items in the GUI, rather than human-readable names.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
static const char *ui_description =
|
||||
"<ui>"
|
||||
" <menubar name='MainMenu'>"
|
||||
" <menu action='FileMenu'>"
|
||||
" <menuitem action='Open'/>"
|
||||
" <menuitem action='Exit'/>"
|
||||
" </menu>"
|
||||
" <menu action='ViewMenu'>"
|
||||
" <menuitem action='ZoomIn'/>"
|
||||
" <menuitem action='ZoomOut'/>"
|
||||
" <separator/>"
|
||||
" <menuitem action='FullScreen'/>"
|
||||
" <separator/>"
|
||||
" <menuitem action='HighQuality'/>"
|
||||
" <menuitem action='NormalQuality'/>"
|
||||
" <menuitem action='LowQuality'/>"
|
||||
" </menu>"
|
||||
" </menubar>"
|
||||
"</ui>";
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<example id="gnomeuiinfo-code">
|
||||
<title>Creating the Menu Bar</title>
|
||||
|
||||
<para>
|
||||
In this last example, we will create a #GtkActionGroup based on the
|
||||
<link linkend="gnomeuiinfo-action-entries">action entries</link>
|
||||
we created above. We will then create a #GtkUIManager with the <link
|
||||
linkend="gnomeuiinfo-xml">XML description</link> of the menu
|
||||
layout. We will also extract the accelerator group and the
|
||||
widgets from the #GtkUIManager put them into a window.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
GtkWidget *window;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *menubar;
|
||||
GtkActionGroup *action_group;
|
||||
GtkUIManager *ui_manager;
|
||||
GtkAccelGroup *accel_group;
|
||||
GError *error;
|
||||
|
||||
register_my_stock_icons (<!-- -->);
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
|
||||
vbox = gtk_vbox_new (FALSE, 0);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
action_group = gtk_action_group_new ("MenuActions");
|
||||
gtk_action_group_add_actions (action_group, entries, G_N_ELEMENTS (entries), window);
|
||||
gtk_action_group_add_toggle_actions (action_group, toggle_entries, G_N_ELEMENTS (toggle_entries), window);
|
||||
gtk_action_group_add_radio_actions (action_group, radio_entries, G_N_ELEMENTS (radio_entries), 0, radio_action_callback, window);
|
||||
|
||||
ui_manager = gtk_ui_manager_new (<!-- -->);
|
||||
gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
|
||||
|
||||
accel_group = gtk_ui_manager_get_accel_group (ui_manager);
|
||||
gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
|
||||
|
||||
error = NULL;
|
||||
if (!gtk_ui_manager_add_ui_from_string (ui_manager, ui_description, -1, &error))
|
||||
{
|
||||
g_message ("building menus failed: %s", error->message);
|
||||
g_error_free (error);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
menubar = gtk_ui_manager_get_widget (ui_manager, "/MainMenu");
|
||||
gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0);
|
||||
|
||||
gtk_widget_show_all (window);
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<example id="gnomeuiinfo-icons">
|
||||
<title>Registering the icons</title>
|
||||
|
||||
<para>
|
||||
Here we show how the register_my_stock_icons() function
|
||||
used in the previous example could look like.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
static struct {
|
||||
gchar *filename;
|
||||
gchar *stock_id;
|
||||
} stock_icons[] = {
|
||||
{ "high-quality.png", "my-stock-high-quality" },
|
||||
{ "normal-quality.png", "my-stock-normal-quality" },
|
||||
{ "low-quality.png", "my-stock-low-quality" },
|
||||
};
|
||||
|
||||
static gint n_stock_icons = G_N_ELEMENTS (stock_icons);
|
||||
|
||||
static void
|
||||
register_my_stock_icons (void)
|
||||
{
|
||||
GtkIconFactory *icon_factory;
|
||||
GtkIconSet *icon_set;
|
||||
GtkIconSource *icon_source;
|
||||
gint i;
|
||||
|
||||
icon_factory = gtk_icon_factory_new (<!-- -->);
|
||||
|
||||
for (i = 0; i < n_stock_icons; i++)
|
||||
{
|
||||
icon_set = gtk_icon_set_new (<!-- -->);
|
||||
icon_source = gtk_icon_source_new (<!-- -->);
|
||||
gtk_icon_source_set_filename (icon_source, stock_icons[i].filename);
|
||||
gtk_icon_set_add_source (icon_set, icon_source);
|
||||
gtk_icon_source_free (icon_source);
|
||||
gtk_icon_factory_add (icon_factory, stock_icons[i].stock_id, icon_set);
|
||||
gtk_icon_set_unref (icon_set);
|
||||
}
|
||||
|
||||
gtk_icon_factory_add_default (icon_factory);
|
||||
|
||||
g_object_unref (icon_factory);
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
|
||||
<!--
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
|
||||
End:
|
||||
-->
|
@ -1,178 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<chapter id="gtk-migrating-GtkAssistant">
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Carlos</firstname>
|
||||
<surname>Garnacho</surname>
|
||||
<affiliation>
|
||||
<address>
|
||||
<email>carlosg@gnome.org</email>
|
||||
</address>
|
||||
</affiliation>
|
||||
</author>
|
||||
</chapterinfo>
|
||||
|
||||
<title>Migrating from GnomeDruid to GtkAssistant</title>
|
||||
|
||||
<para>
|
||||
Since version 2.10, GTK+ provides the GtkAssistant widget as a replacement
|
||||
for the <structname>GnomeDruid</structname> widget in the libgnomeui
|
||||
library.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Conceptually, both <structname>GtkAssistant</structname> and
|
||||
<structname>GnomeDruid</structname> do the same task, but there are
|
||||
several areas where the API has been completely redesigned, so this
|
||||
chapter covers the main changes between both widgets.
|
||||
</para>
|
||||
|
||||
<section id="inserting-pages">
|
||||
<title>Inserting pages</title>
|
||||
|
||||
<para>
|
||||
<structname>GnomeDruid</structname> was implemented as a container for
|
||||
<structname>GnomeDruidPage</structname> abstract objects, which are
|
||||
implemented by the <structname>GnomeDruidPageEdge</structname> and
|
||||
<structname>GnomeDruidPageStandard</structname> widgets. Instead,
|
||||
<structname>GtkAssistant</structname> allows any widget to be a page,
|
||||
and implements per-page settings (such as page type or title) as
|
||||
child properties. So instead of:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
/* Page 1 */
|
||||
page = gnome_druid_page_edge_new (GNOME_EDGE_START);
|
||||
gnome_druid_page_edge_set_test (GNOME_DRUID_PAGE_EDGE (page),
|
||||
"Welcome to the assistant, it will make your life easier");
|
||||
gtk_widget_show (page);
|
||||
gnome_druid_append_page (GNOME_DRUID (druid), GNOME_DRUID_PAGE (page));
|
||||
|
||||
/* Page 2 */
|
||||
page = gnome_druid_page_standard_new ();
|
||||
gtk_container_add (GTK_CONTAINER (GNOME_DRUID_PAGE_STANDARD (page)->vbox,
|
||||
create_page1 ());
|
||||
gtk_widget_show_all (page);
|
||||
gnome_druid_append_page (GNOME_DRUID (druid), GNOME_DRUID_PAGE (page));
|
||||
|
||||
/* Page 3 */
|
||||
page = gnome_druid_page_edge_new (GNOME_EDGE_FINISH);
|
||||
gnome_druid_page_edge_set_test (GNOME_DRUID_PAGE_EDGE (page),
|
||||
"Now you are done, your life is easier");
|
||||
gtk_widget_show (page);
|
||||
gnome_druid_append_page (GNOME_DRUID (druid), GNOME_DRUID_PAGE (page));
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
You have to write:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
gtk_assistant_append_page (GTK_ASSISTANT (assistant),
|
||||
gtk_label_new ("Welcome to the assistant, it will make your life easier"));
|
||||
gtk_assistant_append_page (GTK_ASSISTANT (assistant),
|
||||
create_page1 ());
|
||||
gtk_assistant_append_page (GTK_ASSISTANT (assistant),
|
||||
gtk_label_new ("Now you are done, your life is easier");
|
||||
</programlisting>
|
||||
</section>
|
||||
|
||||
<section id="decorating-the-assistant-pages">
|
||||
<title>Decorating the assistant pages</title>
|
||||
|
||||
<para>
|
||||
To decorate your assistant pages, <structname>GtkAssistant</structname> provides similar functions
|
||||
to <structname>GnomeDruid</structname>, so you have to transform code like this:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
gnome_druid_page_edge_set_title (GNOME_DRUID_PAGE_EDGE (page), "Welcome");
|
||||
gnome_druid_page_edge_set_logo (GNOME_DRUID_PAGE_EDGE (page), logo_pixbuf);
|
||||
gnome_druid_page_edge_set_watermark (GNOME_DRUID_PAGE_EDGE (page), watermark_pixbuf);
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
Into this:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page_widget, "Welcome");
|
||||
gtk_assistant_set_page_header_image (GTK_ASSISTANT (assistant), page_widget, logo_pixbuf);
|
||||
gtk_assistant_set_page_side_image (GTK_ASSISTANT (assistant), page_widget, watermark_pixbuf);
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
Where page_widget is the widget used as a page.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="setting-the-page-flow">
|
||||
<title>Setting the page flow</title>
|
||||
|
||||
<para>
|
||||
Here is the area where <structname>GtkAssistant</structname> and <structname>GnomeDruid</structname>
|
||||
differ the most. While <structname>GnomeDruid</structname> used the "next" and "back" signals from the
|
||||
<structname>GnomeDruidPage</structname>, <structname>GtkAssistant</structname> uses the following
|
||||
techniques:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>gtk_assistant_set_forward_page_func (): Allows to define a GtkAssistantPageFunc to let the
|
||||
assistant know which will be the following page given the current page.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>gtk_assistant_set_page_complete (): Lets the assistant know whether the specified page is complete
|
||||
or not, updating buttons state accordingly.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>gtk_assistant_set_page_type (): Lets the assistant know the page role and update the buttons
|
||||
state accordingly. Pages can have the following roles:</para>
|
||||
<simplelist>
|
||||
<member>Intro</member>
|
||||
<member>Content</member>
|
||||
<member>Progress</member>
|
||||
<member>Confirmation</member>
|
||||
<member>Summary</member>
|
||||
</simplelist>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
A sample GtkAssistantPageFunc could look like this:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
static gint
|
||||
forward_page_function (gint current_page,
|
||||
gpointer data)
|
||||
{
|
||||
switch (current_page)
|
||||
{
|
||||
case 0:
|
||||
return 1;
|
||||
case 1:
|
||||
if (check_page1_data ())
|
||||
return 2;
|
||||
else
|
||||
return 3;
|
||||
case 2:
|
||||
return 3;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
<!--
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
|
||||
End:
|
||||
-->
|
@ -1,102 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<chapter id="gtk-migrating-GtkBuilder">
|
||||
|
||||
<title>Migrating from libglade to GtkBuilder</title>
|
||||
|
||||
<para>
|
||||
Since version 2.12, GTK+ provides #GtkBuilder to construct
|
||||
user interfaces from XML descriptions, similar to the functionality
|
||||
provided by #GladeXML in the libglade library.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
A good way to start a migration from libglade to GtkBuilder is using
|
||||
<application>glade3</application> to convert your .glade file.
|
||||
If your code uses the @root parameter of glade_xml_new(),
|
||||
you can use gtk_builder_add_objects_from_file() to construct only certain
|
||||
objects from a GtkBuilder file.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Alternatively, GTK+ also offers the
|
||||
<link linkend="gtk-builder-convert">gtk-builder-convert</link> script you can use
|
||||
to do the conversion; in which case you should be careful to inspect the output
|
||||
and make sure you didn't lose any data.
|
||||
</para>
|
||||
|
||||
<table pgwide="1" frame="topbot">
|
||||
<title>Step-by-step instructions for porting code from libglade to GtkBuilder</title>
|
||||
<tgroup cols="2" colsep="0" rowsep="0">
|
||||
<thead>
|
||||
<row><entry>libglade</entry><entry>GtkBuilder</entry></row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><![CDATA[#include <glade/glade.h>]]></entry>
|
||||
<entry>not needed</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><screen>GladeXML*</screen></entry>
|
||||
<entry><screen>GtkBuilder*</screen></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><screen>glade_xml_new (FILE, "first_widget", NULL)</screen></entry>
|
||||
<entry>
|
||||
<screen>
|
||||
GError* error = NULL;
|
||||
GtkBuilder* builder = gtk_builder_new (<!-- -->);
|
||||
if (!gtk_builder_add_from_file (builder, FILE, &error))
|
||||
{
|
||||
g_warning ("Couldn't load builder file: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
</screen>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><screen>glade_xml_get_widget (gxml, “widget_name”)</screen></entry>
|
||||
<entry><screen>GTK_WIDGET (gtk_builder_get_object (builder, “widget_name”))</screen></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><screen>glade_get_widget_name (widget)</screen></entry>
|
||||
<entry><screen>gtk_widget_get_name (widget)</screen></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><screen>glade_xml_get_widget_prefix (gxml, “prefix”)</screen></entry>
|
||||
<entry>can be emulated by <literal>gtk_builder_get_objects (builder)</literal> together with manual filtering. It returns a GSList* instead of a GList* though.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>
|
||||
While GtkBuilder strives to be a complete replacement for
|
||||
libglade, there are a number of areas where it is currently
|
||||
still behind libglade:
|
||||
<itemizedlist>
|
||||
|
||||
<listitem><para>
|
||||
GtkBuilder supports context information in translatable
|
||||
properties in a slightly different way than libglade.
|
||||
Intltool does not yet support this; see
|
||||
<ulink url="http://bugzilla.gnome.org/show_bug.cgi?id=454894">bug
|
||||
454894</ulink> for the current status of intltool support for
|
||||
GtkBuilder files. Thankfully, context in translations is a
|
||||
rarely used feature, and if you are not using it, intltools
|
||||
glade format support works just fine for GtkBuilder files.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
While libglade can often tolerate multiple widgets having the
|
||||
same id in a glade file, GtkBuilder will not accept duplicate
|
||||
object ids. Both <application>gtk-builder-convert</application>
|
||||
and the GtkBuilder parser emit warnings when they see
|
||||
duplicate ids.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
</chapter>
|
@ -1,54 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<chapter id="gtk-migrating-GtkColorButton">
|
||||
|
||||
<title>Migrating from GnomeColorPicker to GtkColorButton</title>
|
||||
|
||||
<para>
|
||||
Since version 2.6, GTK+ provides the #GtkColorButton
|
||||
widget as a replacement for the <structname>GnomeColorPicker</structname>
|
||||
widget in the libgnomeui library.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Porting an application from <structname>GnomeColorPicker</structname> to
|
||||
<structname>GtkColorButton</structname> is very simple.
|
||||
<structname>GtkColorButton</structname> doesn't support dithering
|
||||
(since it is rarely needed on modern hardware), and it doesn't have
|
||||
setters and getters to set the color from floating point or integer
|
||||
components. So instead of
|
||||
<informalexample><programlisting>
|
||||
guint red, green, blue, alpha;
|
||||
/* ... */
|
||||
gnome_color_picker_set_i8 (color_picker, red, green, blue, alpha);
|
||||
</programlisting></informalexample>
|
||||
you have to write
|
||||
<informalexample><programlisting>
|
||||
GdkColor color;
|
||||
|
||||
color.red = red << 8;
|
||||
color.green = green << 8;
|
||||
color.blue = blue << 8;
|
||||
gtk_color_button_set_color (color_picker, &color);
|
||||
gtk_color_button_set_alpha (color_picker, alpha << 8);
|
||||
</programlisting></informalexample>
|
||||
and similarly for the setters taking other number formats. For
|
||||
<function>gnome_color_picker_set_i16()</function> no conversion is needed,
|
||||
for <function>gnome_color_picker_set_d()</function>, you need to convert
|
||||
the color components like this:
|
||||
<informalexample><programlisting>
|
||||
color.red = (guint16) (red * 65535.0 + 0.5);
|
||||
color.green = (guint16) (green * 65535.0 + 0.5);
|
||||
color.blue = (guint16) (blue * 65535.0 + 0.5);
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
<!--
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
|
||||
End:
|
||||
-->
|
@ -1,213 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<chapter id="gtk-migrating-GtkComboBox">
|
||||
|
||||
<title>Migrating from GtkOptionMenu and GtkCombo to GtkComboBox and
|
||||
GtkComboBoxEntry</title>
|
||||
|
||||
<para>
|
||||
Prior to 2.4, GTK+ offered two widgets for the task of selecting one
|
||||
item from a list of options. #GtkOptionMenu presents the list of
|
||||
options as a menu while #GtkCombo presents them in a Windows-style list
|
||||
popup. The only difference between the two is that a #GtkCombo allows to
|
||||
manually edit the selected value, while the #GtkOptionMenu does not.
|
||||
</para>
|
||||
<para>
|
||||
In GTK+ 2.4, a unified API for list selection was introduced, with
|
||||
#GtkComboBox for the non-editable case and #GtkComboBoxEntry for the
|
||||
editable case.
|
||||
The selection of the display style — menu or list —
|
||||
is no longer done at the API level, but has been made themeable via
|
||||
the style property #GtkComboBox:appears-as-list.
|
||||
</para>
|
||||
|
||||
<section id="migrating-GtkOptionMenu">
|
||||
<title>Migrating from GtkOptionMenu to GtkComboBox</title>
|
||||
|
||||
<para>
|
||||
Here is an example of a simple, but typical use of
|
||||
#GtkOptionMenu<!---->:
|
||||
<informalexample><programlisting>
|
||||
GtkWidget *option_menu, *menu, *menu_item;
|
||||
|
||||
option_menu = gtk_option_menu_new (<!-- -->);
|
||||
menu = gtk_menu_new (<!-- -->);
|
||||
|
||||
menu_item = gtk_menu_item_new_with_label ("First Item");
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
|
||||
gtk_widget_show (menu_item);
|
||||
menu_item = gtk_menu_item_new_with_label ("Second Item");
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
|
||||
gtk_widget_show (menu_item);
|
||||
menu_item = gtk_menu_item_new_with_label ("Third Item");
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
|
||||
gtk_widget_show (menu_item);
|
||||
|
||||
gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu);
|
||||
</programlisting></informalexample>
|
||||
In order to react to the user's selection, connect to the #GtkOptionMenu::changed
|
||||
signal on the option menu and use gtk_option_menu_get_history()
|
||||
to retrieve the index of the selected item.
|
||||
</para>
|
||||
<para>
|
||||
And here is how it would be done with a #GtkComboBox<!---->:
|
||||
<informalexample><programlisting>
|
||||
GtkWidget *combo_box;
|
||||
|
||||
combo_box = gtk_combo_box_new_text (<!-- -->);
|
||||
|
||||
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), "First Item");
|
||||
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), "Second Item");
|
||||
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), "Third Item");
|
||||
</programlisting></informalexample>
|
||||
In order to react to the user's selection, connect to the
|
||||
#GtkComboBox::changed signal and use gtk_combo_box_get_active()
|
||||
to retrieve the index of the selected item.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
A slightly more complex example involving images:
|
||||
<informalexample><programlisting>
|
||||
GtkWidget *option_menu, *menu, *menu_item;
|
||||
|
||||
option_menu = gtk_option_menu_new (<!-- -->);
|
||||
menu = gtk_menu_new (<!-- -->);
|
||||
|
||||
menu_item = gtk_image_menu_item_new_with_label ("First Item");
|
||||
gtk_image_menu_item_set_image (gtk_image_new_from_pixbuf (pixbuf1));
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
|
||||
gtk_widget_show (menu_item);
|
||||
menu_item = gtk_image_menu_item_new_with_label ("Second Item");
|
||||
gtk_image_menu_item_set_image (gtk_image_new_from_pixbuf (pixbuf2));
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
|
||||
gtk_widget_show (menu_item);
|
||||
menu_item = gtk_image_menu_item_new_with_label ("Third Item");
|
||||
gtk_image_menu_item_set_image (gtk_image_new_from_pixbuf (pixbuf3));
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
|
||||
gtk_widget_show (menu_item);
|
||||
|
||||
gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu);
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
<para>
|
||||
can be done using a #GtkComboBox as follows:
|
||||
<informalexample><programlisting>
|
||||
GtkListStore *store;
|
||||
GtkTreeIter iter;
|
||||
GtkCellRenderer *renderer;
|
||||
GtkWidget *combo_box;
|
||||
|
||||
store = gtk_list_store_new (2, GDK_TYPE_PIXBUF, G_TYPE_STRING);
|
||||
|
||||
gtk_list_store_append (store, &iter);
|
||||
gtk_list_store_set (store, &iter, 0, pixbuf1, 1, "First Item", -1);
|
||||
gtk_list_store_append (store, &iter);
|
||||
gtk_list_store_set (store, &iter, 0, pixbuf2, 1, "Second Item", -1);
|
||||
gtk_list_store_append (store, &iter);
|
||||
gtk_list_store_set (store, &iter, 0, pixbuf3, 1, "Third Item", -1);
|
||||
|
||||
combo_box = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
|
||||
|
||||
renderer = gtk_cell_renderer_pixbuf_new (<!-- -->);
|
||||
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, FALSE);
|
||||
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer,
|
||||
"pixbuf", 0,
|
||||
NULL);
|
||||
|
||||
renderer = gtk_cell_renderer_text_new (<!-- -->);
|
||||
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, TRUE);
|
||||
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer,
|
||||
"text", 1,
|
||||
NULL);
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="migrating-GtkCombo">
|
||||
<title>Migrating from GtkCombo to GtkComboBoxEntry</title>
|
||||
|
||||
<para>
|
||||
Here is an example of a simple, but typical use of a #GtkCombo<!---->:
|
||||
<informalexample><programlisting>
|
||||
GtkWidget *combo;
|
||||
GList *items = NULL;
|
||||
|
||||
items = g_list_append (items, "First Item");
|
||||
items = g_list_append (items, "Second Item");
|
||||
items = g_list_append (items, "Third Item");
|
||||
|
||||
combo = gtk_combo_new (<!-- -->);
|
||||
gtk_combo_set_popdown_strings (GTK_COMBO (combo), items);
|
||||
</programlisting></informalexample>
|
||||
In order to react to the user's selection, connect to the #GtkCombo::changed
|
||||
signal on the combo and use
|
||||
<literal>gtk_entry_get_text (GTK_ENTRY (combo->entry))</literal>
|
||||
to retrieve the selected text.
|
||||
</para>
|
||||
<para>
|
||||
And here is how it would be done using #GtkComboBoxEntry<!---->:
|
||||
<informalexample><programlisting>
|
||||
combo_box = gtk_combo_box_entry_new_text (<!-- -->);
|
||||
|
||||
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), "First Item");
|
||||
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), "Second Item");
|
||||
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), "Third Item");
|
||||
</programlisting></informalexample>
|
||||
In order to react to the user's selection, connect to the #GtkComboBox::changed
|
||||
signal on the combo and use
|
||||
<literal>gtk_entry_get_text (GTK_ENTRY (GTK_BIN (combo_box)->child))</literal>
|
||||
to retrieve the selected text.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="new-features-GtkComboBox">
|
||||
<title>New features</title>
|
||||
|
||||
<para>
|
||||
The new widgets have more to offer than a mere combination of the
|
||||
features of #GtkOptionMenu and #GtkCombo. Notable new features
|
||||
include:
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>Grid mode</term>
|
||||
<listitem><para>Sometimes it is preferable to display the available
|
||||
options not in a linear list, but in a grid. A typical example
|
||||
would be a "color combo" where the individual items are small
|
||||
square color swatches. The new widgets support gridded display
|
||||
with the functions
|
||||
gtk_combo_box_set_wrap_width(),
|
||||
gtk_combo_box_set_row_span_column() and
|
||||
gtk_combo_box_set_column_span_column().
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Display of icons</term>
|
||||
<listitem><para>An often-heard complaint about #GtkOptionMenu is that
|
||||
the icons which appear in the image menu items in its menu are not
|
||||
displayed in the button showing the selected item. This limitation
|
||||
has been removed in #GtkComboBox; the selected item appears in the
|
||||
same way as the options in the popup.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Full tree model power</term>
|
||||
<listitem><para>
|
||||
Since the new widgets are built around the same models that are
|
||||
used for #GtkTreeView, all of the powerful machinery of tree models
|
||||
and cell renderers can be used.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
|
||||
<!--
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
|
||||
End:
|
||||
-->
|
@ -1,141 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<chapter id="gtk-migrating-entry-icons">
|
||||
|
||||
<title>Migrating from SexyIconEntry to GtkEntry</title>
|
||||
|
||||
<para>
|
||||
GTK+ 2.16 supports showing icons inside a #GtkEntry, similar to
|
||||
SexyIconEntry. Porting from SexyIconEntry to GtkEntry is relatively
|
||||
straightforward. The main difference between the two APIs is that
|
||||
SexyIconEntry uses #GtkImage widgets in a somewhat awkward way as
|
||||
storage vehicles for icons, while GtkEntry allows to specify icons
|
||||
via pixbufs, stock ids, icon names or #GIcons. So, if your code uses
|
||||
e.g.:
|
||||
<informalexample><programlisting>
|
||||
image = gtk_image_new_from_stock (GTK_STOCK_NEW, GTK_ICON_SIZE_MENU);
|
||||
sexy_icon_entry_set_icon (entry, SEXY_ICON_ENTRY_PRIMARY, image);
|
||||
</programlisting></informalexample>
|
||||
you can get rid of the @image, and directly write:
|
||||
<informalexample><programlisting>
|
||||
gtk_entry_set_icon_from_stock (entry, GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_NEW);
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The signals SexyIconEntry::icon-pressed and SexyIconEntry::icon-released
|
||||
have been renamed to #GtkEntry::icon-press and #GtkEntry::icon-release
|
||||
to avoid problems due to signal name clashes. Also, the signature of the
|
||||
signals has changed from
|
||||
<informalexample><programlisting>
|
||||
void (*icon_pressed) (SexyIconEntry *entry,
|
||||
SexyIconEntryPosition icon_pos,
|
||||
int button)
|
||||
</programlisting></informalexample>
|
||||
to
|
||||
<informalexample><programlisting>
|
||||
void (*icon_press) (GtkEntry *entry,
|
||||
GtkEntryIconPosition icon_pos,
|
||||
GdkEventButton *event)
|
||||
</programlisting></informalexample>
|
||||
The new signature has the advantage that the signal handler can use
|
||||
the timestamp of the event, e.g. for passing it to gtk_menu_popup().
|
||||
When adapting an existing signal handler to the new signature, you
|
||||
should note that the button number is easily available as @event->button,
|
||||
as shown in the following example:
|
||||
<informalexample><programlisting>
|
||||
static void
|
||||
icon_pressed_cb (SexyIconEntry *entry,
|
||||
SexyIconEntryPosition position,
|
||||
int button,
|
||||
gpointer data)
|
||||
{
|
||||
GtkMenu *menu = data;
|
||||
|
||||
if (position == SEXY_ICON_ENTRY_PRIMARY)
|
||||
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
|
||||
button, GDK_CURRENT_TIME);
|
||||
}
|
||||
</programlisting></informalexample>
|
||||
can be ported as:
|
||||
<informalexample><programlisting>
|
||||
static void
|
||||
icon_press_cb (GtkEntry *entry,
|
||||
GtkEntryIconPosition position,
|
||||
GdkEventButton *event,
|
||||
gpointer data)
|
||||
{
|
||||
GtkMenu *menu = data;
|
||||
|
||||
if (position == GTK_ENTRY_ICON_PRIMARY)
|
||||
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
|
||||
event->button, event->time);
|
||||
}
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Another difference is that SexyIconEntry offers manual control of
|
||||
the icon prelighting, via sexy_icon_entry_set_icon_highlight().
|
||||
#GtkEntry prelights automatically when appropriate, depending on
|
||||
whether the icon is activatable and sensitive. You should make
|
||||
sure that your icons are properly marked as activatable or nonactivatable
|
||||
and sensitive or insensitive:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
Sensitive, but non-activatable icons are
|
||||
good for purely informational purposes.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Icons should be marked as insensitive if the
|
||||
function that they trigger is currently not available.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
GtkEntry has no direct equivalent of the special-purpose function
|
||||
sexy_icon_entry_add_clear_button(). If you need this functionality,
|
||||
the following code works:
|
||||
<informalexample><programlisting>
|
||||
static void
|
||||
icon_pressed_cb (GtkEntry *entry,
|
||||
gint position,
|
||||
GdkEventButton *event,
|
||||
gpointer data)
|
||||
{
|
||||
if (position == GTK_ENTRY_ICON_SECONDARY)
|
||||
gtk_entry_set_text (entry, "");
|
||||
}
|
||||
|
||||
static void
|
||||
text_changed_cb (GtkEntry *entry,
|
||||
GParamSpec *pspec,
|
||||
GtkWidget *button)
|
||||
{
|
||||
gboolean has_text;
|
||||
|
||||
has_text = gtk_entry_get_text_length (entry) > 0;
|
||||
gtk_entry_set_icon_sensitive (entry,
|
||||
GTK_ENTRY_ICON_SECONDARY,
|
||||
has_text);
|
||||
}
|
||||
|
||||
|
||||
/* ... */
|
||||
|
||||
/* Set up the clear icon */
|
||||
gtk_entry_set_icon_from_stock (GTK_ENTRY (entry),
|
||||
GTK_ENTRY_ICON_SECONDARY,
|
||||
GTK_STOCK_CLEAR);
|
||||
g_signal_connect (entry, "icon-press",
|
||||
G_CALLBACK (icon_pressed_cb), NULL);
|
||||
g_signal_connect (entry, "notify::text",
|
||||
G_CALLBACK (text_changed_cb), find_button);
|
||||
|
||||
/* ... */
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
</chapter>
|
@ -1,163 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<chapter id="gtk-migrating-GtkFileChooser">
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Federico</firstname>
|
||||
<surname>Mena-Quintero</surname>
|
||||
<affiliation>
|
||||
<address>
|
||||
<email>federico@ximian.com</email>
|
||||
</address>
|
||||
</affiliation>
|
||||
</author>
|
||||
</chapterinfo>
|
||||
|
||||
<title>Migrating from GtkFileSelection to GtkFileChooser</title>
|
||||
|
||||
<para>
|
||||
#GtkFileChooser, starting with GTK+ 2.4, is the new set of APIs for file
|
||||
selection widgets and dialogs. Previous versions of GTK+ used #GtkFileSelection,
|
||||
which has numerous problems.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
#GtkFileChooser is an abstract interface that can be implemented by widgets
|
||||
that perform file selection tasks. Two widgets in GTK+ implement this
|
||||
interface: #GtkFileChooserDialog and #GtkFileChooserWidget. Most applications
|
||||
simply need to use #GtkFileChooserDialog, which is a dialog box that allows the
|
||||
user to select existing files for opening them, or to pick new filenames for
|
||||
saving documents. #GtkFileChooserWidget is for special applications that need to
|
||||
embed a file selection widget inside a larger window. In the context of GTK+,
|
||||
#GtkFileChooserDialog is simply a #GtkDialog box with a #GtkFileChooserWidget.
|
||||
inside.
|
||||
</para>
|
||||
|
||||
<section id="gtkfilechooser-creating">
|
||||
<title>Creating a GtkFileChooserDialog</title>
|
||||
|
||||
<para>
|
||||
To create a #GtkFileChooserDialog, you simply call gtk_file_chooser_dialog_new().
|
||||
This function is similar to gtk_dialog_new() in that it takes parameters for the
|
||||
title of the dialog box and its transient parent, as well as its
|
||||
buttons. In addition, it takes in an argument that determines
|
||||
whether the file chooser dialog will be used for opening
|
||||
existing files or for saving to a possibly new file.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Please see <xref linkend="gtkfilechooser-typical-usage"/> for
|
||||
how to create a simple file chooser dialog and extract the
|
||||
selected filename from it.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="gtkfilechooser-selection-modes">
|
||||
<title>Selection Modes</title>
|
||||
|
||||
<para>
|
||||
#GtkFileChooser can be used in two modes, to select a single file at a
|
||||
time or to select a set of more than one file. To set this, use
|
||||
gtk_file_chooser_set_select_multiple(). In single-selection
|
||||
mode, you can use gtk_file_chooser_get_filename() to get a file
|
||||
name from the local file system or gtk_file_chooser_get_uri() to
|
||||
get a full-formed URI. In multiple-selection mode, you can use
|
||||
gtk_file_chooser_get_filenames() to get a #GSList of filename strings, or
|
||||
gtk_file_chooser_get_uris() to get a list of URI strings.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Also, you can configure #GtkFileChooser to select files
|
||||
or folders. Consider a backup program that needs to let the
|
||||
user select a folder that will be backed up along with its
|
||||
subfolders. To configure whether #GtkFileChooser is used to select
|
||||
files or folders, use gtk_file_chooser_set_action(). In
|
||||
addition, this lets you configure whether the file chooser will
|
||||
be used to select existing files or folders (e.g. for
|
||||
"File/Open"), or to type in new filenames (for
|
||||
"File/Save As...").
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="gtkfilechooser-installing-preview">
|
||||
<title>Installing a Preview widget</title>
|
||||
|
||||
<para>
|
||||
Many applications need to have a preview facility within their
|
||||
file chooser dialogs. Previous to GTK+ 2.4, one needed to
|
||||
access the #GtkFileSelection widget hierarchy directly to hook in
|
||||
a preview widget. With #GtkFileChooser, there is a
|
||||
dedicated API to do this.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Please see the <link linkend="gtkfilechooser-preview">section on
|
||||
creating preview widgets</link> for more information.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="gtkfilechooser-installing-extra-widgets">
|
||||
<title>Installing Extra Widgets</title>
|
||||
|
||||
<para>
|
||||
Some applications need to install extra widgets in a file
|
||||
chooser. For example, an application may want to provide a
|
||||
toggle button to give the user the option of opening a file
|
||||
read-only.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Please see the <link linkend="gtkfilechooser-extra">section on
|
||||
creating extra widgets</link> for more information.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="gtkfilechooser-new-features">
|
||||
<title>New features</title>
|
||||
|
||||
<para>
|
||||
New features in #GtkFileChooser include the following:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Ability to select URIs rather than just local files. You
|
||||
must use a #GtkFileSystem implementation that supports this,
|
||||
for example the gnome-vfs backend.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Present a list of application-specific shortcut folders.
|
||||
For example, a paint program may want to add a shortcut for
|
||||
its <filename>/usr/share/paint_program/Clipart</filename>
|
||||
folder.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Define custom filters so that not all the files in a folder
|
||||
are listed. For example, you could filter out backup files,
|
||||
or show only image files.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
To see how to use these features, please consult the #GtkFileChooser
|
||||
reference documentation.
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
<!--
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
|
||||
End:
|
||||
-->
|
@ -1,153 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<chapter id="gtk-migrating-GtkIconView">
|
||||
|
||||
<title>Migrating from GnomeIconList to GtkIconView</title>
|
||||
|
||||
<para>
|
||||
Since version 2.6, GTK+ provides the #GtkIconView widget. It is similar in
|
||||
functionality to the <structname>GnomeIconList</structname> widget in the
|
||||
libgnomeui library, both widgets provide a way to lay out named icons in
|
||||
a grid. The distinctive feature of the GTK+ widget is that it follows the
|
||||
model-view pattern, allowing it to share the actual data (i.e. the names
|
||||
and images of the icons) with other views.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
#GtkIconView currently doesn't support some features found in
|
||||
<structname>GnomeIconList</structname>. Icons can not be positioned freely,
|
||||
the spacing is not customizable, and it is not possible to edit the names of
|
||||
icons.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To convert an application that uses <structname>GnomeIconList</structname>
|
||||
to #GtkIconView, the first step is to organize your data in a #GtkTreeModel.
|
||||
<structname>GnomeIconList</structname> lets you directly insert data with
|
||||
gnome_icon_list_insert() and gnome_icon_list_insert_pixbuf() and their
|
||||
append variants. So, if you previously had a function to fill your icon
|
||||
list similar to this one:
|
||||
<informalexample><programlisting>
|
||||
void
|
||||
fill_icon_list (GnomeIconList *icon_list)
|
||||
{
|
||||
gnome_icon_list_append (icon_list, "file1.png", "Icon 1");
|
||||
gnome_icon_list_append (icon_list, "file2.png", "Icon 2");
|
||||
|
||||
/* more icons ... */
|
||||
}
|
||||
</programlisting></informalexample>
|
||||
you will have to create a tree model, attach your icon view to it, and
|
||||
fill the model:
|
||||
<informalexample><programlisting>
|
||||
enum {
|
||||
PIXBUF_COLUMN,
|
||||
TEXT_COLUMN,
|
||||
|
||||
/* you can have more columns here, e.g */
|
||||
|
||||
DATA_COLUMN
|
||||
};
|
||||
|
||||
void
|
||||
fill_model (GtkListStore *store)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
gtk_list_store_append (store, &iter);
|
||||
pixbuf = gdk_pixbuf_new_from_file ("file1.png", NULL);
|
||||
gtk_list_store_set (store, &iter, PIXBUF_COLUMN, pixbuf, TEXT_COLUMN, "Icon 1", -1);
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
gtk_list_store_append (store, &iter);
|
||||
pixbuf = gdk_pixbuf_new_from_file ("file2.png", NULL);
|
||||
gtk_list_store_set (store, &iter, PIXBUF_COLUMN, pixbuf, TEXT_COLUMN, "Icon 2", -1);
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
/* more icons ... */
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GtkWidget *icon_view;
|
||||
GtkListStore *store;
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
/* do other initialization... */
|
||||
|
||||
/* construct the GtkIconView */
|
||||
icon_view = gtk_icon_view_new (<!-- -->);
|
||||
store = gtk_list_store_new (3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER);
|
||||
|
||||
gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (icon_view), PIXBUF_COLUMN);
|
||||
gtk_icon_view_set_text_column (GTK_ICON_VIEW (icon_view), TEXT_COLUMN);
|
||||
gtk_icon_view_set_model (GTK_ICON_VIEW (icon_view), GTK_TREE_MODEL (store));
|
||||
|
||||
fill_model (store);
|
||||
|
||||
/* ... */
|
||||
}
|
||||
</programlisting></informalexample>
|
||||
This example uses a #GtkListStore as model, but part of the elegance of the
|
||||
model-view pattern is that you can easily use another tree model implementation,
|
||||
or even write your own custom tree model.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Your application may make use of extra data attached to the icons in the
|
||||
<structname>GnomeIconList</structname> via gnome_icon_list_set_icon_data() and
|
||||
gnome_icon_list_get_icon_data(). With #GtkIconView such data is most
|
||||
conveniently stored in an extra column in the tree model, so you would
|
||||
call a function like
|
||||
<informalexample><programlisting>
|
||||
void
|
||||
set_icon_data (GtkIconView *icon_view,
|
||||
gint idx,
|
||||
gpointer data)
|
||||
{
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
|
||||
model = gtk_icon_view_get_model (icon_view);
|
||||
|
||||
if (gtk_tree_model_iter_nth_child (model, &iter, NULL, idx))
|
||||
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
|
||||
DATA_COLUMN, data, -1);
|
||||
}
|
||||
</programlisting></informalexample>
|
||||
assuming that your tree model has a <literal>DATA_COLUMN</literal> of type
|
||||
%G_TYPE_POINTER.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
There is a number of minor API differences between
|
||||
<structname>GnomeIconList</structname> and
|
||||
<structname>GtkIconView</structname>:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
<type>GnomeIconListMode</type> is replaced by the
|
||||
<link linkend="GtkIconView--orientation">orientation</link>
|
||||
property of <structname>GtkIconView</structname>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<structname>GtkIconView</structname> can not be frozen in the same
|
||||
way as <structname>GnomeIconList</structname> can with
|
||||
gnome_icon_list_freeze() and gnome_icon_list_thaw(). Instead you can
|
||||
replace the whole model of a <structname>GtkIconView</structname>,
|
||||
instead of doing many small changes to the existing model.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
<!--
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
|
||||
End:
|
||||
-->
|
@ -1,24 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<chapter id="gtk-migrating-label-links">
|
||||
|
||||
<title>Migrating from SexyUrlLabel to GtkLabel</title>
|
||||
|
||||
<para>
|
||||
GTK+ 2.18 supports showing links inside a #GtkLabel, similar to
|
||||
SexyUrlLabel. Porting from SexyUrlLabel to GtkLabel is relatively
|
||||
straightforward. GtkLabel accepts links in the markup using the
|
||||
same HTML <tag>a</tag> notation that SexyUrlLabel uses. In addition
|
||||
to the href attribute, GtkLabel accepts a title attribute that
|
||||
is displayed as a tooltip on the link. Instead of
|
||||
sexy_url_label_set_markup(), just call gtk_label_set_markup().
|
||||
</para>
|
||||
<para>
|
||||
One difference between the two APIs is that the ::url-activated signal
|
||||
from SexyUrlLabel has been replaced by the #GtkLabel::activate-link
|
||||
signal. The need for connecting to this signal is greatly reduced,
|
||||
since GtkLabel has a default handler that calls gtk_show_uri().
|
||||
</para>
|
||||
</chapter>
|
@ -1,81 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<chapter id="gtk-migrating-GtkLinkButton">
|
||||
|
||||
<title>Migrating from GnomeHRef to GtkLinkButton</title>
|
||||
|
||||
<para>
|
||||
Since version 2.10, GTK+ provides the #GtkLinkButton widget as a
|
||||
replacement for the <structname>GnomeHRef</structname> widget
|
||||
in the libgnomeui library.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Porting an application from <structname>GnomeHRef</structname> to
|
||||
#GtkLinkButton is very simple. #GtkLinkButton does not have a
|
||||
default action for #GtkButton::clicked signal. So instead of simply
|
||||
creating the widget
|
||||
<informalexample><programlisting>
|
||||
GtkWidget *button;
|
||||
|
||||
button = gnome_href_new (url, "");
|
||||
</programlisting></informalexample>
|
||||
you will have to handle the activation of the #GtkLinkButton, using
|
||||
the ::clicked signal for instance
|
||||
<informalexample><programlisting>
|
||||
static void
|
||||
link_button_clicked_cb (GtkWidget *widget,
|
||||
gpointer data)
|
||||
{
|
||||
const gchar *link;
|
||||
|
||||
link = gtk_link_button_get_uri (GTK_LINK_BUTTON (widget));
|
||||
open_browser_at_url (link);
|
||||
}
|
||||
|
||||
/* ... */
|
||||
|
||||
GtkWidget *button;
|
||||
|
||||
button = gtk_link_button_new (url);
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (link_button_clicked_cb), NULL);
|
||||
</programlisting></informalexample>
|
||||
If you have more than one #GtkLinkButton instead of connecting
|
||||
a signal to each one, you can use a "hook function" which will be
|
||||
called whenever a user activates a link button
|
||||
<informalexample><programlisting>
|
||||
static void
|
||||
link_button_hook (GtkLinkButton *button,
|
||||
const gchar *link,
|
||||
gpointer user_data)
|
||||
|
||||
{
|
||||
open_browser_at_url (link);
|
||||
}
|
||||
|
||||
/* ... */
|
||||
|
||||
GtkWidget *button1 = gtk_link_button_new (uri1);
|
||||
GtkWidget *button2 = gtk_link_button_new (uri2);
|
||||
|
||||
gtk_link_button_set_uri_hook (link_button_hook, NULL, NULL);
|
||||
</programlisting></informalexample>
|
||||
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Starting with GTK+ 2.16, it is no longer necessary to set up a uri hook
|
||||
manually, since GTK+ now defaults to calling gtk_show_uri() if no uri
|
||||
hook has been set.
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
<!--
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
|
||||
End:
|
||||
-->
|
@ -1,323 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<chapter id="gtk-migrating-GtkRecentChooser">
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Emmanuele</firstname>
|
||||
<lastname>Bassi</lastname>
|
||||
<affiliation>
|
||||
<address>
|
||||
<email>ebassi@gmail.com</email>
|
||||
</address>
|
||||
</affiliation>
|
||||
</author>
|
||||
</chapterinfo>
|
||||
|
||||
<title>Migrating from EggRecent to GtkRecentChooser</title>
|
||||
|
||||
<para>
|
||||
Since version 2.10, GTK+ provides a way of handling the recently used
|
||||
documents. It is similar to the code that has lived inside the libegg
|
||||
library and has been incorporated by many applications. The GTK+ version
|
||||
aims to completely replace that code, and offers many distinctive features
|
||||
that improve the registration and visualization of the recently used
|
||||
documents, such as:
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
Better performances while reading and writing the list of recently used
|
||||
files
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
More meta-data available for each recent document, like the
|
||||
applications that have registered a document inside the list, the last
|
||||
time and the number of times the same application did register a
|
||||
document inside the list, an optional user readable name and
|
||||
description of the document
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Improved the ability to sort and filter the documents, also using
|
||||
custom sorting and filtering functions
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
New widgets for displaying the list, and better integration with
|
||||
current #GtkFileChooser and #GtkUIManager widgets
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<section id="gtkrecent-manager">
|
||||
<title>Managing the Recently Used Documents</title>
|
||||
|
||||
<para>
|
||||
#GtkRecentManager is used to manage the Recently Used Documents. To
|
||||
create a new #GtkRecentManager, you simply call gtk_recent_manager_new().
|
||||
Like the <structname>EggRecentModel</structname> inside EggRecent, the
|
||||
#GtkRecentManager loads the list of the recent documents and notifies
|
||||
you of changes inside the list.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Usually, instead of creating a new #GtkRecentManager each time you
|
||||
need it, you'll want to use the gtk_recent_manager_get_default()
|
||||
function.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To add a document to the list, you can use gtk_recent_manager_add_item(),
|
||||
like:
|
||||
<informalexample><programlisting>
|
||||
GtkRecentManager *manager;
|
||||
|
||||
manager = gtk_recent_manager_new (<!-- -->);
|
||||
|
||||
if (!gtk_recent_manager_add_item (manager, document_uri))
|
||||
{
|
||||
/* warn about the error */
|
||||
}
|
||||
|
||||
g_object_unref (manager);
|
||||
</programlisting></informalexample>
|
||||
The gtk_recent_manager_add_item() function will try and guess some of the
|
||||
meta-data associated to a URI. If you know some of meta-data about the
|
||||
document yourself, set the desired fields of a #GtkRecentData structure
|
||||
and pass it to the gtk_recent_manager_add_full() function instead:
|
||||
<informalexample><programlisting>
|
||||
GtkRecentManager *manager;
|
||||
GtkRecentData *recent_data;
|
||||
|
||||
manager = gtk_recent_manager_new (<!-- -->);
|
||||
|
||||
recent_data = g_new0 (GtkRecentData, 1);
|
||||
/* the user visible name of the document (maybe its title); should
|
||||
* be preferred when displaying the item into the list
|
||||
*/
|
||||
recent_data->display_name = document_name;
|
||||
|
||||
/* the MIME type is mandatory */
|
||||
recent_data->mime_type = document_mime_type;
|
||||
|
||||
/* the name of the application that is registering the document
|
||||
* (also mandatory); usually, the same name you used with
|
||||
* the g_set_application_name (<!-- -->) function.
|
||||
*/
|
||||
recent_data-&app_name = APP_NAME;
|
||||
|
||||
/* the command to open a file; the %u string will be automagically
|
||||
* expanded to the document's URI when getting the application's
|
||||
* command line from the GtkRecentInfo object with
|
||||
* gtk_recent_info_get_application_info (<!-- -->)
|
||||
*/
|
||||
recent_data-&app_exec = g_strjoin (" ", g_get_prgname (<!-- -->), "--open-file", "%u", NULL);
|
||||
|
||||
if (!gtk_recent_manager_add_full (manager, document_uri, recent_data))
|
||||
{
|
||||
/* warn about the error */
|
||||
}
|
||||
|
||||
g_free (recent_data->app_exec);
|
||||
g_free (recent_data);
|
||||
g_object_unref (manager);
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Getting the list of items is also similar to
|
||||
<structname>EggRecentModel</structname>; the GtkRecentInfo data is
|
||||
allocated at look up time in order not to waste memory keeping it
|
||||
around, so you must remember to free the data inside the list and then
|
||||
the list itself when you are done using it:
|
||||
<informalexample><programlisting>
|
||||
GtkRecentManager *manager;
|
||||
GList *recent_items, *l;
|
||||
|
||||
manager = gtk_recent_manager_get_default(<!-- -->);
|
||||
|
||||
recent_items = gtk_recent_manager_get_items (manager);
|
||||
for (l = recent_items; l != NULL; l = l->next)
|
||||
{
|
||||
GtkRecentInfo *recent_info = l->data;
|
||||
|
||||
do_something_with_the_item (recent_info);
|
||||
}
|
||||
|
||||
/* free everything and the list */
|
||||
g_list_foreach (recent_items, (GFunc) gtk_recent_info_unref, NULL);
|
||||
g_list_free (recent_items);
|
||||
</programlisting></informalexample>
|
||||
You can also look up a single item:
|
||||
<informalexample><programlisting>
|
||||
GtkRecentInfo *recent_info;
|
||||
GError *error = NULL;
|
||||
|
||||
recent_info = gtk_recent_manager_lookup_item (manager, document_uri, &error);
|
||||
if (error)
|
||||
{
|
||||
display_error (error);
|
||||
|
||||
g_error_free (error);
|
||||
}
|
||||
else
|
||||
{
|
||||
do_something_with_the_item (recent_info);
|
||||
|
||||
gtk_recent_info_unref (recent_info);
|
||||
}
|
||||
</programlisting></informalexample>
|
||||
The #GtkRecentInfo is a reference counted boxed type, and it holds all
|
||||
the meta-data of a recently used document, like its display name, its
|
||||
description, the list of each application that has registered the
|
||||
document or the list of groups to which the document belong.
|
||||
</para>
|
||||
|
||||
</section> <!-- gtkrecent-manager -->
|
||||
|
||||
<section id="gtkrecent-chooser">
|
||||
<title>Displaying the Recently Used Documents</title>
|
||||
|
||||
<para>
|
||||
Displaying the Recently Used Documents list is handled by any widget
|
||||
implementing the #GtkRecentChooser interface. These widgets also handle
|
||||
the sorting and filtering of the list; they will create their own
|
||||
#GtkRecentManager objects by default:
|
||||
<informalexample><programlisting>
|
||||
GtkWidget *chooser;
|
||||
gint response;
|
||||
|
||||
/* create a new dialog with the recently used documents list shown
|
||||
* using a GtkTreeView widget
|
||||
*/
|
||||
chooser = gtk_recent_chooser_dialog_new ("Recent Documents",
|
||||
parent_window,
|
||||
GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_OK,
|
||||
NULL);
|
||||
/* set the sorting order to "most recently used first" */
|
||||
gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (chooser), GTK_RECENT_SORT_MRU);
|
||||
response = gtk_dialog_run (GTK_DIALOG (chooser));
|
||||
if (response == GTK_RESPONSE_OK)
|
||||
{
|
||||
GtkRecentInfo *info;
|
||||
|
||||
info = gtk_recent_chooser_get_current_item (GTK_RECENT_CHOOSER (chooser));
|
||||
do_something_with_the_item (info);
|
||||
|
||||
gtk_recent_info_unref (info);
|
||||
}
|
||||
|
||||
gtk_widget_destroy (chooser);
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
</section> <!-- gtkrecent-chooser -->
|
||||
|
||||
<section id="gtkrecent-advanced">
|
||||
<title>Advanced usage</title>
|
||||
|
||||
<para>
|
||||
The #GtkRecentChooser widgets might display items sorted and filtered,
|
||||
either with already supplied or custom sorting and filtering functions.
|
||||
The biggest difference from the <structname>EggRecentView</structname>
|
||||
widgets in EggRecent is that the #GtkRecentChooser widgets will use
|
||||
their own copy of the list and will apply the sorting and filtering
|
||||
functions only on the copy; this allows the creation of many viewers
|
||||
with a single controller, like using many #GtkTreeView with a single
|
||||
#GtkTreeModel instance.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Available sorting methods are:
|
||||
<informalexample><programlisting>
|
||||
/* no sorting */
|
||||
gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (chooser), GTK_RECENT_SORT_NONE);
|
||||
|
||||
/* most recently used first */
|
||||
gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (chooser), GTK_RECENT_SORT_MRU);
|
||||
|
||||
/* most recently used last */
|
||||
gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (chooser), GTK_RECENT_SORT_LRU);
|
||||
</programlisting></informalexample>
|
||||
You can create your own sorting function, and the use the
|
||||
GTK_RECENT_SORT_CUSTOM method:
|
||||
<informalexample><programlisting>
|
||||
/* custom sorting function, based on the registration count
|
||||
* (most used first)
|
||||
*/
|
||||
static void
|
||||
sort_by_usage_count (GtkRecentInfo *a,
|
||||
GtkRecentInfo *b,
|
||||
gpointer data)
|
||||
{
|
||||
gint count_a, count_b;
|
||||
|
||||
count_a = count_b = 0;
|
||||
|
||||
if (gtk_recent_info_has_application (a, APP_NAME))
|
||||
gtk_recent_info_get_application_info (a, APP_NAME, NULL, &count_a, NULL);
|
||||
|
||||
if (gtk_recent_info_has_application (b, APP_NAME))
|
||||
gtk_recent_info_get_application_info (b, APP_NAME, NULL, &count_b, NULL);
|
||||
|
||||
return count_a < count_b;
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
/* set custom sorting and set the custom sorting function */
|
||||
gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (chooser),
|
||||
GTK_RECENT_SORT_CUSTOM);
|
||||
gtk_recent_chooser_set_sort_func (GTK_RECENT_CHOOSER,
|
||||
sort_by_usage_count,
|
||||
NULL, /* sort function data */
|
||||
NULL /* destroy notify for the data */);
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Filtering is done using the #GtkRecentFilter object, similar to the
|
||||
#GtkFileFilter object used by the #GtkFileChooser widgets. The
|
||||
#GtkRecentFilter object has a set of pre-defined options based on the
|
||||
meta-data exposed by the #GtkRecentInfo object. It also allows custom
|
||||
filtering function:
|
||||
<informalexample><programlisting>
|
||||
GtkRecentFilter *filter;
|
||||
|
||||
filter = gtk_recent_filter_new (<!-- -->);
|
||||
|
||||
/* set the user visible name of the filter */
|
||||
gtk_recent_filter_set_name (filter, "Since Last Month");
|
||||
|
||||
/* set the maximum age of a recently used document */
|
||||
gtk_recent_filter_set_age (filter, 31);
|
||||
|
||||
/* the chooser takes the ownership of the object */
|
||||
gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (chooser), filter);
|
||||
|
||||
/* set the currently used filter */
|
||||
gtk_recent_chooser_set_filter (GTK_RECENT_CHOOSER (chooser), filter);
|
||||
|
||||
filter = gtk_recent_filter_new (<!-- -->);
|
||||
gtk_recent_filter_set_name (filter, "Every text file");
|
||||
gtk_recent_filter_set_mime_type (filter, "text/plain");
|
||||
|
||||
gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (chooser), filter);
|
||||
</programlisting></informalexample>
|
||||
The #GtkRecentChooserWidget and #GtkRecentChooserDialog widgets allow
|
||||
multiple filters and the selection of an appropriate one; the
|
||||
#GtkRecentChooserMenu widget allows just a single filter object.
|
||||
</para>
|
||||
|
||||
</section> <!-- gtkrecent-advanced -->
|
||||
|
||||
</chapter>
|
||||
|
||||
<!--
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
|
||||
End:
|
||||
-->
|
@ -1,66 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<chapter id="gtk-migrating-tooltips">
|
||||
|
||||
<title>Migrating from GtkTooltips to GtkTooltip</title>
|
||||
|
||||
<para>
|
||||
GTK+ 2.12 brings a completely new tooltip implementation which
|
||||
allows many things that were not possible with the old
|
||||
#GtkTooltips interface. The new possibilities are explained
|
||||
in more detail in the section about #GtkTooltip.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
A number of complications of the old API have been removed:
|
||||
<itemizedlist>
|
||||
|
||||
<listitem><para>
|
||||
Tooltips can not be grouped anymore. The old tooltips
|
||||
API allowed this by using multiple #GtkTooltips objects.
|
||||
We believe that the timeout behaviour of the new tooltips
|
||||
implementation is better and makes it unnecessary to use
|
||||
grouping as a way to overcome shortcomings of the
|
||||
fast-tooltips mode.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Timeouts can not be set individually anymore. Instead
|
||||
there are settings #GtkSettings:gtk-tooltip-timeout,
|
||||
#GtkSettings:gtk-tooltip-browse-timeout and
|
||||
#GtkSettings:gtk-tooltip-browse-mode-timeout to influence
|
||||
the behaviour of tooltips globally.
|
||||
</para></listitem>
|
||||
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Here is an example of setting a tooltip on a widget with the old API:
|
||||
<informalexample><programlisting>
|
||||
GtkTooltips *tooltips = gtk_tooltips_new ();
|
||||
gtk_tooltips_set_tip (tooltips, widget, "Some tips", NULL);
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
<para>
|
||||
Using the new tooltips API, it is no longer necessary to create
|
||||
an object:
|
||||
<informalexample><programlisting>
|
||||
gtk_widget_set_tooltip_text (widget, "Some tips");
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
<para>
|
||||
Similarly, setting a tooltip on a #GtkToolItem gets
|
||||
simplified from
|
||||
<informalexample><programlisting>
|
||||
gtk_tool_item_set_tooltip (toolitem, toolbar->tooltips, "tool tip", NULL);
|
||||
</programlisting></informalexample>
|
||||
to
|
||||
<informalexample><programlisting>
|
||||
gtk_tool_item_set_tooltip_text (toolitem, text);
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
</chapter>
|
Loading…
Reference in New Issue
Block a user