Help language development. Donate to The Perl Foundation

GTK::V3 cpan:MARTIMM last updated on 2019-05-18

gtk-v3-0.12.0/

GTK::V3 - Accessing Gtk version 3.*

License

Description

First of all, I would like to thank the developers of the GTK::Simple project because of the information I got while reading the code. Also because one of the files is copied unaltered for which I did not had to think about to get that right. The examples in that project are also useful to compare code with each other and to see what is or is not possible.

The purpose of this project is to create an interface to the GTK version 3 library. Previously I had this library in the GTK::Glade project but because of its growth I decided to create a separate project.

Example

This example does the same as the example from GTK::Simple to show you the differences between the implementations. What immediately is clear is that this example is somewhat longer. To sum up;

Pros

Cons

use v6;

use GTK::V3::Gtk::GtkMain;
use GTK::V3::Gtk::GtkWindow;
use GTK::V3::Gtk::GtkGrid;
use GTK::V3::Gtk::GtkButton;

# Instantiate main module for UI control
my GTK::V3::Gtk::GtkMain $m .= new;

# Class to handle signals
class AppSignalHandlers {

  # Handle 'Hello World' button click
  method first-button-click ( :widget($b1), :other-button($b2) ) {
    $b1.set-sensitive(False);
    $b2.set-sensitive(True);
  }

  # Handle 'Goodbye' button click
  method second-button-click ( ) {
    $m.gtk-main-quit;
  }
}

# Create a top level window and set a title
my GTK::V3::Gtk::GtkWindow $top-window .= new(:empty);
$top-window.set-title('Hello GTK!');
$top-window.set-border-width(20);

# Create a grid and add it to the window
my GTK::V3::Gtk::GtkGrid $grid .= new(:empty);
$top-window.gtk-container-add($grid);

# Create buttons and disable the second one
my GTK::V3::Gtk::GtkButton $button .= new(:label('Hello World'));
my GTK::V3::Gtk::GtkButton $second .= new(:label('Goodbye'));
$second.set-sensitive(False);

# Add buttons to the grid
$grid.gtk-grid-attach( $button, 0, 0, 1, 1);
$grid.gtk-grid-attach( $second, 0, 1, 1, 1);

# Instantiate the event handler class and register signals
my AppSignalHandlers $ash .= new;
$button.register-signal(
  $ash, 'first-button-click', 'clicked',  :other-button($second)
);
$second.register-signal( $ash, 'second-button-click', 'clicked');

# Show everything and activate all
$top-window.show-all;
$m.gtk-main;

Design

I want to follow the interface of the classes in Gtk, Gdk and Glib as closely as possible by keeping the names of the native functions the same as provided with the following exceptions; * The native subroutines are defined in their classes. They are setup in such a way that they have become methods in those classes. Many subs also have as their first argument the native object. This object is held in the class and is automatically inserted when needed. E.g. a definition like the following in the GtkButton class

sub gtk_button_set_label ( N-GObject $widget, Str $label )
  is native(&gtk-lib)
  { * }

can be used as

my GTK::V3::Gtk::GtkButton $button .= new(:empty);
$button.gtk_button_set_label('Start Program');
$button.gtk_widget_set_tooltip_text('When pressed, program will start');
my Str $button-label = $button.get_label;

In the documentation this will be shown with brackets around the part that can be left out. In this case is is shown as [gtk_button_] get_label.

my Str $button-label = $button.gtk-button-get-label;

or

my Str $button-label = $button.get-label;
sub g_slist_nth_data_str ( N-GSList $list, uint32 $n --> Str )
  is native(&gtk-lib)
  is symbol('g_slist_nth_data')
  { * }

sub g_slist_nth_data_gobject ( N-GSList $list, uint32 $n --> N-GObject )
  is native(&gtk-lib)
  is symbol('g_slist_nth_data')
  { * }

Other causes are variable argument lists where I had to choose for the extra arguments. E.g. in the GtkFileChooserDialog the native sub gtk_file_chooser_dialog_new has a way to extend it with a number of buttons on the dialog. I had to fix that list to a known number of arguments and renamed the sub gtk_file_chooser_dialog_new_two_buttons.

