%include "std.mgp" %%default 1 bimage "gtk/gtk-window.jpg" 1024x768, center %page %charset "iso8859-1" Gtk+2 Ein erweiterbares GUI-Toolkit %page Glib 2 Verbesserungen gegenüber Vorversion: %pause Objektmodell %pause 100% Skriptbar %pause Metadaten zur Laufzeit verfügbar %pause Datentypen erweiterbar %pause Integration von weiteren Datentypen einfach %page Datentyp: Klasse %pause Methoden %pause constructor, dispose, finalize %pause destroy (gtk+) %pause Signale %pause events (z.B button-press-event) %pause callbacks (z.B. populate) %pause Properties %pause borderwidth, label... %pause Key-Value-Paare %pause zusätzliche Daten, in Perl: %$self %page Informationen zur Laufzeit abfragen z.B. list_properties: %pause %font "t4" for (Gtk2::Widget->list_properties) { printf "%-16s %-24s %-24s %s\n", $_->{name}, $_->{type}, (join ":", @{$_->{flags}}), $_->{descr}; } %pause %font "t3" user-data gpointer readable:writable Anonymous User Data Pointer name Glib::String readable:writable The name of the widget parent Gtk2::Container readable:writable The parent widget of this widget. Must be a Container widget width-request Glib::Int readable:writable Override for width request of the widget, or -1 if natural request should be used %page Informationen zur Laufzeit abfragen z.B. Signale: %pause %font "t4" Dumpvalue->new (bareStringify => 0)->dumpValue ($_) for Glib::Type->list_signals (Gtk2::Widget::); %pause %font "t4" 'signal_id' => 23 'signal_name' => 'button-press-event' 'itype' => 'Gtk2::Widget' 'param_types' => ARRAY(0x83b4f28) 0 'Gtk2::Gdk::Event' 'return_type' => 'Glib::Boolean' 'signal_flags' => [ run-last ] -> 2 %font "s" %pause Enums, Flags, Superklasse etc.. %page Perl vs. C-Namen %pause %font "t4" warn Glib::Type->package_from_cname ("GtkWindowPosition"); Gtk2::WindowPosition at gtk.pl line xx. %pause warn Glib::Type->package_from_cname ("GdkPixbuf"); Gtk2::Gdk::Pixbuf at gtk.pl line xx. %font "s" %page Neue Datentypen %pause %font "t4" Glib::Type->register_flags (Meine::Flags => %pause 'eins', # implizit 1<<0 'zwei', # implizit 1<<1 %pause ['drei' => 15 ], # explizit 15 ['vier' => 35 ], # explizit 35 ); %pause %font "s" Operationen sind in Perl überladen: %pause %font "t3" $widget->signal_connect (button_press_event => sub { if ($_[1]->type eq "button-press") { %pause if ($_[1]->state == "shift-mask") { %pause if ($_[1]->state * "shift-mask") { # oder '&' %pause if ($_[1]->state >= ["control-mask", "shift-mask"]) { %page Beispiel: Session-Management mit Gtk2 (1) %pause Session-Management = Property-Management? %pause Bei Widget-Erzeugung setzen bzw. Widget vormerken %font "t5" %pause $w = new Gtk2::Window; ::state $w, "main window", allow_shrink => 1, position => "center"; %pause $w = new Gtk2::VPaned; ::state $w, "user/event pane", position => 300; %page Beispiel: Session-Management mit Gtk2 (2) %font "t4" my $state = Storable::retrieve "session.dat"; %pause sub state { my ($widget, $class, %attr) = @_; %pause while (my ($k, $v) = each %attr) { $v = $state->{$class}{$k} if exists $state->{$class}{$k}; %pause $widget->set ($k => $v); } %pause $widget{$widget} = [$widget, $class, \%attr]; Scalar::Util::weaken $widget{$widget}[0]; } %page Beispiel: Session-Management mit Gtk2 (2) Speichern der Sessionkonfiguration %pause %font "t4" sub save_state { for (grep $_, values %widget) { my ($widget, $class, $attr) = @$_; next unless $widget; # widget schon tot... %pause $widget->realize if $widget->can ("realize"); %pause while (my ($k, $v) = each %$attr) { $state->{$class}{$k} = $widget->get ($k); } } %pause Storable::nstore $state, "session.dat"; } %page Glade %pause Glade => abschreckend? %pause Glade kann für Dialogdesign benutzt werden %pause Erzeugen einer Hierarchie mit GladeXML %pause Trennung von Layout und Code %pause Siehe Tagungsband :) %page Eigene Widgets %pause Selten genutzt, aber wichtig für "echte" Applikationen %pause Zwei Methoden: %pause Perl %pause "einfach ableiten" %pause keine eigenen Signale, Properties etc. %pause nur in Perl benutzbar %pause Glib %pause "ungewohnt" %pause eigene Signale, Properties etc... %pause von jeder Sprache aus ansprechbar %page Die Perl-Methode %pause "kennt eh' jeder" %pause => Tagungsband hat ein Beispiel %page Die Glib-Methode (1) Glib::Object::Subclass-"Pragma" %pause %font "t5" package IntegerWidget; %pause use Glib::Object::Subclass Gtk2::Entry, %pause signals => { insert_text => sub { %pause my ($self, $text, $length, $position) = @_; $text =~ y/0-9//cd; $self->signal_chain_from_overridden ($text, $length, $position); }, }; %page Die Glib-Methode (2) %font "t4" package IntegerWidget; use Glib::Object::Subclass Gtk2::Entry, %pause signals => { # neues signal, range-exception range_exception => { class_closure => sub { ... }, flags => [qw(run-first)], param_types => [Glib::Integer], }, }, %pause properties => [ Glib::ParamSpec->string ( min => "Minimum", "Values smaller ...", 0, [qw(readable writable)] ), ], %page Die Glib-Methode (3) %font "t5" %pause Perl Glib %pause new - %pause - INIT_INSTANCE %pause DESTROY FINALIZE_INSTANCE %pause - SET_PROPERTY - GET_PROPERTY %page Standardmethoden - new / INIT_INSTANCE %pause Default-"new"-Methode: Glib::Object::new %pause %font "t5" Glib::Object::new (Gtk::Window::, position => "center", ...); %pause sub INIT_INSTANCE { my ($self) = @_; %pause $self->{button} = new Gtk2::Button ...; } %page Standardmethoden - GET/SET_PROPERTY Default-Implementation: $self->{propname} %font "t5" sub SET_PROPERTY { my ($self, $pspec, $newval) = @_; %pause $pspec = $pspec->get_name; %pause $self->cursor (0) if $pspec =~ /^cursor/; $self->{$pspec} = $newval; $self->cursor (1) if $pspec =~ /^cursor/; } %page Perl-Widgets: Interaktion mit C %pause %font "t5" GtkWidget *w = g_object_new ( "Gtk2__GoBoard", "size", 19 ); %pause g_object_set (w, "size", 19, NULL); %pause int size; g_object_get (w, "size", &size, NULL); %page Objekte aus anderen Sprachen nutzen (1) %pause Init-Funktion aufrufen %pause Datentypen registrieren %pause %font "t5" BOOT: gperl_register_object ( GIMP_TYPE_COLOR_BUTTON, "Gimp::ColorButton"); %pause gperl_register_fundamental ( GDK_TYPE_CAP_STYLE, "Gtk2::Gdk::CapStyle"); %font "s" %page Objekte aus anderen Sprachen nutzen (2) Gimp::ColorButton ist sofort benutzbar: %pause %font "t5" use MeinXSModul; %pause my $button = Gimp::ColorButton ->Glib::Object::new (...);