more on the Text widget, update the tictactoe example to the current code
Sun Mar 29 22:25:22 BST 1998 Tony Gale <gale@gimp.org> * docs/gtk_tut.sgml: more on the Text widget, update the tictactoe example to the current code
This commit is contained in:
committed by
Tony Gale
parent
2f5621e566
commit
4098ac22ff
@ -6,11 +6,11 @@
|
||||
|
||||
<article>
|
||||
<title>GTK Tutorial
|
||||
<author>Ian Main <tt><htmlurl url="mailto:imain@gimp.org"
|
||||
name="<imain@gimp.org>"></tt>,
|
||||
Tony Gale <tt><htmlurl url="mailto:gale@gimp.org"
|
||||
name="<gale@gimp.org>"></tt
|
||||
<date>March 8th, 1998
|
||||
<author>Ian Main <tt><htmlurl url="mailto:imain@gtk.org"
|
||||
name="<imain@gtk.org>"></tt>,
|
||||
Tony Gale <tt><htmlurl url="mailto:gale@gtk.org"
|
||||
name="<gale@gtk.org>"></tt
|
||||
<date>March 29th, 1998
|
||||
|
||||
<!-- ***************************************************************** -->
|
||||
<sect>Introduction
|
||||
@ -42,8 +42,8 @@ replacements for some standard calls, as well as some additional functions
|
||||
for handling linked lists etc. The replacement functions are used to
|
||||
increase GTK's portability, as some of the functions implemented
|
||||
here are not available or are nonstandard on other unicies such as
|
||||
g_strerror(). Some also contain enhancements to the libc versions such as
|
||||
g_malloc has enhanced debugging utilities.
|
||||
g_strerror(). Some also contain enhancements to the libc versions, such as
|
||||
g_malloc that has enhanced debugging utilities.
|
||||
<p>
|
||||
This tutorial is an attempt to document as much as possible of GTK, it is by
|
||||
no means complete. This
|
||||
@ -51,7 +51,7 @@ tutorial assumes a good understanding of C, and how to create C programs.
|
||||
It would be a great benefit for the reader to have previous X programming
|
||||
experience, but it shouldn't be necessary. If you are learning GTK as your
|
||||
first widget set, please comment on how you found this tutorial, and what
|
||||
you had troubles with.
|
||||
you had trouble with.
|
||||
Note that there is also a C++ API for GTK (GTK--) in the works, so if you
|
||||
prefer to use C++, you should look into this instead. There's also an
|
||||
Objective C wrapper, and guile bindings available, but I don't follow these.
|
||||
@ -65,8 +65,9 @@ document, and would appreciate input as to how it may be improved.
|
||||
|
||||
<p>
|
||||
The first thing to do of course, is download the GTK source and install
|
||||
it. You can always get the latest version from ftp.gimp.org in /pub/gtk.
|
||||
You can also view other sources of GTK information on http://www.gimp.org/gtk
|
||||
it. You can always get the latest version from ftp.gtk.org in /pub/gtk.
|
||||
You can also view other sources of GTK information on http://www.gtk.org/
|
||||
<htmlurl url="http://www.gtk.org/" name="http://www.gtk.org/">.
|
||||
GTK uses GNU autoconf for
|
||||
configuration. Once untar'd, type ./configure --help to see a list of options.
|
||||
<p>
|
||||
@ -122,7 +123,7 @@ of the following:
|
||||
<p>
|
||||
It removes these from the argument list, leaving anything it does
|
||||
not recognize for your application to parse or ignore. This creates a set
|
||||
of standard arguments excepted by all GTK applications.
|
||||
of standard arguments accepted by all GTK applications.
|
||||
<p>
|
||||
The next two lines of code create and display a window.
|
||||
|
||||
@ -5165,6 +5166,9 @@ The Text widget allows multiple lines of text to be displayed and edited. It sup
|
||||
multi-colored and multi-font text, allowing them to be mixed in any way we wish. It also has
|
||||
a wide set of key based text editing commands, which are compatible with Emacs.
|
||||
|
||||
The text widget supports full cut-and-paste facilities, including the use of double- and
|
||||
triple-click to select a word and a whole line, respectively.
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect1>Creating and Configuring a Text box
|
||||
<p>
|
||||
@ -5187,6 +5191,19 @@ void gtk_text_set_adjustments (GtkText *text,
|
||||
The above function allows the horizontal and vertical adjustments of a Text widget to be
|
||||
changed at any time.
|
||||
|
||||
The text widget will not automatically create it's own scrollbars when the amount of text
|
||||
to be displayed is too long for the display window. We therefore have to create and add
|
||||
them to the display layout ourselves.
|
||||
|
||||
<tscreen><verb>
|
||||
vscrollbar = gtk_vscrollbar_new (GTK_TEXT(text)->vadj);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), vscrollbar, FALSE, FALSE, 0);
|
||||
gtk_widget_show (vscrollbar);
|
||||
</verb></tscreen>
|
||||
|
||||
The above code snippet creates a new vertical scrollbar, and attaches it to the vertical
|
||||
adjustment of the text widget, <tt/text/. It then packs it into a box in the normal way.
|
||||
|
||||
There are two main ways in which a Text widget can be used: to allow the user to edit a
|
||||
body of text, or to allow us to display multiple lines of text to the user. In order for
|
||||
us to switch between these modes of operation, the text widget has the following function:
|
||||
@ -5200,6 +5217,21 @@ The <tt/editable/ argument is a TRUE or FALSE value that specifies whether the u
|
||||
permitted to edit the contents of the Text widget. When the text widget is editable, it
|
||||
will display a cursor at the current insertion point.
|
||||
|
||||
You are not, however, restricted to just using the text widget in these two modes. You can
|
||||
toggle the editable state of the text widget at any time, and can insert text at any time.
|
||||
|
||||
The text widget is capable of wrapping lines of text that are too long to fit onto a single
|
||||
line of the display window. It's default behaviour is to break words across line breaks. This
|
||||
can be changed using the next function:
|
||||
|
||||
<tscreen><verb>
|
||||
void gtk_text_set_word_wrap (GtkText *text,
|
||||
gint word_wrap);
|
||||
</verb></tscreen>
|
||||
|
||||
Using this function allows us to specify that the text widget should wrap long lines on word
|
||||
boundaries. The <tt/word_wrap/ argument is a TRUE or FALSE value.
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect1>Text Manipulation
|
||||
<P>
|
||||
@ -5236,9 +5268,94 @@ void gtk_text_insert (GtkText *text,
|
||||
gint length);
|
||||
</verb></tscreen>
|
||||
|
||||
Passing a value of <tt/NULL/ in as the value for the foreground color, background colour or
|
||||
Passing a value of <tt/NULL/ in as the value for the foreground color, background colour or
|
||||
font will result in the values set within the widget style to be used. Using a value of <tt/-1/ for
|
||||
the length parameter will result in the whole of the text string given to be inserted.
|
||||
the length parameter will result in the whole of the text string given being inserted.
|
||||
|
||||
The text widget is one of the few within GTK that redraws itself dynamically, outside of the gtk_main
|
||||
function. This means that all changes to the contents of the text widget take effect immediately. This
|
||||
may be undesirable when performing multiple changes to the text widget. In order to allow us to perform
|
||||
multiple updates to the text widget without it continuously redrawing, we can freeze the widget, which
|
||||
temporarily stops it from automatically redrawing itself every time it is changed. We can then thaw the
|
||||
widget after our updates are complete.
|
||||
|
||||
The following two functions perform this freeze and thaw action:
|
||||
|
||||
<tscreen><verb>
|
||||
void gtk_text_freeze (GtkText *text);
|
||||
void gtk_text_thaw (GtkText *text);
|
||||
</verb></tscreen>
|
||||
|
||||
Text is deleted from the text widget relative to the current insertion point by the following
|
||||
two functions:
|
||||
|
||||
<tscreen><verb>
|
||||
gint gtk_text_backward_delete (GtkText *text,
|
||||
guint nchars);
|
||||
gint gtk_text_forward_delete (GtkText *text,
|
||||
guint nchars);
|
||||
</verb></tscreen>
|
||||
|
||||
If you want to retrieve the contents of the text widget, then the macro
|
||||
<tt/GTK_TEXT_INDEX(t, index)/ allows you to retrieve the character at position
|
||||
<tt/index/ within the text widget <tt/t/.
|
||||
|
||||
To retrieve larger blocks of text, we can use the function
|
||||
|
||||
<tscreen><verb>
|
||||
gchar *gtk_editable_get_chars (GtkEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
</verb></tscreen>
|
||||
|
||||
This is a function of the parent class of the text widget. A value of -1 as
|
||||
<tt/end_pos/ signifies the end of the text. The index of the text starts at 0.
|
||||
|
||||
The function allocates a new chunk of memory for the text block, so don't forget
|
||||
to free it with a call to g_free when you have finished with it.
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect1>Keyboard Shortcuts
|
||||
<p>
|
||||
The text widget has a number of pre-installed keyboard shotcuts for common
|
||||
editing, motion and selection functions. These are accessed using Control and Alt
|
||||
key combinations.
|
||||
|
||||
In addition to these, holding down the Control key whilst using cursor key movement
|
||||
will move the cursor by words rather than characters. Holding down Shift whilst using
|
||||
cursor movement will extend the selection.
|
||||
|
||||
<sect2>Motion Shotcuts
|
||||
<p>
|
||||
<itemize>
|
||||
<item> Ctrl-A Beginning of line
|
||||
<item> Ctrl-E End of line
|
||||
<item> Ctrl-N Next Line
|
||||
<item> Ctrl-P Previous Line
|
||||
<item> Ctrl-B Backward one character
|
||||
<item> Ctrl-F Forward one character
|
||||
<item> Alt-B Backward one word
|
||||
<item> Alt-F Forward one word
|
||||
</itemize>
|
||||
|
||||
<sect2>Editing Shortcuts
|
||||
<p>
|
||||
<itemize>
|
||||
<item> Ctrl-H Delete Backward Character (Backspace)
|
||||
<item> Ctrl-D Delete Forward Character (Delete)
|
||||
<item> Ctrl-W Delete Backward Word
|
||||
<item> Alt-D Delete Forward Word
|
||||
<item> Ctrl-K Delete to end of line
|
||||
<item> Ctrl-U Delete line
|
||||
</itemize>
|
||||
|
||||
<sect2>Selection Shortcuts
|
||||
<p>
|
||||
<itemize>
|
||||
<item> Ctrl-X Cut to clipboard
|
||||
<item> Ctrl-C Copy to clipboard
|
||||
<item> Ctrl-V Paste from clipboard
|
||||
</itemize>
|
||||
|
||||
<!-- ***************************************************************** -->
|
||||
<sect> Undocumented Widgets
|
||||
@ -5261,10 +5378,6 @@ your time.
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect1> Range Controls
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect1> Text Boxes
|
||||
<p>
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect1> Previews
|
||||
<p>
|
||||
@ -7024,7 +7137,7 @@ struct _GtkButtonClass
|
||||
|
||||
<p>
|
||||
When a button is treated as a container (for instance, when it is
|
||||
resized), its class structure can be casted to GtkContainerClass, and
|
||||
resized), its class structure can be cast to GtkContainerClass, and
|
||||
the relevant fields used to handle the signals.
|
||||
|
||||
<p>
|
||||
@ -7049,7 +7162,7 @@ struct _GtkButton
|
||||
<p>
|
||||
Note that, similar to the class structure, the first field is the
|
||||
object structure of the parent class, so that this structure can be
|
||||
casted to the parent class's object structure as needed.
|
||||
cast to the parent class's object structure as needed.
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect1> Creating a Composite widget
|
||||
@ -7128,7 +7241,7 @@ extern "C" {
|
||||
Along with the functions and structures, we declare three standard
|
||||
macros in our header file, <tt/TICTACTOE(obj)/,
|
||||
<tt/TICTACTOE_CLASS(klass)/, and <tt/IS_TICTACTOE(obj)/, which cast a
|
||||
pointer into a pointer to the the object or class structure, and check
|
||||
pointer into a pointer to the object or class structure, and check
|
||||
if an object is a Tictactoe widget respectively.
|
||||
|
||||
<p>
|
||||
@ -7206,7 +7319,8 @@ tictactoe_get_type ()
|
||||
sizeof (TictactoeClass),
|
||||
(GtkClassInitFunc) tictactoe_class_init,
|
||||
(GtkObjectInitFunc) tictactoe_init,
|
||||
(GtkArgFunc) NULL,
|
||||
(GtkArgSetFunc) NULL,
|
||||
(GtkArgGetFunc) NULL
|
||||
};
|
||||
|
||||
ttt_type = gtk_type_unique (gtk_vbox_get_type (), &ttt_info);
|
||||
@ -7227,13 +7341,15 @@ struct _GtkTypeInfo
|
||||
guint class_size;
|
||||
GtkClassInitFunc class_init_func;
|
||||
GtkObjectInitFunc object_init_func;
|
||||
GtkArgFunc arg_func;
|
||||
GtkArgSetFunc arg_set_func;
|
||||
GtkArgGetFunc arg_get_func;
|
||||
};
|
||||
</verb></tscreen>
|
||||
|
||||
<p>
|
||||
The fields of this structure are pretty self-explanatory. We'll ignore
|
||||
the <tt/arg_func/ field here: It has an important, but as yet largely
|
||||
the <tt/arg_set_func/ and <tt/arg_get_func/ fields here: they have an important,
|
||||
but as yet largely
|
||||
unimplemented, role in allowing widget options to be conveniently set
|
||||
from interpreted languages. Once GTK has a correctly filled in copy of
|
||||
this structure, it knows how to create objects of a particular widget
|
||||
@ -7267,7 +7383,7 @@ tictactoe_class_init (TictactoeClass *class)
|
||||
GTK_RUN_FIRST,
|
||||
object_class->type,
|
||||
GTK_SIGNAL_OFFSET (TictactoeClass, tictactoe),
|
||||
gtk_signal_default_marshaller, GTK_ARG_NONE, 0);
|
||||
gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
|
||||
|
||||
|
||||
gtk_object_class_add_signals (object_class, tictactoe_signals, LAST_SIGNAL);
|
||||
@ -7286,14 +7402,14 @@ things are going to get a bit complicated.
|
||||
The function:
|
||||
|
||||
<tscreen><verb>
|
||||
gint gtk_signal_new (gchar *name,
|
||||
GtkSignalRunType run_type,
|
||||
gint object_type,
|
||||
gint function_offset,
|
||||
GtkSignalMarshaller marshaller,
|
||||
GtkArgType return_val,
|
||||
gint nparams,
|
||||
...);
|
||||
gint gtk_signal_new (const gchar *name,
|
||||
GtkSignalRunType run_type,
|
||||
GtkType object_type,
|
||||
gint function_offset,
|
||||
GtkSignalMarshaller marshaller,
|
||||
GtkType return_val,
|
||||
guint nparams,
|
||||
...);
|
||||
</verb></tscreen>
|
||||
|
||||
Creates a new signal. The parameters are:
|
||||
@ -7310,29 +7426,45 @@ a pointer to the default handler.
|
||||
<item> <tt/marshaller/: A function that is used to invoke the signal
|
||||
handler. For signal handlers that have no arguments other than the
|
||||
object that emitted the signal and user data, we can use the
|
||||
presupplied marshaller function <tt/gtk_signal_default_marshaller/.
|
||||
pre-supplied marshaller function <tt/gtk_signal_default_marshaller/.
|
||||
<item> <tt/return_val/: The type of the return val.
|
||||
<item> <tt/nparams/: The number of parameters of the signal handler
|
||||
(other than the two default ones mentioned above)
|
||||
<item> <tt/.../: The types of the parameters.
|
||||
</itemize>
|
||||
|
||||
When specifying types, the <tt/GtkArgType/ enumeration is used:
|
||||
When specifying types, the <tt/GtkType/ enumeration is used:
|
||||
|
||||
<tscreen><verb>
|
||||
typedef enum
|
||||
{
|
||||
GTK_ARG_INVALID,
|
||||
GTK_ARG_NONE,
|
||||
GTK_ARG_CHAR,
|
||||
GTK_ARG_SHORT,
|
||||
GTK_ARG_INT,
|
||||
GTK_ARG_LONG,
|
||||
GTK_ARG_POINTER,
|
||||
GTK_ARG_OBJECT,
|
||||
GTK_ARG_FUNCTION,
|
||||
GTK_ARG_SIGNAL
|
||||
} GtkArgType;
|
||||
GTK_TYPE_INVALID,
|
||||
GTK_TYPE_NONE,
|
||||
GTK_TYPE_CHAR,
|
||||
GTK_TYPE_BOOL,
|
||||
GTK_TYPE_INT,
|
||||
GTK_TYPE_UINT,
|
||||
GTK_TYPE_LONG,
|
||||
GTK_TYPE_ULONG,
|
||||
GTK_TYPE_FLOAT,
|
||||
GTK_TYPE_DOUBLE,
|
||||
GTK_TYPE_STRING,
|
||||
GTK_TYPE_ENUM,
|
||||
GTK_TYPE_FLAGS,
|
||||
GTK_TYPE_BOXED,
|
||||
GTK_TYPE_FOREIGN,
|
||||
GTK_TYPE_CALLBACK,
|
||||
GTK_TYPE_ARGS,
|
||||
|
||||
GTK_TYPE_POINTER,
|
||||
|
||||
/* it'd be great if the next two could be removed eventually */
|
||||
GTK_TYPE_SIGNAL,
|
||||
GTK_TYPE_C_CALLBACK,
|
||||
|
||||
GTK_TYPE_OBJECT
|
||||
|
||||
} GtkFundamentalType;
|
||||
</verb></tscreen>
|
||||
|
||||
<p>
|
||||
@ -7360,7 +7492,6 @@ setting the fields of the structure to default values. For composite
|
||||
widgets, however, this function also creates the component widgets.
|
||||
|
||||
<tscreen><verb>
|
||||
|
||||
static void
|
||||
tictactoe_init (Tictactoe *ttt)
|
||||
{
|
||||
@ -7393,8 +7524,8 @@ tictactoe_init (Tictactoe *ttt)
|
||||
There is one more function that every widget (except for base widget
|
||||
types like GtkBin that cannot be instantiated) needs to have - the
|
||||
function that the user calls to create an object of that type. This is
|
||||
conventionally called <tt/WIDGETNAME_new()/In some
|
||||
widgets, thought not for the Tictactoe widgets, this function takes
|
||||
conventionally called <tt/WIDGETNAME_new()/. In some
|
||||
widgets, though not for the Tictactoe widgets, this function takes
|
||||
arguments, and does some setup based on the arguments. The other two
|
||||
functions are specific to the Tictactoe widget.
|
||||
|
||||
@ -7530,7 +7661,7 @@ main (int argc, char *argv[])
|
||||
|
||||
In this section, we'll learn more about how widgets display themselves
|
||||
on the screen and interact with events. As an example of this, we'll
|
||||
create a analog dial widget with a pointer that the user can drag to
|
||||
create an analog dial widget with a pointer that the user can drag to
|
||||
set the value.
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
@ -7701,15 +7832,12 @@ void gtk_dial_set_adjustment (GtkDial *dial,
|
||||
|
||||
|
||||
#endif /* __GTK_DIAL_H__ */
|
||||
|
||||
</verb></tscreen>
|
||||
|
||||
Since there is quite a bit more going on in this widget, than the last
|
||||
one, we have more fields in the data structure, but otherwise things
|
||||
are pretty similar.
|
||||
|
||||
<p>
|
||||
|
||||
Next, after including header files, and declaring a few constants,
|
||||
we have some functions to provide information about the widget
|
||||
and initialize it:
|
||||
@ -7747,7 +7875,8 @@ gtk_dial_get_type ()
|
||||
sizeof (GtkDialClass),
|
||||
(GtkClassInitFunc) gtk_dial_class_init,
|
||||
(GtkObjectInitFunc) gtk_dial_init,
|
||||
(GtkArgFunc) NULL,
|
||||
(GtkArgSetFunc) NULL,
|
||||
(GtkArgGetFunc) NULL,
|
||||
};
|
||||
|
||||
dial_type = gtk_type_unique (gtk_widget_get_type (), &dial_info);
|
||||
@ -8371,7 +8500,6 @@ gtk_dial_adjustment_value_changed (GtkAdjustment *adjustment,
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect2> Possible Enhancements
|
||||
|
||||
<p>
|
||||
|
||||
The Dial widget as we've described it so far runs about 670 lines of
|
||||
@ -8491,8 +8619,8 @@ know which events we want to be notified about. To do this, we call
|
||||
the function:
|
||||
|
||||
<tscreen><verb>
|
||||
void gtk_widget_set_events (GtkWidget *widget,
|
||||
gint events);
|
||||
void gtk_widget_set_events (GtkWidget *widget,
|
||||
gint events);
|
||||
</verb></tscreen>
|
||||
|
||||
The second field specifies the events we are interested in. It
|
||||
@ -8536,16 +8664,12 @@ GtkBox
|
||||
GtkImage
|
||||
GtkItem
|
||||
GtkLabel
|
||||
GtkPaned
|
||||
GtkPixmap
|
||||
GtkScrolledWindow
|
||||
GtkSeparator
|
||||
GtkTable
|
||||
GtkViewport
|
||||
GtkAspectFrame
|
||||
GtkFrame
|
||||
GtkVPaned
|
||||
GtkHPaned
|
||||
GtkVBox
|
||||
GtkHBox
|
||||
GtkVSeparator
|
||||
@ -9291,8 +9415,8 @@ that does not already have documentation, please consider contributing to
|
||||
this document.
|
||||
<p>
|
||||
If you do decide to contribute, please mail your text to Tony Gale,
|
||||
<tt><htmlurl url="mailto:gale@gimp.org"
|
||||
name="gale@gimp.org"></tt>. Also, be aware that the entirety of this
|
||||
<tt><htmlurl url="mailto:gale@gtk.org"
|
||||
name="gale@gtk.org"></tt>. Also, be aware that the entirety of this
|
||||
document is free, and any addition by yourself must also be free. That is,
|
||||
people may use any portion of your examples in their programs, and copies
|
||||
of this document may be distributed at will etc.
|
||||
|
||||
@ -6,11 +6,11 @@
|
||||
|
||||
<article>
|
||||
<title>GTK Tutorial
|
||||
<author>Ian Main <tt><htmlurl url="mailto:imain@gimp.org"
|
||||
name="<imain@gimp.org>"></tt>,
|
||||
Tony Gale <tt><htmlurl url="mailto:gale@gimp.org"
|
||||
name="<gale@gimp.org>"></tt
|
||||
<date>March 8th, 1998
|
||||
<author>Ian Main <tt><htmlurl url="mailto:imain@gtk.org"
|
||||
name="<imain@gtk.org>"></tt>,
|
||||
Tony Gale <tt><htmlurl url="mailto:gale@gtk.org"
|
||||
name="<gale@gtk.org>"></tt
|
||||
<date>March 29th, 1998
|
||||
|
||||
<!-- ***************************************************************** -->
|
||||
<sect>Introduction
|
||||
@ -42,8 +42,8 @@ replacements for some standard calls, as well as some additional functions
|
||||
for handling linked lists etc. The replacement functions are used to
|
||||
increase GTK's portability, as some of the functions implemented
|
||||
here are not available or are nonstandard on other unicies such as
|
||||
g_strerror(). Some also contain enhancements to the libc versions such as
|
||||
g_malloc has enhanced debugging utilities.
|
||||
g_strerror(). Some also contain enhancements to the libc versions, such as
|
||||
g_malloc that has enhanced debugging utilities.
|
||||
<p>
|
||||
This tutorial is an attempt to document as much as possible of GTK, it is by
|
||||
no means complete. This
|
||||
@ -51,7 +51,7 @@ tutorial assumes a good understanding of C, and how to create C programs.
|
||||
It would be a great benefit for the reader to have previous X programming
|
||||
experience, but it shouldn't be necessary. If you are learning GTK as your
|
||||
first widget set, please comment on how you found this tutorial, and what
|
||||
you had troubles with.
|
||||
you had trouble with.
|
||||
Note that there is also a C++ API for GTK (GTK--) in the works, so if you
|
||||
prefer to use C++, you should look into this instead. There's also an
|
||||
Objective C wrapper, and guile bindings available, but I don't follow these.
|
||||
@ -65,8 +65,9 @@ document, and would appreciate input as to how it may be improved.
|
||||
|
||||
<p>
|
||||
The first thing to do of course, is download the GTK source and install
|
||||
it. You can always get the latest version from ftp.gimp.org in /pub/gtk.
|
||||
You can also view other sources of GTK information on http://www.gimp.org/gtk
|
||||
it. You can always get the latest version from ftp.gtk.org in /pub/gtk.
|
||||
You can also view other sources of GTK information on http://www.gtk.org/
|
||||
<htmlurl url="http://www.gtk.org/" name="http://www.gtk.org/">.
|
||||
GTK uses GNU autoconf for
|
||||
configuration. Once untar'd, type ./configure --help to see a list of options.
|
||||
<p>
|
||||
@ -122,7 +123,7 @@ of the following:
|
||||
<p>
|
||||
It removes these from the argument list, leaving anything it does
|
||||
not recognize for your application to parse or ignore. This creates a set
|
||||
of standard arguments excepted by all GTK applications.
|
||||
of standard arguments accepted by all GTK applications.
|
||||
<p>
|
||||
The next two lines of code create and display a window.
|
||||
|
||||
@ -5165,6 +5166,9 @@ The Text widget allows multiple lines of text to be displayed and edited. It sup
|
||||
multi-colored and multi-font text, allowing them to be mixed in any way we wish. It also has
|
||||
a wide set of key based text editing commands, which are compatible with Emacs.
|
||||
|
||||
The text widget supports full cut-and-paste facilities, including the use of double- and
|
||||
triple-click to select a word and a whole line, respectively.
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect1>Creating and Configuring a Text box
|
||||
<p>
|
||||
@ -5187,6 +5191,19 @@ void gtk_text_set_adjustments (GtkText *text,
|
||||
The above function allows the horizontal and vertical adjustments of a Text widget to be
|
||||
changed at any time.
|
||||
|
||||
The text widget will not automatically create it's own scrollbars when the amount of text
|
||||
to be displayed is too long for the display window. We therefore have to create and add
|
||||
them to the display layout ourselves.
|
||||
|
||||
<tscreen><verb>
|
||||
vscrollbar = gtk_vscrollbar_new (GTK_TEXT(text)->vadj);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), vscrollbar, FALSE, FALSE, 0);
|
||||
gtk_widget_show (vscrollbar);
|
||||
</verb></tscreen>
|
||||
|
||||
The above code snippet creates a new vertical scrollbar, and attaches it to the vertical
|
||||
adjustment of the text widget, <tt/text/. It then packs it into a box in the normal way.
|
||||
|
||||
There are two main ways in which a Text widget can be used: to allow the user to edit a
|
||||
body of text, or to allow us to display multiple lines of text to the user. In order for
|
||||
us to switch between these modes of operation, the text widget has the following function:
|
||||
@ -5200,6 +5217,21 @@ The <tt/editable/ argument is a TRUE or FALSE value that specifies whether the u
|
||||
permitted to edit the contents of the Text widget. When the text widget is editable, it
|
||||
will display a cursor at the current insertion point.
|
||||
|
||||
You are not, however, restricted to just using the text widget in these two modes. You can
|
||||
toggle the editable state of the text widget at any time, and can insert text at any time.
|
||||
|
||||
The text widget is capable of wrapping lines of text that are too long to fit onto a single
|
||||
line of the display window. It's default behaviour is to break words across line breaks. This
|
||||
can be changed using the next function:
|
||||
|
||||
<tscreen><verb>
|
||||
void gtk_text_set_word_wrap (GtkText *text,
|
||||
gint word_wrap);
|
||||
</verb></tscreen>
|
||||
|
||||
Using this function allows us to specify that the text widget should wrap long lines on word
|
||||
boundaries. The <tt/word_wrap/ argument is a TRUE or FALSE value.
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect1>Text Manipulation
|
||||
<P>
|
||||
@ -5236,9 +5268,94 @@ void gtk_text_insert (GtkText *text,
|
||||
gint length);
|
||||
</verb></tscreen>
|
||||
|
||||
Passing a value of <tt/NULL/ in as the value for the foreground color, background colour or
|
||||
Passing a value of <tt/NULL/ in as the value for the foreground color, background colour or
|
||||
font will result in the values set within the widget style to be used. Using a value of <tt/-1/ for
|
||||
the length parameter will result in the whole of the text string given to be inserted.
|
||||
the length parameter will result in the whole of the text string given being inserted.
|
||||
|
||||
The text widget is one of the few within GTK that redraws itself dynamically, outside of the gtk_main
|
||||
function. This means that all changes to the contents of the text widget take effect immediately. This
|
||||
may be undesirable when performing multiple changes to the text widget. In order to allow us to perform
|
||||
multiple updates to the text widget without it continuously redrawing, we can freeze the widget, which
|
||||
temporarily stops it from automatically redrawing itself every time it is changed. We can then thaw the
|
||||
widget after our updates are complete.
|
||||
|
||||
The following two functions perform this freeze and thaw action:
|
||||
|
||||
<tscreen><verb>
|
||||
void gtk_text_freeze (GtkText *text);
|
||||
void gtk_text_thaw (GtkText *text);
|
||||
</verb></tscreen>
|
||||
|
||||
Text is deleted from the text widget relative to the current insertion point by the following
|
||||
two functions:
|
||||
|
||||
<tscreen><verb>
|
||||
gint gtk_text_backward_delete (GtkText *text,
|
||||
guint nchars);
|
||||
gint gtk_text_forward_delete (GtkText *text,
|
||||
guint nchars);
|
||||
</verb></tscreen>
|
||||
|
||||
If you want to retrieve the contents of the text widget, then the macro
|
||||
<tt/GTK_TEXT_INDEX(t, index)/ allows you to retrieve the character at position
|
||||
<tt/index/ within the text widget <tt/t/.
|
||||
|
||||
To retrieve larger blocks of text, we can use the function
|
||||
|
||||
<tscreen><verb>
|
||||
gchar *gtk_editable_get_chars (GtkEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
</verb></tscreen>
|
||||
|
||||
This is a function of the parent class of the text widget. A value of -1 as
|
||||
<tt/end_pos/ signifies the end of the text. The index of the text starts at 0.
|
||||
|
||||
The function allocates a new chunk of memory for the text block, so don't forget
|
||||
to free it with a call to g_free when you have finished with it.
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect1>Keyboard Shortcuts
|
||||
<p>
|
||||
The text widget has a number of pre-installed keyboard shotcuts for common
|
||||
editing, motion and selection functions. These are accessed using Control and Alt
|
||||
key combinations.
|
||||
|
||||
In addition to these, holding down the Control key whilst using cursor key movement
|
||||
will move the cursor by words rather than characters. Holding down Shift whilst using
|
||||
cursor movement will extend the selection.
|
||||
|
||||
<sect2>Motion Shotcuts
|
||||
<p>
|
||||
<itemize>
|
||||
<item> Ctrl-A Beginning of line
|
||||
<item> Ctrl-E End of line
|
||||
<item> Ctrl-N Next Line
|
||||
<item> Ctrl-P Previous Line
|
||||
<item> Ctrl-B Backward one character
|
||||
<item> Ctrl-F Forward one character
|
||||
<item> Alt-B Backward one word
|
||||
<item> Alt-F Forward one word
|
||||
</itemize>
|
||||
|
||||
<sect2>Editing Shortcuts
|
||||
<p>
|
||||
<itemize>
|
||||
<item> Ctrl-H Delete Backward Character (Backspace)
|
||||
<item> Ctrl-D Delete Forward Character (Delete)
|
||||
<item> Ctrl-W Delete Backward Word
|
||||
<item> Alt-D Delete Forward Word
|
||||
<item> Ctrl-K Delete to end of line
|
||||
<item> Ctrl-U Delete line
|
||||
</itemize>
|
||||
|
||||
<sect2>Selection Shortcuts
|
||||
<p>
|
||||
<itemize>
|
||||
<item> Ctrl-X Cut to clipboard
|
||||
<item> Ctrl-C Copy to clipboard
|
||||
<item> Ctrl-V Paste from clipboard
|
||||
</itemize>
|
||||
|
||||
<!-- ***************************************************************** -->
|
||||
<sect> Undocumented Widgets
|
||||
@ -5261,10 +5378,6 @@ your time.
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect1> Range Controls
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect1> Text Boxes
|
||||
<p>
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect1> Previews
|
||||
<p>
|
||||
@ -7024,7 +7137,7 @@ struct _GtkButtonClass
|
||||
|
||||
<p>
|
||||
When a button is treated as a container (for instance, when it is
|
||||
resized), its class structure can be casted to GtkContainerClass, and
|
||||
resized), its class structure can be cast to GtkContainerClass, and
|
||||
the relevant fields used to handle the signals.
|
||||
|
||||
<p>
|
||||
@ -7049,7 +7162,7 @@ struct _GtkButton
|
||||
<p>
|
||||
Note that, similar to the class structure, the first field is the
|
||||
object structure of the parent class, so that this structure can be
|
||||
casted to the parent class's object structure as needed.
|
||||
cast to the parent class's object structure as needed.
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect1> Creating a Composite widget
|
||||
@ -7128,7 +7241,7 @@ extern "C" {
|
||||
Along with the functions and structures, we declare three standard
|
||||
macros in our header file, <tt/TICTACTOE(obj)/,
|
||||
<tt/TICTACTOE_CLASS(klass)/, and <tt/IS_TICTACTOE(obj)/, which cast a
|
||||
pointer into a pointer to the the object or class structure, and check
|
||||
pointer into a pointer to the object or class structure, and check
|
||||
if an object is a Tictactoe widget respectively.
|
||||
|
||||
<p>
|
||||
@ -7206,7 +7319,8 @@ tictactoe_get_type ()
|
||||
sizeof (TictactoeClass),
|
||||
(GtkClassInitFunc) tictactoe_class_init,
|
||||
(GtkObjectInitFunc) tictactoe_init,
|
||||
(GtkArgFunc) NULL,
|
||||
(GtkArgSetFunc) NULL,
|
||||
(GtkArgGetFunc) NULL
|
||||
};
|
||||
|
||||
ttt_type = gtk_type_unique (gtk_vbox_get_type (), &ttt_info);
|
||||
@ -7227,13 +7341,15 @@ struct _GtkTypeInfo
|
||||
guint class_size;
|
||||
GtkClassInitFunc class_init_func;
|
||||
GtkObjectInitFunc object_init_func;
|
||||
GtkArgFunc arg_func;
|
||||
GtkArgSetFunc arg_set_func;
|
||||
GtkArgGetFunc arg_get_func;
|
||||
};
|
||||
</verb></tscreen>
|
||||
|
||||
<p>
|
||||
The fields of this structure are pretty self-explanatory. We'll ignore
|
||||
the <tt/arg_func/ field here: It has an important, but as yet largely
|
||||
the <tt/arg_set_func/ and <tt/arg_get_func/ fields here: they have an important,
|
||||
but as yet largely
|
||||
unimplemented, role in allowing widget options to be conveniently set
|
||||
from interpreted languages. Once GTK has a correctly filled in copy of
|
||||
this structure, it knows how to create objects of a particular widget
|
||||
@ -7267,7 +7383,7 @@ tictactoe_class_init (TictactoeClass *class)
|
||||
GTK_RUN_FIRST,
|
||||
object_class->type,
|
||||
GTK_SIGNAL_OFFSET (TictactoeClass, tictactoe),
|
||||
gtk_signal_default_marshaller, GTK_ARG_NONE, 0);
|
||||
gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
|
||||
|
||||
|
||||
gtk_object_class_add_signals (object_class, tictactoe_signals, LAST_SIGNAL);
|
||||
@ -7286,14 +7402,14 @@ things are going to get a bit complicated.
|
||||
The function:
|
||||
|
||||
<tscreen><verb>
|
||||
gint gtk_signal_new (gchar *name,
|
||||
GtkSignalRunType run_type,
|
||||
gint object_type,
|
||||
gint function_offset,
|
||||
GtkSignalMarshaller marshaller,
|
||||
GtkArgType return_val,
|
||||
gint nparams,
|
||||
...);
|
||||
gint gtk_signal_new (const gchar *name,
|
||||
GtkSignalRunType run_type,
|
||||
GtkType object_type,
|
||||
gint function_offset,
|
||||
GtkSignalMarshaller marshaller,
|
||||
GtkType return_val,
|
||||
guint nparams,
|
||||
...);
|
||||
</verb></tscreen>
|
||||
|
||||
Creates a new signal. The parameters are:
|
||||
@ -7310,29 +7426,45 @@ a pointer to the default handler.
|
||||
<item> <tt/marshaller/: A function that is used to invoke the signal
|
||||
handler. For signal handlers that have no arguments other than the
|
||||
object that emitted the signal and user data, we can use the
|
||||
presupplied marshaller function <tt/gtk_signal_default_marshaller/.
|
||||
pre-supplied marshaller function <tt/gtk_signal_default_marshaller/.
|
||||
<item> <tt/return_val/: The type of the return val.
|
||||
<item> <tt/nparams/: The number of parameters of the signal handler
|
||||
(other than the two default ones mentioned above)
|
||||
<item> <tt/.../: The types of the parameters.
|
||||
</itemize>
|
||||
|
||||
When specifying types, the <tt/GtkArgType/ enumeration is used:
|
||||
When specifying types, the <tt/GtkType/ enumeration is used:
|
||||
|
||||
<tscreen><verb>
|
||||
typedef enum
|
||||
{
|
||||
GTK_ARG_INVALID,
|
||||
GTK_ARG_NONE,
|
||||
GTK_ARG_CHAR,
|
||||
GTK_ARG_SHORT,
|
||||
GTK_ARG_INT,
|
||||
GTK_ARG_LONG,
|
||||
GTK_ARG_POINTER,
|
||||
GTK_ARG_OBJECT,
|
||||
GTK_ARG_FUNCTION,
|
||||
GTK_ARG_SIGNAL
|
||||
} GtkArgType;
|
||||
GTK_TYPE_INVALID,
|
||||
GTK_TYPE_NONE,
|
||||
GTK_TYPE_CHAR,
|
||||
GTK_TYPE_BOOL,
|
||||
GTK_TYPE_INT,
|
||||
GTK_TYPE_UINT,
|
||||
GTK_TYPE_LONG,
|
||||
GTK_TYPE_ULONG,
|
||||
GTK_TYPE_FLOAT,
|
||||
GTK_TYPE_DOUBLE,
|
||||
GTK_TYPE_STRING,
|
||||
GTK_TYPE_ENUM,
|
||||
GTK_TYPE_FLAGS,
|
||||
GTK_TYPE_BOXED,
|
||||
GTK_TYPE_FOREIGN,
|
||||
GTK_TYPE_CALLBACK,
|
||||
GTK_TYPE_ARGS,
|
||||
|
||||
GTK_TYPE_POINTER,
|
||||
|
||||
/* it'd be great if the next two could be removed eventually */
|
||||
GTK_TYPE_SIGNAL,
|
||||
GTK_TYPE_C_CALLBACK,
|
||||
|
||||
GTK_TYPE_OBJECT
|
||||
|
||||
} GtkFundamentalType;
|
||||
</verb></tscreen>
|
||||
|
||||
<p>
|
||||
@ -7360,7 +7492,6 @@ setting the fields of the structure to default values. For composite
|
||||
widgets, however, this function also creates the component widgets.
|
||||
|
||||
<tscreen><verb>
|
||||
|
||||
static void
|
||||
tictactoe_init (Tictactoe *ttt)
|
||||
{
|
||||
@ -7393,8 +7524,8 @@ tictactoe_init (Tictactoe *ttt)
|
||||
There is one more function that every widget (except for base widget
|
||||
types like GtkBin that cannot be instantiated) needs to have - the
|
||||
function that the user calls to create an object of that type. This is
|
||||
conventionally called <tt/WIDGETNAME_new()/In some
|
||||
widgets, thought not for the Tictactoe widgets, this function takes
|
||||
conventionally called <tt/WIDGETNAME_new()/. In some
|
||||
widgets, though not for the Tictactoe widgets, this function takes
|
||||
arguments, and does some setup based on the arguments. The other two
|
||||
functions are specific to the Tictactoe widget.
|
||||
|
||||
@ -7530,7 +7661,7 @@ main (int argc, char *argv[])
|
||||
|
||||
In this section, we'll learn more about how widgets display themselves
|
||||
on the screen and interact with events. As an example of this, we'll
|
||||
create a analog dial widget with a pointer that the user can drag to
|
||||
create an analog dial widget with a pointer that the user can drag to
|
||||
set the value.
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
@ -7701,15 +7832,12 @@ void gtk_dial_set_adjustment (GtkDial *dial,
|
||||
|
||||
|
||||
#endif /* __GTK_DIAL_H__ */
|
||||
|
||||
</verb></tscreen>
|
||||
|
||||
Since there is quite a bit more going on in this widget, than the last
|
||||
one, we have more fields in the data structure, but otherwise things
|
||||
are pretty similar.
|
||||
|
||||
<p>
|
||||
|
||||
Next, after including header files, and declaring a few constants,
|
||||
we have some functions to provide information about the widget
|
||||
and initialize it:
|
||||
@ -7747,7 +7875,8 @@ gtk_dial_get_type ()
|
||||
sizeof (GtkDialClass),
|
||||
(GtkClassInitFunc) gtk_dial_class_init,
|
||||
(GtkObjectInitFunc) gtk_dial_init,
|
||||
(GtkArgFunc) NULL,
|
||||
(GtkArgSetFunc) NULL,
|
||||
(GtkArgGetFunc) NULL,
|
||||
};
|
||||
|
||||
dial_type = gtk_type_unique (gtk_widget_get_type (), &dial_info);
|
||||
@ -8371,7 +8500,6 @@ gtk_dial_adjustment_value_changed (GtkAdjustment *adjustment,
|
||||
|
||||
<!-- ----------------------------------------------------------------- -->
|
||||
<sect2> Possible Enhancements
|
||||
|
||||
<p>
|
||||
|
||||
The Dial widget as we've described it so far runs about 670 lines of
|
||||
@ -8491,8 +8619,8 @@ know which events we want to be notified about. To do this, we call
|
||||
the function:
|
||||
|
||||
<tscreen><verb>
|
||||
void gtk_widget_set_events (GtkWidget *widget,
|
||||
gint events);
|
||||
void gtk_widget_set_events (GtkWidget *widget,
|
||||
gint events);
|
||||
</verb></tscreen>
|
||||
|
||||
The second field specifies the events we are interested in. It
|
||||
@ -8536,16 +8664,12 @@ GtkBox
|
||||
GtkImage
|
||||
GtkItem
|
||||
GtkLabel
|
||||
GtkPaned
|
||||
GtkPixmap
|
||||
GtkScrolledWindow
|
||||
GtkSeparator
|
||||
GtkTable
|
||||
GtkViewport
|
||||
GtkAspectFrame
|
||||
GtkFrame
|
||||
GtkVPaned
|
||||
GtkHPaned
|
||||
GtkVBox
|
||||
GtkHBox
|
||||
GtkVSeparator
|
||||
@ -9291,8 +9415,8 @@ that does not already have documentation, please consider contributing to
|
||||
this document.
|
||||
<p>
|
||||
If you do decide to contribute, please mail your text to Tony Gale,
|
||||
<tt><htmlurl url="mailto:gale@gimp.org"
|
||||
name="gale@gimp.org"></tt>. Also, be aware that the entirety of this
|
||||
<tt><htmlurl url="mailto:gale@gtk.org"
|
||||
name="gale@gtk.org"></tt>. Also, be aware that the entirety of this
|
||||
document is free, and any addition by yourself must also be free. That is,
|
||||
people may use any portion of your examples in their programs, and copies
|
||||
of this document may be distributed at will etc.
|
||||
|
||||
Reference in New Issue
Block a user