sub gtk_grid_attach (
  N-GObject $grid, N-GObject $child,
  int32 $x, int32 $y,
  int32 $width, int32 $height
) is native(&gtk-lib)
  { * }

And its use;

my GTK::V3::Gtk::GtkGrid $grid .= new(:empty);
my GTK::V3::Gtk::GtkLabel $label .= new(:label('server name'));
$grid.gtk-grid-attach( $label, 0, 0, 1, 1);

Errors and crashes

I came to the conclusion that Perl6 is not (yet) capable to return a proper message when mistakes are made by me e.g. spelling errors or using wrong types when using the native call interface. Most of them end up in MoarVM panic: Internal error: Unwound entire stack and missed handler. Other times it ends in just a plain crash. Some of the crashes are happening within GTK and cannot be captured by Perl6. One of those moments are the use of GTK calls without initializing GTK with gtk_init. The panic mentioned above mostly happens when perl6 code is called from C as a callback. The stack might not be interpreted completely at that moment hence the message.

A few measures are implemented to help a bit preventing problems;

Documentation

Gtk library

Pdf from pod Link to Gnome Developer
GTK::V3::Gtk::GtkAboutDialog GtkAboutDialog.html
GTK::V3::Gtk::GtkBin GtkBin.html
GTK::V3::Gtk::GtkBuilder GtkBuilder.html
GTK::V3::Gtk::GtkButton GtkButton.html
GTK::V3::Gtk::GtkCheckButton GtkCheckButton.html
GTK::V3::Gtk::GtkComboBox GtkComboBox.html
GTK::V3::Gtk::GtkComboBoxText GtkComboBoxText.html
GTK::V3::Gtk::GtkContainer GtkContainer.html
GTK::V3::Gtk::GtkCssProvider GtkCssProvider.html
GTK::V3::Gtk::GtkStyleContext GtkStyleContext.html
GTK::V3::Gtk::GtkDialog GtkDialog.html
GTK::V3::Gtk::GtkEntry GtkEntry.html
GTK::V3::Gtk::GtkFileChooser GtkFileChooser.html
GTK::V3::Gtk::GtkFileChooserDialog GtkFileChooserDialog.html
GTK::V3::Gtk::GtkFileFilter GtkFileFilter.html
GTK::V3::Gtk::GtkGrid GtkGrid.html
GTK::V3::Gtk::GtkImage GtkImage.html
GTK::V3::Gtk::GtkImageMenuItem GtkImageMenuItem.html
GTK::V3::Gtk::GtkLabel GtkLabel.html
[ GTK::V3::Gtk::GtkLevelBar ][ GTK::V3::Gtk::GtkLevelBar pdf] [GtkLevelBar.html][]GtkLevelBar
GTK::V3::Gtk::GtkListBox GtkListBox.html
GTK::V3::Gtk::GtkMain GtkMain.html
GTK::V3::Gtk::GtkMenuItem GtkMenuItem.html
GTK::V3::Gtk::GtkOrientable GtkOrientable.html
GTK::V3::Gtk::GtkRadioButton GtkRadioButton.html
GTK::V3::Gtk::GtkStyleContext GtkStyleContext.html
GTK::V3::Gtk::GtkTextBuffer GtkTextBuffer.html
GTK::V3::Gtk::GtkTextTagTable GtkTextTagTable.html
GTK::V3::Gtk::GtkTextView GtkTextView.html
GTK::V3::Gtk::GtkToggleButton GtkToggleButton.html
GTK::V3::Gtk::GtkWidget GtkWidget.html
GTK::V3::Gtk::GtkWindow GtkWindow.html

Gdk library

Pdf from pod Link to Gnome Developer
GTK::V3::Gdk::GdkDisplay Controls a set of GdkScreens and their associated input devices
GTK::V3::Gdk::GdkEventTypes Device events
GTK::V3::Gdk::GdkScreen Object representing a physical screen
GTK::V3::Gdk::GdkTypes
GTK::V3::Gdk::GdkWindow Windows

