[racket] Extending racket/gui with Gtk widgets

From: Diogo F. S. Ramos (diogofsr at gmail.com)
Date: Thu Mar 1 14:25:56 EST 2012

Matthew Flatt <mflatt at cs.utah.edu> writes:

> At Tue, 26 Jul 2011 00:37:41 -0300, Diogo F. S. Ramos wrote:
>> Is there a documented way to extend the racket/gui language with widgets
>> already present in Gtk?
>
> Use the `get-client-handle' method of a `panel%' instance to get a
> GtkWidget pointer for the panel as a Gtk container. Then you can use
> the FFI to call a Gtk functions such as gtk_spin_button_new()
> and gtk_container_add().

Nice, thank you.

I'm able to add a GtkSpinButton with this method but now I'm trying to
take a step further and encapsulate the machinery.

Experimenting with different codes, I get the impression that a panel%,
using gtk_container_add(), can hold only one child. So, my idea is to
create subclasses of panel% and each of these will have a new GtkWidget
inside.

Unfortunately my new objects do not show if I add them to a panel% but
they make an appearance inside a frame%.

Below there is a code example of my proposed technique and the ninja
class (under certain weather conditions) label%, which is redundant
because of message% but illustrates my point. The object `message'
appears, but not `label'.

For the record, I'm using Racket 5.1.3.

#lang racket/gui

(require racket/class)
(require ffi/unsafe)

(define win (new frame% (label "hello, world")))
(define pan (new panel% (parent win)))
(define gtk-label-new (get-ffi-obj "gtk_label_new" #f (_fun _string -> _pointer)))
(define gtk-container-add (get-ffi-obj "gtk_container_add" #f (_fun _pointer _pointer -> _void)))
(define gtk-widget-show (get-ffi-obj "gtk_widget_show" #f (_fun _pointer -> _void)))

(define label%
  (class panel%
    (init parent text)
    (super-new (parent parent))
    (define ptr (gtk-label-new text))
    (gtk-container-add (send this get-client-handle) ptr)
    (gtk-widget-show ptr)))

(define label (new label%
                   (text "GtkLabel")
                   (parent pan)))
(define message (new message%
                     (label "Message")
                     (parent pan)))

(send label show #t)
(send win show #t)

-- 
Diogo F. S. Ramos

Posted on the users mailing list.