[racket] Extending racket/gui with Gtk widgets
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