Glib library

Pdf from pod Link to Gnome Developer
GTK::V3::Glib::GError
GTK::V3::Glib::GInitiallyUnowned
GTK::V3::Glib::GInterface
GTK::V3::Glib::GList Doubly-Linked Lists
GTK::V3::Glib::GMain The Main Event Loop
GTK::V3::Glib::GObject The base object type
GTK::V3::Glib::GSignal Signal handling
GTK::V3::Glib::GSList Singly-Linked Lists
GTK::V3::Glib::GType 1) Type Information, 2) Basic Types
GTK::V3::Glib::GValue 1) Generic values, 2) Parameters and Values

Miscellaneous

Release notes

Notes

1) The CALL-ME method is coded in such a way that a native widget can be set or retrieved easily. E.g.

my GTK::V3::Gtk::GtkLabel $label .= new(:label('my label'));
my GTK::V3::Gtk::GtkGrid $grid .= new;
$grid.gtk_grid_attach( $label(), 0, 0, 1, 1);
  Notice how the native widget is retrieved with `$label()`.

2) The FALLBACK method is used to test for the defined native functions as if the functions where methods. It calls the fallback methods in the class which in turn call the parent fallback using callsame. The resulting function addres is returned and processed with the test-call functions from GTK::V3::X. Thrown exceptions are handled by the function test-catch-exception from the same module. 3) N-GObject is a native widget which is held internally in most of the classes. Sometimes they need to be handed over in a call or stored when it is returned. 4) Each method can at least be called with perl6 like dashes in the method name. E.g. gtk_container_add can be written as gtk-container-add. 5) In some cases the calls can be shortened too. E.g. gtk_button_get_label can also be called like get_label or get-label. Sometimes, when shortened, calls can end up with a call using the wrong native widget. When in doubt use the complete method call. 6) Also a sub like gtk_button_new cannot be shortened because it will call the perl6 init method new(). In most cases, these calls are used when initializing classes, in this case to initialize a GTK::V3::Gtk::GtkButton class. Above brackets '[]' show which part can be chopped. 7) All classes deriving from GtkObject know about the :widget named attribute when instantiating a widget class. This is used when the result of another native sub returns a N-GObject. This option works for all child classes too. E.g. cleaning a list box;

my GTK::V3::Gtk::GtkListBox $list-box .= new(:build-id<someListBox>);
loop {
  # Keep the index 0, entries will shift up after removal
  my $nw = $list-box.get-row-at-index(0);
  last unless $nw.defined;
  my GTK::V3::Gtk::GtkBin $lb-row .= new(:widget($nw));
  $lb-row.gtk-widget-destroy;
}

8) The attribute :build-id is used when a N-GObject is returned from builder for a search with a given object id using $builder.gtk_builder_get_object(). A builder must be initialized before to be useful. This option works for all child classes too. E.g.

my GTK::V3::Gtk::GtkLabel $label .= new(:build-id<inputLabel>);

9) Sometimes a N-GObject must be given as a parameter. As mentioned above in [1] the CALL-ME method helps to return that object. To prevent mistakes (forgetting the '()' after the object), the parameters to the call are checked for the use of a GtkObject instead of the native object. When encountered, the parameters are automatically converted. E.g.

my GTK::V3::Gtk::GtkButton $button .= new(:label('press here'));
my GTK::V3::Gtk::GtkLabel $label .= new(:label('note'));

my GTK::V3::Gtk::GtkGrid $grid .= new(:empty);
$grid.attach( $button, 0, 0, 1, 1);
$grid.attach( $label, 0, 1, 1, 1);
Here in the call to gtk_grid_attach $button and $label is used instead of $button() and label().

Miscellaneous

TODO

Versions of involved software

Installation of GTK::V3

zef install GTK::V3

Author

Name: Marcel Timmerman Github account name: MARTIMM

Documentation

Documentation is generated with pod-render.pl6 --pdf --style=pod6 --g=github.com/MARTIMM/gtk-v3 lib