2002-12-25 15:26:17 +00:00
< html >
< head >
< title > The Gnome.NET Tutorial< / title >
< link rel = "stylesheet" type = "text/css" href = "../../style.css" / >
< / head >
< body >
< table bgcolor = #BEBAA8 width = 100% >
< tr > < td > < a href = "../../../index.html" > < img src = "../../../mg.png" border = 0 > < / a > < a href = "../../index.html" > < img src = "../../gn.png" border = 0 > < / a > < / td > < / tr >
< / table >
< table bgcolor = #efefef width = 100% >
< tr > < td class = "navbar" > < a href = "../../../index.html" > Monkeyguide< / a > > < a href = "../../index.html" > GNOME.NET< / a > > C# bindings > < b > GTK#< / b > < / tr >
< / table >
< p > < h1 > GTK#< / h1 >
by Johannes Roith (< a href = "mailto:johannes@jroith.de" > johannes@jroith.de< / a > ), Alejandro S<> nchez Acosta (< a href = "mailto:raciel@es.gnu.org" > raciel@es.gnu.org< / a > ) [if you contribute to this chapter please add your name here]< br >
2002-11-25 16:50:27 +00:00
This chapter does use some content from the GTK+ Tutorial by Tony Gale, Ian Main, & the GTK team
< h2 > Introduction< / h2 >
GTK (GIMP Toolkit) is a library for creating graphical user interfaces. It is licensed using the LGPL license, so you can develop open software, free software, or even commercial non-free software using GTK without having to spend anything for licenses or royalties.
< br > < br >
It's called the GIMP toolkit because it was originally written for developing the GNU Image Manipulation Program (GIMP), but GTK has now been used in a large number of software projects, including the GNU Network Object Model Environment (GNOME) project. GTK is built on top of GDK (GIMP Drawing Kit) which is basically a wrapper around the low-level functions for accessing the underlying windowing functions (Xlib in the case of the X windows system), and gdk-pixbuf, a library for client-side image manipulation.
< h2 > HelloWorld, first try< / h2 >
HelloWorld in Gtk#:
< table cellpadding = 5 border = 0 >
< tr >
< td valign = top >
< pre class = "code" >
using Gtk;
using GtkSharp;
using System;
class Hello {
static void Main()
{
Application.Init ();
Window window = new Window ("helloworld");
window.Show();
Application.Run ();
}
}
< / pre >
< / td >
< td valign = top > < img src = base.png border = 0 > < / td >
< / tr > < / table >
[compile: mcs helloworld.cs -r gtk-sharp.dll -r glib-sharp.dll]< br > < br >
It's a bit longer than console hello world and needs some explanation.< br > < br >
Before we jump in the Main method, every GTK# Application will have to import the namespaces:
< pre class = "code" >
using Gtk;
using GtkSharp;
< / pre >
If you don't do so, each Class from one of these namespaces needs the namespace mentioned as prefix.< br >
< br >
In Main() at first you see:
< pre class = "code" > Application.Init()< / pre >
This initializes GTK and is needed in every GTK# Application.< br >
The next line create a new window. GTK# can set the title in the constructor and saves one line compared to C.< br >
< pre class = "code" >
Window window = new Window ("helloworld");
< / pre >
< pre class = "code" > Application.Run()< / pre > shows the application and most importantly keeps it open, waiting for events, until Quit() is called.
< h2 > HelloWorld, second try< / h2 >
While the above program compiles and runs, it's doesn't quit, properly. You've to exit with CRTL+C.< br > < br >
< pre class = "code" >
using Gtk;
using GtkSharp;
using System;
class Hello {
static void Main()
{
Application.Init ();
Window window = new Window ("helloworld");
window.DeleteEvent += new DeleteEventHandler (delete_event);
window.ShowAll ();
Button btn = new Button ("Hello World");
btn.Clicked += new EventHandler (hello);
Application.Run ();
}
static void delete_event (object obj, DeleteEventArgs args)
{
Application.Quit ();
}
static void hello (object obj, EventArgs args)
{
Console.WriteLine("Hello World");
Application.Quit ();
}
}
< / pre >
This sample quits correctly.< br >
GTK is an event driven toolkit, which means it will sleep in Application.Run() until an event occurs and control is passed to the appropriate function. GTK# can make use of the type "event". When you close HelloWorld, the DeleteEvent is thrown, by the window.
To enable your application to react on the DeleteEvent, you must connect it to an event handler.
< pre class = "code" >
window.DeleteEvent += new DeleteEventHandler (delete_event);
< / pre >
An event handler is passed an object, the object that fired the event, here window, and EventArgs. The EventArgs here have the special type DeleteEventArgs).
< pre class = "code" >
static void delete_event (object obj, DeleteEventArgs args)
{
Application.Quit ();
}
< / pre >
This sample also adds a button to the window and connects the clicked event to "hello".
2002-12-23 22:36:38 +00:00
< h2 > Packing Widgets< / h2 >
< p >
When you create an application you will need to pack your widgets in a window, that is it too easy to make, only you have to use the Add method with your corresponding widget like window.Add (button), that would be add a button in your window.< / p >
< p >
2002-11-25 16:50:27 +00:00
If you come from Windows, you're probably used to position several widgets using coordinates. Also possible, that's not the way it's done in GTK#. Most packing is done by creating boxes. These are invisible widget containers that we can pack our widgets into which come in two forms, a horizontal box, and a vertical box. While this is more difficult for a newcomer it has some advantages:
< ul >
< li > Independent of screesize< / li >
< li > Easier Internationalization< / li >
< / ul >
2002-12-23 22:36:38 +00:00
< p >
There are other kind of methods to pack widgets that is using packing widgets. There are two boxes: vbox and hbox. The creation of that is too simple, only you have to create an instance of HBox or VBox like the Button widgets.< / p >
2002-11-25 16:50:27 +00:00
2002-12-23 22:36:38 +00:00
< p >
Two important methods of that packing boxes are PackStart and PackEnd, these methods packing the element beginning with the top to the button and the second will do button to up in VBox. In HBox you package the samples left to right with PackStart and right to left with PackEnd.
< / p >
< p >
By using these calls, GTK knows where you want to place your widgets so it can do automatic resizing and other nifty things. There are also a number of options as to how your widgets should be packed. As you can imagine, this method gives us a quite a bit of flexibility when placing and creating widgets.
< p >
< p > Then a packing widgets sample:< / p >
< pre class = "code" >
namespace GtkSharpTutorial {
using Gtk;
using GtkSharp;
using Gdk;
using GdkSharp;
using Glib;
using GlibSharp;
using System;
using System.Drawing;
public class fixedcontainer
{
public int x = 50;
public int y = 50;
static Gtk.HBox make_box (bool homogeneous, int spacing, bool expand, bool fill, uint padding)
{
HBox box;
Box box1;
Button button;
string padstr;
box = new HBox (homogeneous, spacing);
button = new Button ("gtk_box_pack");
box.PackStart (button, expand, fill, padding);
button.Show();
button = new Button ("(box,");
box.PackStart (button, expand, fill, padding);
button.Show();
button = new Button ("button");
box.PackStart (button, expand, fill, padding);
button.Show();
if (expand == true)
button = new Button ("TRUE");
else
button = new Button ("FALSE");
box.PackStart (button, expand, fill, padding);
button.Show();
button = new Button (fill ? "TRUE," : "FALSE,");
box.PackStart(button, expand, fill, padding);
button.Show();
padstr=padding.ToString()+");";
button = new Button (padstr);
box.PackStart (button, expand, fill, padding);
button.Show();
return box;
}
static void delete_event (object obj, DeleteEventArgs args)
{
Application.Quit();
}
static void exitbutton_event (object obj, ButtonPressEventArgs args)
{
Application.Quit();
}
public static int Main (string[] args)
{
Gtk.Window window;
Button button;
VBox box1;
HBox box2;
HSeparator separator;
Misc misc;
Box quitbox;
int which;
Gtk.Label label;
Application.Init();
if (args.Length !=1) {
Console.WriteLine ("Usage: packbox num, where num is 1, 2 o 3");
return (1);
}
which = Convert.ToInt32 (args[0]);
window = new Gtk.Window ("packingdemo");
window.DeleteEvent += new DeleteEventHandler (delete_event);
window.BorderWidth = 10;
box1 = new VBox (false, 0);
switch (which) {
case 1:
label=new Gtk.Label("gtk_hbox_new (FALSE, 0);");
box2 = new HBox (false, 0);
label.SetAlignment (0, 0);
box1.PackStart (label, false, false, 0);
label.Show();
box2 = make_box (false, 0, false, false, 0);
box1.PackStart (box2, false, false, 0);
box2.Show();
box2 = make_box (false, 0, true, false, 0);
box1.PackStart (box2, false, false, 0);
box2.Show();
box2 = make_box (false, 0, true, true, 0);
box1.PackStart (box2, false, false, 0);
box2.Show();
separator = new HSeparator ();
box1.PackStart (separator, false, true, 5);
separator.Show();
box1 = new VBox (true, 0);
label=new Gtk.Label("gtk_hbox_new (TRUE, 0);");
label.SetAlignment (0, 0);
box1.PackStart(label, false, false, 0);
label.Show();
box2 = make_box (true, 0, true, true, 0);
box1.PackStart (box2, false, false, 0);
box2.Show();
box2 = make_box (true, 0, true, true, 0);
box1.PackStart(box2, false, false, 0);
box2.Show();
separator = new HSeparator();
box1.PackStart (separator, false, true, 5);
separator.Show();
break;
case 2:
box2 = new HBox (false, 10);
label = new Gtk.Label("gtk_hbox_new (FALSE, 10);");
label.SetAlignment (0, 0);
box1.PackStart (box2, false, false, 0);
box1.Show();
box2 = make_box (false, 10, true, true, 0);
box1.PackStart (box2, false, false, 0);
box2.Show();
separator = new HSeparator ();
box1.PackStart (separator, false, true, 5);
separator.Show();
box2 = new HBox (false, 0);
label=new Gtk.Label("gtk_hbox_new (FALSE, 0);");
label.SetAlignment (0, 0);
box1.PackStart (label, false, false, 0);
label.Show();
box2 = make_box (false, 0, true, false, 10);
box1.PackStart (box2, false, false, 0);
box2.Show();
box2 = make_box (false, 0, true, true, 10);
box1.PackStart (box2, false, false, 0);
box2.Show();
separator = new HSeparator ();
box1.PackStart(separator, false, true, 5);
separator.Show();
break;
case 3:
box2 = make_box (false, 0, false, false, 0);
label = new Label ("end");
box2.PackEnd(label, false, false, 0);
label.Show();
box1.PackStart(box2, false, false, 0);
box2.Show();
separator = new HSeparator();
separator.SetSizeRequest(400, 5);
box1.PackStart (separator, false, true, 5);
separator.Show();
break;
}
quitbox = new HBox (false, 0);
button = new Button ("Quit");
button.Clicked += new EventHandler (ClickedEventHandler);
quitbox.PackStart(button, true, false, 0);
box1.PackStart (quitbox, false, false, 0);
window.Add(box1);
button.Show();
quitbox.Show();
box1.Show();
window.Show();
Application.Run();
return 0;
}
static void ClickedEventHandler(object sender, EventArgs e)
{
Application.Quit();
}
}
}
< / pre >
< p > [TODO]: Explain sample.
2002-11-25 16:50:27 +00:00
< h2 > A closer look at Buttons< / h2 >
GTK# offers not just the normal button, but some other types, derived from it.
< h3 > Using Stock Icons< / h3 >
Up to now, we only created Buttons containing a label. It's possible to create a
Button from Stock Icon, which is very good for consistency in Gnome apps:< br >
< br >
Common look & feel: Toolbar with 4 Stock Icons.< br >
< img src = "stockicons.png" border = 0 >
< br >
< pre class = "code" >
Button stockbutton = Button.FromStock(< b > stocktype< / b > );
< / pre >
Gtk# offers a wide range of good-looking, well designed and accessible icons.
Anopther benfit of Stock Icons is, that they are available in many languages,
and there is no need, to translate them.
< b > stocktype< / b > must be one of these values:
< pre class = "code" >
Gtk.Stock.Add
Gtk.Stock.Apply
Gtk.Stock.Bold
Gtk.Stock.Cancel
Gtk.Stock.Cdrom
Gtk.Stock.Clear
Gtk.Stock.Close
Gtk.Stock.Convert
Gtk.Stock.Copy
Gtk.Stock.Cut
Gtk.Stock.Delete
Gtk.Stock.DialogError
Gtk.Stock.DialogInfo
Gtk.Stock.DialogQuestion
Gtk.Stock.DialogWarning
Gtk.Stock.StockDnd
Gtk.Stock.DndMultiple
Gtk.Stock.Execute
Gtk.Stock.FIND
Gtk.Stock.FIND_AND_REPLACE
Gtk.Stock.FLOPPY
Gtk.Stock.GOTO_BOTTOM
Gtk.Stock.GOTO_FIRST
Gtk.Stock.GOTO_LAST
Gtk.Stock.GOTO_TOP
Gtk.Stock.GO_BACK
Gtk.Stock.GO_DOWN
Gtk.Stock.GO_FORWARD
Gtk.Stock.GO_UP
Gtk.Stock.HELP
Gtk.Stock.HOME
Gtk.Stock.INDEX
Gtk.Stock.ITALIC
Gtk.Stock.JUMP_TO
Gtk.Stock.JUSTIFY_CENTER
Gtk.Stock.JUSTIFY_FILL
Gtk.Stock.JUSTIFY_LEFT
Gtk.Stock.JUSTIFY_RIGHT
Gtk.Stock.MISSING_IMAGE
Gtk.Stock.NEW
Gtk.Stock.NO
Gtk.Stock.OK
Gtk.Stock.OPEN
Gtk.Stock.PASTE
Gtk.Stock.PREFERENCES
Gtk.Stock.PRINT
Gtk.Stock.PRINT_PREVIEW
Gtk.Stock.PROPERTIES
Gtk.Stock.QUIT
Gtk.Stock.REDO
Gtk.Stock.REFRESH
Gtk.Stock.REMOVE
Gtk.Stock.REVERT_TO_SAVED
Gtk.Stock.SAVE
Gtk.Stock.SAVE_AS
Gtk.Stock.SELECT_COLOR
Gtk.Stock.SELECT_FONT
Gtk.Stock.SORT_ASCENDING
Gtk.Stock.SORT_DESCENDING
Gtk.Stock.SPELL_CHECK
Gtk.Stock.STOP
Gtk.Stock.STRIKETHROUGH
Gtk.Stock.UNDELETE
Gtk.Stock.UNDERLINE
Gtk.Stock.UNDO
Gtk.Stock.YES
Gtk.Stock.ZOOM_100
Gtk.Stock.ZOOM_FIT
Gtk.Stock.ZOOM_IN
Gtk.Stock.ZOOM_OUT
< / pre >
< h3 > Custom Buttons< / h3 >
You can put pretty much everything in the button. A often used example is a button with icon and label.
< br >
[TODO]
< h3 > Toggle Buttons< / h3 >
ToggleButtons are similiar to the normal button, but when clicked, may be depressed, and when you click again,
they will pop back up. Click again, and they will pop back down. When popped down, the Property Active has the value "true".
< pre class = "code" >
using Gtk;
using GtkSharp;
using System;
using System.Drawing;
2002-12-23 22:36:38 +00:00
public class togglebuttons
2002-11-25 16:50:27 +00:00
{
public static void Main(string[] args)
{
Application.Init();
Window window = new Window("toggle buttons");
window.DeleteEvent += new DeleteEventHandler (delete_event);
< b > /* Creating a new ToggleButton*/
ToggleButton togglebutton = new ToggleButton ("button1");< / b >
togglebutton.Clicked += new EventHandler (clickedCallback);
window.Add(togglebutton);
window.ShowAll();
Application.Run();
}
static void delete_event (object obj, DeleteEventArgs args)
{
Application.Quit();
}
static void clickedCallback (object obj, EventArgs args)
{
< b > /* Check Active Property */< / b >
if (((ToggleButton) obj).< b > Active< / b > )
Console.WriteLine ("ToggleButton clicked, I'm activating");
}
}
< / pre >
< h3 > Check Buttons< / h3 >
Check Buttons are squares with text besides them. From a programmers point of view, they work like ToggleButtons.
< pre class = "code" >
CheckButton cb1 = new CheckButton ("CheckButton 1");
< / pre >
< h3 > Radio Buttons< / h3 >
< br >
[TODO]: Sample needs explanation.
< pre class = "code" >
using Gtk;
using GtkSharp;
using System;
using System.Drawing;
public class radiobuttons
{
static GLib.SList group = null;
static void delete_event (object obj, DeleteEventArgs args)
{
Application.Quit();
}
static void exitbutton_event (object obj, EventArgs args)
{
Application.Quit();
}
public static void Main(string[] args)
{
Application.Init();
Window window = new Window("radio buttons");
window.DeleteEvent += new DeleteEventHandler (delete_event);
window.BorderWidth = 0;
VBox box1 = new VBox (false, 0);
window.Add(box1);
box1.Show();
VBox box2 = new VBox (false, 10);
box2.BorderWidth = 10;
box1.PackStart(box2, true, true, 0);
box2.Show();
RadioButton radiobutton = new RadioButton (null, "button1");
box2.PackStart(radiobutton, true, true, 0);
radiobutton.Show();
group = radiobutton.Group;
RadioButton radiobutton2 = new RadioButton(group, "button2");
radiobutton2.Active = true;
box2.PackStart(radiobutton2, true, true, 0);
radiobutton2.Show();
RadioButton radiobutton3 = RadioButton.NewWithLabelFromWidget(radiobutton, "button3");
box2.PackStart(radiobutton3, true, true, 0);
radiobutton3.Show();
HSeparator separator = new HSeparator ();
box1.PackStart (separator,false, true, 0);
separator.Show();
VBox box3 = new VBox(false, 10);
box3.BorderWidth = 10;
box1.PackStart(box3,false, true, 0);
box3.Show();
Button button = new Button ("close");
button.Clicked += new EventHandler (exitbutton_event);
box3.PackStart(button, true, true, 0);
button.CanDefault = true;
button.GrabDefault();
button.Show();
window.ShowAll();
Application.Run();
}
}
< / pre >
2002-12-23 22:36:38 +00:00
2002-11-25 16:50:27 +00:00
< h2 > Miscellaneous Widgets< / h2 >
This section describes some often used widgets, but is not a complete reference. A more complete
listing will be available in the GTK# port of the GTK+ 2.0 tutorial or the GTK# documentation.
< h3 > Labels< / h3 >
Creating a new Label...
< pre class = "code" >
Label label1 = new Label("Caption");
< / pre >
A new feature makes it possible, to use simple styles in label captions. It's called GMarkup and is similiar to HTML:
< pre class = "code" >
Label label1 = new Label("A < span color=\"blue\"> blue< /span> < big> and< /big> < b> bold< /b> label");
< / pre >
This line is rendered like that:< br > < br >
< img src = label.png border = 0 > < br > < br >
The feature is possible, thanks to pango, that is discussed later.
< br > < br >
The label text can be justified using:
< pre class = "code" >
label1.Justify = jtype;
< / pre >
jtype must be a value of the Justification enumeration:
< pre class = "code" >
Justification.Left
Justification.Right
Justification.Center
Justification.Fill
< / pre >
The label widget is also capable of line wrapping the text automatically. This can be activated using:
< pre class = "code" >
label1.LineWrap = true;
< / pre >
The wrap argument takes a true or false value.
< br >
The text can be underlined:
< pre class = "code" >
label1.Pattern = "_________________________ _ _________ _ ______ __ _______ ___";
< / pre >
An example application, using labels can be viewed here: < a href = "label.cs" > label.cs< / a >
< h3 > Using Tooltips< / h3 >
Tooltips are boxes with some text, that can be shown, when the mouse moves over a widget.
< br >
< pre class = "code" >
Tooltips tooltip1 = new Tooltips();
tooltip1.SetTip(button1, "Click on this button to exit", null)
< / pre >
You can use the same tooltip object for all widgets. This makes sense, because you can then enable/disable all tooltips easily:
< pre class = "code" >
tooltip1.Enable();
tooltip1.Disable();
< / pre >
< h3 > Progress Bars< / h3 >
< br >
[TODO]
< h3 > Statusbar< / h3 >
< br >
[TODO]
< h3 > Color Selection< / h3 >
< br >
[TODO]
< h3 > File Selection< / h3 >
The Gnome FileOpen/Close Dialog.
[TODO]
< h3 > Font Selection< / h3 >
< br >
[TODO]
< h3 > Message Dialog< / h3 >
< br >
[TODO]
< h3 > Tree View< / h3 >
< br >
[TODO]
< h3 > Text View< / h3 >
< br >
[TODO]
< h2 > Using Drag & Drop< / h2 >
< h2 > Widget Overview< / h2 >
< h3 > Widget Hierarchy< / h3 >
Here is the class hierarchy tree used to implement widgets:
< pre class = "code" >
GObject
|
GtkObject
+GtkWidget
| +GtkMisc
| | +GtkLabel
| | | `GtkAccelLabel
| | +GtkArrow
| | `GtkImage
| +GtkContainer
| | +GtkBin
| | | +GtkAlignment
| | | +GtkFrame
| | | | `GtkAspectFrame
| | | +GtkButton
| | | | +GtkToggleButton
| | | | | `GtkCheckButton
| | | | | `GtkRadioButton
| | | | `GtkOptionMenu
| | | +GtkItem
| | | | +GtkMenuItem
| | | | +GtkCheckMenuItem
| | | | | `GtkRadioMenuItem
| | | | +GtkImageMenuItem
| | | | +GtkSeparatorMenuItem
| | | | `GtkTearoffMenuItem
| | | +GtkWindow
| | | | +GtkDialog
| | | | | +GtkColorSelectionDialog
| | | | | +GtkFileSelection
| | | | | +GtkFontSelectionDialog
| | | | | +GtkInputDialog
| | | | | `GtkMessageDialog
| | | | `GtkPlug
| | | +GtkEventBox
| | | +GtkHandleBox
| | | +GtkScrolledWindow
| | | `GtkViewport
| | +GtkBox
| | | +GtkButtonBox
| | | | +GtkHButtonBox
| | | | `GtkVButtonBox
| | | +GtkVBox
| | | | +GtkColorSelection
| | | | +GtkFontSelection
| | | | `GtkGammaCurve
| | | `GtkHBox
| | | +GtkCombo
| | | `GtkStatusbar
| | +GtkFixed
| | +GtkPaned
| | | +GtkHPaned
| | | `GtkVPaned
| | +GtkLayout
| | +GtkMenuShell
| | | +GtkMenuBar
| | | `GtkMenu
| | +GtkNotebook
| | +GtkSocket
| | +GtkTable
| | +GtkTextView
| | +GtkToolbar
| | `GtkTreeView
| +GtkCalendar
| +GtkDrawingArea
| | `GtkCurve
| +GtkEditable
| | +GtkEntry
| | `GtkSpinButton
| +GtkRuler
| | +GtkHRuler
| | `GtkVRuler
| +GtkRange
| | +GtkScale
| | | +GtkHScale
| | | `GtkVScale
| | `GtkScrollbar
| | +GtkHScrollbar
| | `GtkVScrollbar
| +GtkSeparator
| | +GtkHSeparator
| | `GtkVSeparator
| +GtkInvisible
| +GtkPreview
| `GtkProgressBar
+GtkAdjustment
+GtkCellRenderer
| +GtkCellRendererPixbuf
| +GtkCellRendererText
| +GtkCellRendererToggle
+GtkItemFactory
+GtkTooltips
`GtkTreeViewColumn
< / pre >
< / body >
2002-12-23 22:36:38 +00:00
< / html >