mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-24 12:41:16 +00:00
cleanups
Mon Aug 26 12:21:16 BST 2002 Tony Gale <gale@gtk.org> * docs/tutorial/package-db-tutorial.sh: cleanups * docs/tutorial/gtk-tut.sgml: new content for the ItemFactory section. Originally from Robert Cleaver Ancell.
This commit is contained in:
parent
7049e0cb59
commit
5abc7156b6
@ -1,3 +1,10 @@
|
||||
Mon Aug 26 12:21:16 BST 2002 Tony Gale <gale@gtk.org>
|
||||
|
||||
* docs/tutorial/package-db-tutorial.sh: cleanups
|
||||
|
||||
* docs/tutorial/gtk-tut.sgml: new content for the
|
||||
ItemFactory section. Originally from Robert Cleaver Ancell.
|
||||
|
||||
2002-08-25 Tor Lillqvist <tml@iki.fi>
|
||||
|
||||
* gtk/gtkfilesel.c: Don't include <winsock.h> on Cygwin (#91654,
|
||||
|
@ -1,3 +1,10 @@
|
||||
Mon Aug 26 12:21:16 BST 2002 Tony Gale <gale@gtk.org>
|
||||
|
||||
* docs/tutorial/package-db-tutorial.sh: cleanups
|
||||
|
||||
* docs/tutorial/gtk-tut.sgml: new content for the
|
||||
ItemFactory section. Originally from Robert Cleaver Ancell.
|
||||
|
||||
2002-08-25 Tor Lillqvist <tml@iki.fi>
|
||||
|
||||
* gtk/gtkfilesel.c: Don't include <winsock.h> on Cygwin (#91654,
|
||||
|
@ -1,3 +1,10 @@
|
||||
Mon Aug 26 12:21:16 BST 2002 Tony Gale <gale@gtk.org>
|
||||
|
||||
* docs/tutorial/package-db-tutorial.sh: cleanups
|
||||
|
||||
* docs/tutorial/gtk-tut.sgml: new content for the
|
||||
ItemFactory section. Originally from Robert Cleaver Ancell.
|
||||
|
||||
2002-08-25 Tor Lillqvist <tml@iki.fi>
|
||||
|
||||
* gtk/gtkfilesel.c: Don't include <winsock.h> on Cygwin (#91654,
|
||||
|
@ -1,3 +1,10 @@
|
||||
Mon Aug 26 12:21:16 BST 2002 Tony Gale <gale@gtk.org>
|
||||
|
||||
* docs/tutorial/package-db-tutorial.sh: cleanups
|
||||
|
||||
* docs/tutorial/gtk-tut.sgml: new content for the
|
||||
ItemFactory section. Originally from Robert Cleaver Ancell.
|
||||
|
||||
2002-08-25 Tor Lillqvist <tml@iki.fi>
|
||||
|
||||
* gtk/gtkfilesel.c: Don't include <winsock.h> on Cygwin (#91654,
|
||||
|
@ -1,3 +1,10 @@
|
||||
Mon Aug 26 12:21:16 BST 2002 Tony Gale <gale@gtk.org>
|
||||
|
||||
* docs/tutorial/package-db-tutorial.sh: cleanups
|
||||
|
||||
* docs/tutorial/gtk-tut.sgml: new content for the
|
||||
ItemFactory section. Originally from Robert Cleaver Ancell.
|
||||
|
||||
2002-08-25 Tor Lillqvist <tml@iki.fi>
|
||||
|
||||
* gtk/gtkfilesel.c: Don't include <winsock.h> on Cygwin (#91654,
|
||||
|
@ -1,3 +1,10 @@
|
||||
Mon Aug 26 12:21:16 BST 2002 Tony Gale <gale@gtk.org>
|
||||
|
||||
* docs/tutorial/package-db-tutorial.sh: cleanups
|
||||
|
||||
* docs/tutorial/gtk-tut.sgml: new content for the
|
||||
ItemFactory section. Originally from Robert Cleaver Ancell.
|
||||
|
||||
2002-08-25 Tor Lillqvist <tml@iki.fi>
|
||||
|
||||
* gtk/gtkfilesel.c: Don't include <winsock.h> on Cygwin (#91654,
|
||||
|
@ -5,7 +5,7 @@
|
||||
<book id="gtk-tut">
|
||||
|
||||
<bookinfo>
|
||||
<date>August 24, 2002</date>
|
||||
<date>August 26, 2002</date>
|
||||
<title>GTK+ 2.0 Tutorial</title>
|
||||
<authorgroup>
|
||||
<author>
|
||||
@ -8586,6 +8586,326 @@ table, bind keys to menu functions.</para>
|
||||
<para>Now that we've shown you the hard way, here's how you do it using the
|
||||
gtk_item_factory calls.</para>
|
||||
|
||||
<para>ItemFactory creates a menu out of an array of ItemFactory entries. This
|
||||
means you can define your menu in its simplest form and then create the
|
||||
menu/menubar widgets with a minimum of function calls.</para>
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect2 id="sec-ItemFactoryEntries">
|
||||
<title>ItemFactory entries</title>
|
||||
|
||||
<para>At the core of ItemFactory is the ItemFactoryEntry. This structure defines
|
||||
one menu item, and when an array of these entries is defined a whole
|
||||
menu is formed. The ItemFactory entry struct definition looks like this:</para>
|
||||
|
||||
<programlisting role="C">
|
||||
struct _GtkItemFactoryEntry
|
||||
{
|
||||
gchar *path;
|
||||
gchar *accelerator;
|
||||
|
||||
GtkItemFactoryCallback callback;
|
||||
guint callback_action;
|
||||
|
||||
gchar *item_type;
|
||||
};
|
||||
</programlisting>
|
||||
|
||||
<para>Each field defines part of the menu item.</para>
|
||||
|
||||
<para><literal>*path</literal> is a string which defines both the name and the
|
||||
path of a menu item, for example, "/File/Open" would be the name of a menu
|
||||
item which would come under the ItemFactory entry with path "/File". Note however
|
||||
that "/File/Open" would be displayed in the File menu as "Open". Also note
|
||||
since the forward slashes are used to define the path of the menu,
|
||||
they cannot be used as part of the name. A letter preceded by an underscore
|
||||
indicates an accelerator (shortcut) key once the menu is open.</para>
|
||||
|
||||
<para>
|
||||
<literal>*accelerator</literal> is a string that indicates a key combination
|
||||
that can be used as a shortcut to that menu item. The string can be made up
|
||||
of either a single character, or a combination of modifier keys with a single
|
||||
character. It is case insensitive.</para>
|
||||
|
||||
|
||||
<para>The available modifier keys are:</para>
|
||||
|
||||
<programlisting role="C">
|
||||
"<ALT> - alt
|
||||
"<CTL>" or "<CTRL>" or "<CONTROL>" - control
|
||||
"<MOD1>" to "<MOD5>" - modn
|
||||
"<SHFT>" or "<SHIFT>" - shift
|
||||
</programlisting>
|
||||
|
||||
<para>Examples:</para>
|
||||
<programlisting role="C">
|
||||
"<ConTroL>a"
|
||||
"<SHFT><ALT><CONTROL>X"
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
<literal>callback</literal> is the function that is called when the menu item
|
||||
emits the "activate" signal. The form of the callback is described
|
||||
in the <link linkend="sec-ItemFactoryCallback">Callback Description</link>
|
||||
section.</para>
|
||||
|
||||
<para>
|
||||
The value of <literal>callback_action</literal> is passed to the callback
|
||||
function. It also affects the function prototype, as shown
|
||||
in the <link linkend="sec-ItemFactoryCallback">Callback Description</link>
|
||||
section.</para>
|
||||
|
||||
<para>
|
||||
<literal>item_type</literal> is a string that defines what type of widget is
|
||||
packed into the menu items container. It can be:</para>
|
||||
|
||||
<programlisting role="C">
|
||||
NULL or "" or "<Item>" - create a simple item
|
||||
"<Title>" - create a title item
|
||||
"<CheckItem>" - create a check item
|
||||
"<ToggleItem>" - create a toggle item
|
||||
"<RadioItem>" - create a (root) radio item
|
||||
"Path" - create a sister radio item
|
||||
"<Tearoff>" - create a tearoff
|
||||
"<Separator>" - create a separator
|
||||
"<Branch>" - create an item to hold submenus (optional)
|
||||
"<LastBranch>" - create a right justified branch
|
||||
</programlisting>
|
||||
|
||||
<para>Note that <LastBranch> is only useful for one submenu of
|
||||
a menubar.</para>
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect3 id="sec-ItemFactoryCallback">
|
||||
<title>Callback Description</title>
|
||||
|
||||
<para>
|
||||
The callback for an ItemFactory entry can take two forms. If
|
||||
<literal>callback_action</literal> is zero, it is of the following
|
||||
form:</para>
|
||||
|
||||
<programlisting role="C">
|
||||
void callback(void)
|
||||
</programlisting>
|
||||
|
||||
<para>otherwise it is of the form:</para>
|
||||
|
||||
<programlisting role="C">
|
||||
void callback(gpointer callback_data,
|
||||
guint callback_action,
|
||||
GtkWidget *widget)
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
<literal>callback_data</literal> is a pointer to an arbitrary piece of data and
|
||||
is set during the call to gtk_item_factory_create_items().</para>
|
||||
|
||||
<para>
|
||||
<literal>callback_action</literal> is the same value as
|
||||
<literal>callback_action</literal> in the ItemFactory entry.</para>
|
||||
|
||||
<para>
|
||||
<literal>*widget</literal> is a pointer to a menu item widget
|
||||
(described in <link linkend="sec-ManualMenuCreation">Manual Menu Creation</link>).
|
||||
</para>
|
||||
</sect3>
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect3 id="sec-ItemFactoryEntryExamples">
|
||||
<title>ItemFactory entry examples</title>
|
||||
|
||||
<para>Creating a simple menu item:</para>
|
||||
|
||||
<programlisting role="C">
|
||||
GtkItemFactoryEntry entry = {"/_File/_Open...", "<CTRL>O", print_hello,
|
||||
0, "<Item>"};
|
||||
</programlisting>
|
||||
|
||||
<para>This will define a new simple menu entry "/File/Open" (displayed as "Open"),
|
||||
under the menu entry "/File". It has the accelerator (shortcut) control+'O'
|
||||
that when clicked calls the function print_hello(). print_hello() is of
|
||||
the form <literal>void print_hello(void)</literal> since the callback_action
|
||||
field is zero. When displayed the 'O' in "Open" will be underlined and if the
|
||||
menu item is visible on the screen pressing 'O' will activate the item. Note
|
||||
that "File/_Open" could also have been used as the path instead of
|
||||
"/_File/_Open".</para>
|
||||
|
||||
<para>Creating an entry with a more complex callback:</para>
|
||||
|
||||
<programlisting role="C">
|
||||
GtkItemFactoryEntry entry = {"/_View/Display _FPS", NULL, print_state,
|
||||
7,"<CheckItem>"};
|
||||
</programlisting>
|
||||
|
||||
<para>This defines a new menu item displayed as "Display FPS" which is under
|
||||
the menu item "View". When clicked the function print_state() will be called.
|
||||
Since <literal>callback_action</literal> is not zero print_state() is of the
|
||||
form:</para>
|
||||
|
||||
<programlisting role="C">
|
||||
void print_state(gpointer callback_data,
|
||||
guint callback_action,
|
||||
GtkWidget *widget)
|
||||
</programlisting>
|
||||
|
||||
<para>with <literal>callback_action</literal> equal to 7.</para>
|
||||
|
||||
<para>Creating a radio button set:</para>
|
||||
|
||||
<programlisting role="C">
|
||||
GtkItemFactoryEntry entry1 = {"/_View/_Low Resolution", NULL, change_resolution,
|
||||
1, "<RadioButton>"};
|
||||
GtkItemFactoryEntry entry2 = {"/_View/_High Resolution", NULL, change_resolution,
|
||||
2, "/View/Low Resolution"};
|
||||
</programlisting>
|
||||
|
||||
<para><literal>entry1</literal> defines a lone radio button that when toggled
|
||||
calls the function change_resolution() with the parameter
|
||||
<literal>callback_action</literal> equal to 1. change_resolution() is of
|
||||
the form:</para>
|
||||
|
||||
<programlisting role="C">
|
||||
void change_resolution(gpointer callback_data,
|
||||
guint callback_action,
|
||||
GtkWidget *widget)
|
||||
</programlisting>
|
||||
|
||||
<para><literal>entry2</literal> defines a radio button that belongs to the
|
||||
radio group that entry1 belongs to. It calls the same function when toggled
|
||||
but with the parameter <literal>callback_action</literal> equal to 2. Note that
|
||||
the item_type of <literal>entry2</literal> is the path of entry1
|
||||
<emphasis>without</emphasis> the accelerators ('_'). If another radio button was
|
||||
required in the same group then it would be defined in the same way as
|
||||
<literal>entry2</literal> was with its <literal>item_type</literal> again
|
||||
equal to "/View/Low Resolution".</para>
|
||||
</sect3>
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect3 id="sec-ItemFactoryEntryArrays">
|
||||
<title>ItemFactoryEntry Arrays</title>
|
||||
|
||||
<para>An ItemFactoryEntry on it's own however isn't useful. An array of
|
||||
entries is what's required to define a menu. Below is an example of how
|
||||
you'd declare this array.</para>
|
||||
|
||||
<programlisting role="C">
|
||||
static GtkItemFactoryEntry entries[] = {
|
||||
{ "/_File", NULL, NULL, 0, "<Branch>" },
|
||||
{ "/File/tear1", NULL, NULL, 0, "<Tearoff>" },
|
||||
{ "/File/_New", "<CTRL>N", new_file, 1, "<Item>" },
|
||||
{ "/File/_Open...", "<CTRL>O", open_file, 1, "<Item>" },
|
||||
{ "/File/sep1", NULL, NULL, 0, "<Seperator>" },
|
||||
{ "/File/_Quit", "<CTRL>Q", quit_program, 0, "<Item>"} };
|
||||
</programlisting>
|
||||
</sect3>
|
||||
</sect2>
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect2 id="sec-ItemFactoryCreation">
|
||||
<title>Creating an ItemFactory</title>
|
||||
|
||||
<para>An array of GtkItemFactoryEntry items defines a menu. Once this
|
||||
array is defined then the item factory can be created. The function that
|
||||
does this is:</para>
|
||||
|
||||
<programlisting role="C">
|
||||
GtkItemFactory* gtk_item_factory_new( GtkType container_type,
|
||||
const gchar *path,
|
||||
GtkAccelGroup *accel_group );
|
||||
</programlisting>
|
||||
|
||||
<para><literal>container_type</literal> can be one of:</para>
|
||||
|
||||
<programlisting role="C">
|
||||
GTK_TYPE_MENU
|
||||
GTK_TYPE_MENU_BAR
|
||||
GTK_TYPE_OPTION_MENU
|
||||
</programlisting>
|
||||
|
||||
<para><literal>container_type</literal> defines what type of menu
|
||||
you want, so when you extract it later it is either a menu (for pop-ups
|
||||
for instance), a menu bar, or an option menu (like a combo box but with
|
||||
a menu of pull downs).</para>
|
||||
|
||||
<para><literal>path</literal> defines the path of the root of the menu.
|
||||
Basically it is a unique name for the root of the menu, it must be
|
||||
surrounded by "<>". This is important for the naming of the
|
||||
accelerators and should be unique. It should be unique both for each
|
||||
menu and between each program. For example in a program named 'foo', the
|
||||
main menu should be called "<FooMain>", and a pop-up menu
|
||||
"<FooImagePopUp>", or similar. What's important is that they're unique.</para>
|
||||
|
||||
<para><literal>accel_group</literal> is a pointer to a gtk_accel_group. The
|
||||
item factory sets up the accelerator table while generating menus. New
|
||||
accelerator groups are generated by gtk_accel_group_new().</para>
|
||||
|
||||
<para>But this is just the first step. To convert the array of GtkItemFactoryEntry
|
||||
information into widgets the following function is used:</para>
|
||||
|
||||
<programlisting role="C">
|
||||
void gtk_item_factory_create_items( GtkItemFactory *ifactory,
|
||||
guint n_entries,
|
||||
GtkItemFactoryEntry *entries,
|
||||
gpointer callback_data );
|
||||
</programlisting>
|
||||
|
||||
<para><literal>*ifactory</literal> a pointer to the above created item factory.</para>
|
||||
<para><literal>n_entries</literal> is the number of entries in the
|
||||
GtkItemFactoryEntry array.</para>
|
||||
<para><literal>*entries</literal> is a pointer to the GtkItemFactoryEntry array.</para>
|
||||
<para><literal>callback_data</literal> is what gets passed to all the callback functions
|
||||
for all the entries with callback_action != 0.</para>
|
||||
|
||||
<para>The accelerator group has now been formed, so you'll probably want
|
||||
to attach it to the window the menu is in:</para>
|
||||
|
||||
<programlisting role="C">
|
||||
void gtk_window_add_accel_group( GtkWindow *window,
|
||||
GtkAccelGroup *accel_group);
|
||||
</programlisting>
|
||||
</sect2>
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect2 id="sec-UsingMenuandItems">
|
||||
<title>Making use of the menu and its menu items</title>
|
||||
|
||||
<para>The last thing to do is make use of the menu. The following function
|
||||
extracts the relevant widgets from the ItemFactory:</para>
|
||||
|
||||
<programlisting role="C">
|
||||
GtkWidget* gtk_item_factory_get_widget( GtkItemFactory *ifactory,
|
||||
const gchar *path );
|
||||
</programlisting>
|
||||
|
||||
<para>For instance if an ItemFactory has two entries "/File" and "/File/New",
|
||||
using a path of "/File" would retrieve a <emphasis>menu</emphasis> widget from the
|
||||
ItemFactory. Using a path of "/File/New" would retrieve a
|
||||
<emphasis>menu item</emphasis> widget. This makes it possible to set the initial state
|
||||
of menu items. For example to set the default radio
|
||||
item to the one with the path "/Shape/Oval" then the following code would
|
||||
be used:</para>
|
||||
|
||||
<programlisting role="C">
|
||||
gtk_check_menu_item_set_active(
|
||||
GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory, "/Shape/Oval")),
|
||||
TRUE);
|
||||
</programlisting>
|
||||
|
||||
<para>Finally to retrieve the root of the menu use gtk_item_factory_get_item()
|
||||
with a path of "<main>" (or whatever path was used in
|
||||
gtk_item_factory_new()). In the case of the ItemFactory being created with
|
||||
type GTK_TYPE_MENU_BAR this returns a menu bar widget. With type GTK_TYPE_MENU
|
||||
a menu widget is returned. With type GTK_TYPE_OPTION_MENU an option menu
|
||||
widget is returned.</para>
|
||||
|
||||
<para><emphasis>Remember</emphasis> for an entry defined with path "/_File"
|
||||
the path here is actually "/File".</para>
|
||||
|
||||
<para>Now you have a menubar or menu which can be manipulated in the same
|
||||
way as shown in the
|
||||
<link linkend="sec-ManualMenuCreation">Manual Menu Creation</link>
|
||||
section.</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
@ -8595,10 +8915,10 @@ gtk_item_factory calls.</para>
|
||||
<para>Here is an example using the GTK item factory.</para>
|
||||
|
||||
<programlisting role="C">
|
||||
<!-- example-start menu itemfactory.c -->
|
||||
/* example-start menu itemfactory.c */
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <strings.h>
|
||||
#include &lt;gtk/gtk.h&gt;
|
||||
#include &lt;strings.h&gt;
|
||||
|
||||
/* Obligatory basic callback */
|
||||
static void print_hello( GtkWidget *w,
|
||||
@ -8607,63 +8927,58 @@ static void print_hello( GtkWidget *w,
|
||||
g_message ("Hello, World!\n");
|
||||
}
|
||||
|
||||
/* This is the GtkItemFactoryEntry structure used to generate new menus.
|
||||
Item 1: The menu path. The letter after the underscore indicates an
|
||||
accelerator key once the menu is open.
|
||||
Item 2: The accelerator key for the entry
|
||||
Item 3: The callback function.
|
||||
Item 4: The callback action. This changes the parameters with
|
||||
which the function is called. The default is 0.
|
||||
Item 5: The item type, used to define what kind of an item it is.
|
||||
Here are the possible values:
|
||||
/* For the check button */
|
||||
static void print_toggle(gpointer callback_data,
|
||||
guint callback_action,
|
||||
GtkWidget *menu_item)
|
||||
{
|
||||
g_message ("Check button state - %d\n",
|
||||
GTK_CHECK_MENU_ITEM(menu_item)-&gt;active);
|
||||
}
|
||||
|
||||
NULL -> "<Item>"
|
||||
"" -> "<Item>"
|
||||
"<Title>" -> create a title item
|
||||
"<Item>" -> create a simple item
|
||||
"<CheckItem>" -> create a check item
|
||||
"<ToggleItem>" -> create a toggle item
|
||||
"<RadioItem>" -> create a radio item
|
||||
<path> -> path of a radio item to link against
|
||||
"<Separator>" -> create a separator
|
||||
"<Branch>" -> create an item to hold sub items (optional)
|
||||
"<LastBranch>" -> create a right justified branch
|
||||
*/
|
||||
/* For the radio buttons */
|
||||
static void print_selected(gpointer callback_data,
|
||||
guint callback_action,
|
||||
GtkWidget *menu_item)
|
||||
{
|
||||
if(GTK_CHECK_MENU_ITEM(menu_item)-&gt;active)
|
||||
g_message("Radio button %d selected\n", callback_action);
|
||||
}
|
||||
|
||||
/* Our menu, an array of GtkItemFactoryEntry structures that defines each menu item */
|
||||
static GtkItemFactoryEntry menu_items[] = {
|
||||
{ "/_File", NULL, NULL, 0, "<Branch>" },
|
||||
{ "/File/_New", "<control>N", print_hello, 0, NULL },
|
||||
{ "/File/_Open", "<control>O", print_hello, 0, NULL },
|
||||
{ "/File/_Save", "<control>S", print_hello, 0, NULL },
|
||||
{ "/File/Save _As", NULL, NULL, 0, NULL },
|
||||
{ "/File/sep1", NULL, NULL, 0, "<Separator>" },
|
||||
{ "/File/Quit", "<control>Q", gtk_main_quit, 0, NULL },
|
||||
{ "/_Options", NULL, NULL, 0, "<Branch>" },
|
||||
{ "/Options/Test", NULL, NULL, 0, NULL },
|
||||
{ "/_Help", NULL, NULL, 0, "<LastBranch>" },
|
||||
{ "/_Help/About", NULL, NULL, 0, NULL },
|
||||
{ "/_File", NULL, NULL, 0, "&lt;Branch&gt;" },
|
||||
{ "/File/_New", "&lt;control&gt;N", print_hello, 0, "<Item>" },
|
||||
{ "/File/_Open", "&lt;control&gt;O", print_hello, 0, "<Item>" },
|
||||
{ "/File/_Save", "&lt;control&gt;S", print_hello, 0, "<Item>" },
|
||||
{ "/File/Save _As", NULL, NULL, 0, "<Item>" },
|
||||
{ "/File/sep1", NULL, NULL, 0, "&lt;Separator&gt;" },
|
||||
{ "/File/Quit", "&lt;control&gt;Q", gtk_main_quit, 0, "<Item>" },
|
||||
{ "/_Options", NULL, NULL, 0, "&lt;Branch&gt;" },
|
||||
{ "/Options/tear", NULL, NULL, 0, "&lt;Tearoff&gt;" },
|
||||
{ "/Options/Check", NULL, print_toggle, 1, "&lt;CheckItem&gt;" },
|
||||
{ "/Options/sep", NULL, NULL, 0, "&lt;Separator&gt;" },
|
||||
{ "/Options/Rad1", NULL, print_selected, 1, "&lt;RadioItem&gt;" },
|
||||
{ "/Options/Rad2", NULL, print_selected, 2, "/Options/Rad1" },
|
||||
{ "/Options/Rad3", NULL, print_selected, 3, "/Options/Rad1" },
|
||||
{ "/_Help", NULL, NULL, 0, "&lt;LastBranch&gt;" },
|
||||
{ "/_Help/About", NULL, NULL, 0, "<Item>" },
|
||||
};
|
||||
|
||||
static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
|
||||
|
||||
void get_main_menu( GtkWidget *window,
|
||||
GtkWidget **menubar )
|
||||
/* Returns a menubar widget made from the above menu */
|
||||
GtkWidget *get_menubar_menu( GtkWidget *window)
|
||||
{
|
||||
GtkItemFactory *item_factory;
|
||||
GtkAccelGroup *accel_group;
|
||||
gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
|
||||
|
||||
/* Make an accelerator group (shortcut keys) */
|
||||
accel_group = gtk_accel_group_new ();
|
||||
|
||||
/* This function initializes the item factory.
|
||||
Param 1: The type of menu - can be GTK_TYPE_MENU_BAR, GTK_TYPE_MENU,
|
||||
or GTK_TYPE_OPTION_MENU.
|
||||
Param 2: The path of the menu.
|
||||
Param 3: A pointer to a gtk_accel_group. The item factory sets up
|
||||
the accelerator table while generating menus.
|
||||
*/
|
||||
|
||||
item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
|
||||
accel_group);
|
||||
/* Make an ItemFactory (that makes a menubar) */
|
||||
item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "&lt;main&gt;",
|
||||
accel_group);
|
||||
|
||||
/* This function generates the menu items. Pass the item factory,
|
||||
the number of items in the array, the array itself, and any
|
||||
@ -8673,48 +8988,112 @@ void get_main_menu( GtkWidget *window,
|
||||
/* Attach the new accelerator group to the window. */
|
||||
gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
|
||||
|
||||
if (menubar)
|
||||
/* Finally, return the actual menu bar created by the item factory. */
|
||||
*menubar = gtk_item_factory_get_widget (item_factory, "<main>");
|
||||
/* Finally, return the actual menu bar created by the item factory. */
|
||||
return gtk_item_factory_get_widget (item_factory, "&lt;main&gt;");
|
||||
}
|
||||
|
||||
/* Popup the menu when the popup button is pressed */
|
||||
static gint popup_cb(GtkWidget *widget, GdkEvent *event, GtkWidget *menu)
|
||||
{
|
||||
GdkEventButton *bevent = (GdkEventButton *)event;
|
||||
|
||||
/* Only take button presses */
|
||||
if(event-&gt;type != GDK_BUTTON_PRESS)
|
||||
return FALSE;
|
||||
|
||||
/* Show the menu */
|
||||
gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
|
||||
NULL, NULL, bevent-&gt;button, bevent-&gt;time);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Same as with get_menubar_menu() but just return a button with a signal to
|
||||
call a popup menu */
|
||||
GtkWidget *get_popup_menu(void)
|
||||
{
|
||||
GtkItemFactory *item_factory;
|
||||
GtkWidget *button, *menu;
|
||||
|
||||
/* Same as before but don't bother with the accelerators */
|
||||
item_factory = gtk_item_factory_new (GTK_TYPE_MENU, "&lt;main&gt;",
|
||||
NULL);
|
||||
gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
|
||||
menu = gtk_item_factory_get_widget(item_factory, "&lt;main&gt;");
|
||||
|
||||
/* Make a button to activate the popup menu */
|
||||
button = gtk_button_new_with_label("Popup");
|
||||
/* Make the menu popup when clicked */
|
||||
g_signal_connect(G_OBJECT(button),
|
||||
"event",
|
||||
G_CALLBACK(popup_cb),
|
||||
(gpointer) menu);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
/* Same again but return an option menu */
|
||||
GtkWidget *get_option_menu(void)
|
||||
{
|
||||
GtkItemFactory *item_factory;
|
||||
GtkWidget *option_menu;
|
||||
|
||||
/* Same again, not bothering with the accelerators */
|
||||
item_factory = gtk_item_factory_new (GTK_TYPE_OPTION_MENU, "&lt;main&gt;",
|
||||
NULL);
|
||||
gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
|
||||
option_menu = gtk_item_factory_get_widget(item_factory, "&lt;main&gt;");
|
||||
|
||||
return option_menu;
|
||||
}
|
||||
|
||||
/* You have to start somewhere */
|
||||
int main( int argc,
|
||||
char *argv[] )
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *main_vbox;
|
||||
GtkWidget *menubar;
|
||||
|
||||
GtkWidget *menubar, *option_menu, *popup_button;
|
||||
|
||||
/* Initialize GTK */
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
|
||||
/* Make a window */
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
g_signal_connect (G_OBJECT (window), "destroy",
|
||||
G_CALLBACK (gtk_main_quit),
|
||||
NULL);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Item Factory");
|
||||
gtk_widget_set_size_request (GTK_WIDGET (window), 300, 200);
|
||||
|
||||
g_signal_connect (G_OBJECT (window), "destroy",
|
||||
G_CALLBACK (gtk_main_quit),
|
||||
NULL);
|
||||
gtk_window_set_title (GTK_WINDOW(window), "Item Factory");
|
||||
gtk_widget_set_size_request (GTK_WIDGET(window), 300, 200);
|
||||
|
||||
/* Make a vbox to put the three menus in */
|
||||
main_vbox = gtk_vbox_new (FALSE, 1);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 1);
|
||||
gtk_container_add (GTK_CONTAINER (window), main_vbox);
|
||||
gtk_widget_show (main_vbox);
|
||||
|
||||
/* Get the three types of menu */
|
||||
/* Note: all three menus are separately created, so they are not the
|
||||
same menu */
|
||||
menubar = get_menubar_menu (window);
|
||||
popup_button = get_popup_menu();
|
||||
option_menu = get_option_menu();
|
||||
|
||||
get_main_menu (window, &menubar);
|
||||
/* Pack it all together */
|
||||
gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, TRUE, 0);
|
||||
gtk_widget_show (menubar);
|
||||
|
||||
gtk_widget_show (window);
|
||||
gtk_box_pack_end (GTK_BOX (main_vbox), popup_button, FALSE, TRUE, 0);
|
||||
gtk_box_pack_end (GTK_BOX (main_vbox), option_menu, FALSE, TRUE, 0);
|
||||
|
||||
/* Show the widgets */
|
||||
gtk_widget_show_all (window);
|
||||
|
||||
/* Finished! */
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
|
||||
return(0);
|
||||
}
|
||||
<!-- example-end -->
|
||||
/* example-end */
|
||||
</programlisting>
|
||||
|
||||
<para>For now, there's only this example. An explanation and lots 'o' comments
|
||||
will follow later.</para>
|
||||
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
TARGET=`pwd`/gtk-tut.sgml
|
||||
IMAGES="`pwd`/images"
|
||||
IMAGESDIR="images"
|
||||
EXAMPLES=`pwd`/../../examples
|
||||
|
||||
PATH=`pwd`:$PATH
|
||||
@ -46,7 +47,7 @@ if [ ! -d sgml ]; then
|
||||
mkdir sgml
|
||||
fi
|
||||
|
||||
(cd sgml ; cp $TARGET . ; cp -R $IMAGES . ; rm -rf images/CVS)
|
||||
(cd sgml ; cp $TARGET . ; cp -R $IMAGES . ; rm -rf $IMAGESDIR/CVS)
|
||||
echo "done"
|
||||
|
||||
# HTML Format
|
||||
@ -59,8 +60,8 @@ if [ ! -d html ]; then
|
||||
mkdir html
|
||||
fi
|
||||
|
||||
(db2html gtk-tut.sgml ; mv gtk-tut/* html ; cp -R $IMAGES html ; rm -rf gtk-tut) > /dev/null
|
||||
(cd html ; ln -s book1.html index.html ; rm -rf images/CVS)
|
||||
(db2html gtk-tut.sgml ; mv gtk-tut/* html ; cp -R $IMAGES html ; rm html/$IMAGESDIR/*.eps ; rm -rf gtk-tut) > /dev/null
|
||||
(cd html ; ln -s book1.html index.html ; rm -rf $IMAGESDIR/CVS)
|
||||
echo "done"
|
||||
|
||||
# PS, PDF and DVI Format
|
||||
@ -81,29 +82,12 @@ if [ ! -d pdf ]; then
|
||||
mkdir pdf
|
||||
fi
|
||||
|
||||
#sed 's/gtk_tut_packbox1.jpg/gtk_tut_packbox1.eps/ ; s/gtk_tut_packbox2.jpg/gtk_tut_packbox2.eps/ ; s/gtk_tut_table.jpg/gtk_tut_table.eps/' gtk-tut.sgml > ps/gtk-tut.sgml
|
||||
sed "s/images\/\(.*\)\.png/images\/\1.eps/g" gtk-tut.sgml > ps/gtk-tut.sgml
|
||||
cp -R ../images ps
|
||||
cp -R $IMAGES ps
|
||||
(cd ps ; db2dvi gtk-tut.sgml ; dvips gtk-tut.dvi -o gtk-tut.ps ; dvipdf gtk-tut.dvi ../pdf/gtk-tut.pdf) > /dev/null 2>&1
|
||||
#sed 's/gtk_tut_packbox1.jpg/gtk_tut_packbox1.eps/ ; s/gtk_tut_packbox2.jpg/gtk_tut_packbox2.eps/ ; s/gtk_tut_table.jpg/gtk_tut_table.eps/' gtk-tut.sgml > ps/gtk-tut.sgml
|
||||
#sed "s/images\/\(.*\)\.png/images\/\1.eps/g" gtk-tut.sgml > ps/gtk-tut.sgml
|
||||
#cp -R images ps
|
||||
(cd ps ; rm gtk-tut.aux gtk-tut.log gtk-tut.sgml gtk-tut.tex ; rm -Rf images) > /dev/null 2>&1
|
||||
(cd ps ; rm gtk-tut.aux gtk-tut.log gtk-tut.sgml gtk-tut.tex ; rm -Rf $IMAGESDIR) > /dev/null 2>&1
|
||||
echo "done"
|
||||
|
||||
# PDF Format
|
||||
#echo -n "Formatting into PDF.... "
|
||||
#if [ ! -d pdf ]; then
|
||||
# if [ -e pdf ]; then
|
||||
# echo "ERROR: pdf is not a directory"
|
||||
# exit
|
||||
# fi
|
||||
# mkdir pdf
|
||||
#fi
|
||||
|
||||
#(db2pdf gtk-tut.sgml ; mv gtk-tut.pdf pdf) > /dev/null
|
||||
#echo "done"
|
||||
|
||||
# RTF Format
|
||||
echo -n "Formatting into RTF.... "
|
||||
if [ ! -d rtf ]; then
|
||||
@ -115,7 +99,7 @@ if [ ! -d rtf ]; then
|
||||
fi
|
||||
|
||||
(db2rtf gtk-tut.sgml ; mv gtk-tut.rtf rtf) > /dev/null
|
||||
cp -R $IMAGES rtf
|
||||
(cd rtf ; cp -R $IMAGES . ; rm -f $IMAGESDIR/*.eps ; rm -rf $IMAGESDIR/CVS)
|
||||
echo "done"
|
||||
|
||||
# Copy examples
|
||||
@ -125,7 +109,7 @@ cp -R $EXAMPLES .
|
||||
echo "done"
|
||||
|
||||
rm -f *
|
||||
rm -rf images
|
||||
rm -rf $IMAGESDIR
|
||||
|
||||
# Package it all up
|
||||
echo -n "Creating packages.... "
|
||||
|
@ -9,63 +9,58 @@ static void print_hello( GtkWidget *w,
|
||||
g_message ("Hello, World!\n");
|
||||
}
|
||||
|
||||
/* This is the GtkItemFactoryEntry structure used to generate new menus.
|
||||
Item 1: The menu path. The letter after the underscore indicates an
|
||||
accelerator key once the menu is open.
|
||||
Item 2: The accelerator key for the entry
|
||||
Item 3: The callback function.
|
||||
Item 4: The callback action. This changes the parameters with
|
||||
which the function is called. The default is 0.
|
||||
Item 5: The item type, used to define what kind of an item it is.
|
||||
Here are the possible values:
|
||||
/* For the check button */
|
||||
static void print_toggle(gpointer callback_data,
|
||||
guint callback_action,
|
||||
GtkWidget *menu_item)
|
||||
{
|
||||
g_message ("Check button state - %d\n",
|
||||
GTK_CHECK_MENU_ITEM(menu_item)->active);
|
||||
}
|
||||
|
||||
NULL -> "<Item>"
|
||||
"" -> "<Item>"
|
||||
"<Title>" -> create a title item
|
||||
"<Item>" -> create a simple item
|
||||
"<CheckItem>" -> create a check item
|
||||
"<ToggleItem>" -> create a toggle item
|
||||
"<RadioItem>" -> create a radio item
|
||||
<path> -> path of a radio item to link against
|
||||
"<Separator>" -> create a separator
|
||||
"<Branch>" -> create an item to hold sub items (optional)
|
||||
"<LastBranch>" -> create a right justified branch
|
||||
*/
|
||||
/* For the radio buttons */
|
||||
static void print_selected(gpointer callback_data,
|
||||
guint callback_action,
|
||||
GtkWidget *menu_item)
|
||||
{
|
||||
if(GTK_CHECK_MENU_ITEM(menu_item)->active)
|
||||
g_message("Radio button %d selected\n", callback_action);
|
||||
}
|
||||
|
||||
/* Our menu, an array of GtkItemFactoryEntry structures that defines each menu item */
|
||||
static GtkItemFactoryEntry menu_items[] = {
|
||||
{ "/_File", NULL, NULL, 0, "<Branch>" },
|
||||
{ "/File/_New", "<control>N", print_hello, 0, NULL },
|
||||
{ "/File/_Open", "<control>O", print_hello, 0, NULL },
|
||||
{ "/File/_Save", "<control>S", print_hello, 0, NULL },
|
||||
{ "/File/Save _As", NULL, NULL, 0, NULL },
|
||||
{ "/File/sep1", NULL, NULL, 0, "<Separator>" },
|
||||
{ "/File/Quit", "<control>Q", gtk_main_quit, 0, NULL },
|
||||
{ "/_Options", NULL, NULL, 0, "<Branch>" },
|
||||
{ "/Options/Test", NULL, NULL, 0, NULL },
|
||||
{ "/_Help", NULL, NULL, 0, "<LastBranch>" },
|
||||
{ "/_Help/About", NULL, NULL, 0, NULL },
|
||||
{ "/_File", NULL, NULL, 0, "<Branch>" },
|
||||
{ "/File/_New", "<control>N", print_hello, 0, "<Item>" },
|
||||
{ "/File/_Open", "<control>O", print_hello, 0, "<Item>" },
|
||||
{ "/File/_Save", "<control>S", print_hello, 0, "<Item>" },
|
||||
{ "/File/Save _As", NULL, NULL, 0, "<Item>" },
|
||||
{ "/File/sep1", NULL, NULL, 0, "<Separator>" },
|
||||
{ "/File/Quit", "<control>Q", gtk_main_quit, 0, "<Item>" },
|
||||
{ "/_Options", NULL, NULL, 0, "<Branch>" },
|
||||
{ "/Options/tear", NULL, NULL, 0, "<Tearoff>" },
|
||||
{ "/Options/Check", NULL, print_toggle, 1, "<CheckItem>" },
|
||||
{ "/Options/sep", NULL, NULL, 0, "<Separator>" },
|
||||
{ "/Options/Rad1", NULL, print_selected, 1, "<RadioItem>" },
|
||||
{ "/Options/Rad2", NULL, print_selected, 2, "/Options/Rad1" },
|
||||
{ "/Options/Rad3", NULL, print_selected, 3, "/Options/Rad1" },
|
||||
{ "/_Help", NULL, NULL, 0, "<LastBranch>" },
|
||||
{ "/_Help/About", NULL, NULL, 0, "<Item>" },
|
||||
};
|
||||
|
||||
static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
|
||||
|
||||
void get_main_menu( GtkWidget *window,
|
||||
GtkWidget **menubar )
|
||||
/* Returns a menubar widget made from the above menu */
|
||||
GtkWidget *get_menubar_menu( GtkWidget *window)
|
||||
{
|
||||
GtkItemFactory *item_factory;
|
||||
GtkAccelGroup *accel_group;
|
||||
gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
|
||||
|
||||
/* Make an accelerator group (shortcut keys) */
|
||||
accel_group = gtk_accel_group_new ();
|
||||
|
||||
/* This function initializes the item factory.
|
||||
Param 1: The type of menu - can be GTK_TYPE_MENU_BAR, GTK_TYPE_MENU,
|
||||
or GTK_TYPE_OPTION_MENU.
|
||||
Param 2: The path of the menu.
|
||||
Param 3: A pointer to a gtk_accel_group. The item factory sets up
|
||||
the accelerator table while generating menus.
|
||||
*/
|
||||
|
||||
item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
|
||||
accel_group);
|
||||
/* Make an ItemFactory (that makes a menubar) */
|
||||
item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
|
||||
accel_group);
|
||||
|
||||
/* This function generates the menu items. Pass the item factory,
|
||||
the number of items in the array, the array itself, and any
|
||||
@ -75,39 +70,106 @@ void get_main_menu( GtkWidget *window,
|
||||
/* Attach the new accelerator group to the window. */
|
||||
gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
|
||||
|
||||
if (menubar)
|
||||
/* Finally, return the actual menu bar created by the item factory. */
|
||||
*menubar = gtk_item_factory_get_widget (item_factory, "<main>");
|
||||
/* Finally, return the actual menu bar created by the item factory. */
|
||||
return gtk_item_factory_get_widget (item_factory, "<main>");
|
||||
}
|
||||
|
||||
/* Popup the menu when the popup button is pressed */
|
||||
static gint popup_cb(GtkWidget *widget, GdkEvent *event, GtkWidget *menu)
|
||||
{
|
||||
GdkEventButton *bevent = (GdkEventButton *)event;
|
||||
|
||||
/* Only take button presses */
|
||||
if(event->type != GDK_BUTTON_PRESS)
|
||||
return FALSE;
|
||||
|
||||
/* Show the menu */
|
||||
gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
|
||||
NULL, NULL, bevent->button, bevent->time);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Same as with get_menubar_menu() but just return a button with a signal to
|
||||
call a popup menu */
|
||||
GtkWidget *get_popup_menu(void)
|
||||
{
|
||||
GtkItemFactory *item_factory;
|
||||
GtkWidget *button, *menu;
|
||||
|
||||
/* Same as before but don't bother with the accelerators */
|
||||
item_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<main>",
|
||||
NULL);
|
||||
gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
|
||||
menu = gtk_item_factory_get_widget(item_factory, "<main>");
|
||||
|
||||
/* Make a button to activate the popup menu */
|
||||
button = gtk_button_new_with_label("Popup");
|
||||
/* Make the menu popup when clicked */
|
||||
g_signal_connect(G_OBJECT(button),
|
||||
"event",
|
||||
G_CALLBACK(popup_cb),
|
||||
(gpointer) menu);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
/* Same again but return an option menu */
|
||||
GtkWidget *get_option_menu(void)
|
||||
{
|
||||
GtkItemFactory *item_factory;
|
||||
GtkWidget *option_menu;
|
||||
|
||||
/* Same again, not bothering with the accelerators */
|
||||
item_factory = gtk_item_factory_new (GTK_TYPE_OPTION_MENU, "<main>",
|
||||
NULL);
|
||||
gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
|
||||
option_menu = gtk_item_factory_get_widget(item_factory, "<main>");
|
||||
|
||||
return option_menu;
|
||||
}
|
||||
|
||||
/* You have to start somewhere */
|
||||
int main( int argc,
|
||||
char *argv[] )
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *main_vbox;
|
||||
GtkWidget *menubar;
|
||||
|
||||
GtkWidget *menubar, *option_menu, *popup_button;
|
||||
|
||||
/* Initialize GTK */
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
|
||||
/* Make a window */
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
g_signal_connect (G_OBJECT (window), "destroy",
|
||||
G_CALLBACK (gtk_main_quit),
|
||||
NULL);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Item Factory");
|
||||
gtk_widget_set_size_request (GTK_WIDGET (window), 300, 200);
|
||||
|
||||
g_signal_connect (G_OBJECT (window), "destroy",
|
||||
G_CALLBACK (gtk_main_quit),
|
||||
NULL);
|
||||
gtk_window_set_title (GTK_WINDOW(window), "Item Factory");
|
||||
gtk_widget_set_size_request (GTK_WIDGET(window), 300, 200);
|
||||
|
||||
/* Make a vbox to put the three menus in */
|
||||
main_vbox = gtk_vbox_new (FALSE, 1);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 1);
|
||||
gtk_container_add (GTK_CONTAINER (window), main_vbox);
|
||||
gtk_widget_show (main_vbox);
|
||||
|
||||
/* Get the three types of menu */
|
||||
/* Note: all three menus are separately created, so they are not the
|
||||
same menu */
|
||||
menubar = get_menubar_menu (window);
|
||||
popup_button = get_popup_menu();
|
||||
option_menu = get_option_menu();
|
||||
|
||||
get_main_menu (window, &menubar);
|
||||
/* Pack it all together */
|
||||
gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, TRUE, 0);
|
||||
gtk_widget_show (menubar);
|
||||
|
||||
gtk_widget_show (window);
|
||||
gtk_box_pack_end (GTK_BOX (main_vbox), popup_button, FALSE, TRUE, 0);
|
||||
gtk_box_pack_end (GTK_BOX (main_vbox), option_menu, FALSE, TRUE, 0);
|
||||
|
||||
gtk_main ();
|
||||
/* Show the widgets */
|
||||
gtk_widget_show_all (window);
|
||||
|
||||
return 0;
|
||||
/* Finished! */
|
||||
gtk_main ();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user