unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* G-Golf - Help with ListView needed
@ 2023-03-04  9:09 Michele Lindroos
  2023-03-05  2:35 ` David Pirotte
  2023-03-06  4:07 ` David Pirotte
  0 siblings, 2 replies; 7+ messages in thread
From: Michele Lindroos @ 2023-03-04  9:09 UTC (permalink / raw)
  To: guile-user

Hello Guilers!

I'm trying to learn g-golf. It has been a blast, great technology!
However, the last few days I've tried to get ListView working and now
I'm stuck.

There are plenty of code samples online written in C. I've added at
the bottom of the e-mail a code sample I tried and it works on my
machine as expected. I tried to rewrite the code sample in guile
scheme using g-golf. However, I don't get any elements drawn. Also, I
get no error messages. I don't know where to look for solutions. Have
I failed in translating the C code to scheme? Or is there some other
problem?

Any help is appreciated!

BR,
Michele

$ cat list1.c
#include <gtk/gtk.h>

static void
setup_cb (GtkSignalListItemFactory *self, GtkListItem *listitem,
gpointer user_data) {
  GtkWidget *lb = gtk_label_new (NULL);
  gtk_list_item_set_child (listitem, lb);
  /* Because gtk_list_item_set_child sunk the floating reference of
lb, releasing (unref) isn't necessary for lb. */
}

static void
bind_cb (GtkSignalListItemFactory *self, GtkListItem *listitem,
gpointer user_data) {
  GtkWidget *lb = gtk_list_item_get_child (listitem);
  /* Strobj is owned by the instance. Caller mustn't change or destroy it. */
  GtkStringObject *strobj = gtk_list_item_get_item (listitem);
  /* The string returned by gtk_string_object_get_string is owned by
the instance. */
  gtk_label_set_text (GTK_LABEL (lb), gtk_string_object_get_string (strobj));
}

static void
unbind_cb (GtkSignalListItemFactory *self, GtkListItem *listitem,
gpointer user_data) {
  /* There's nothing to do here. */
}

static void
teardown_cb (GtkSignalListItemFactory *self, GtkListItem *listitem,
gpointer user_data) {
  /* There's nothing to do here. */
  /* GtkListItem instance will be destroyed soon. You don't need to
set the child to NULL. */
}

static void
app_activate (GApplication *application) {
  GtkApplication *app = GTK_APPLICATION (application);
  GtkWidget *win = gtk_application_window_new (app);
  gtk_window_set_default_size (GTK_WINDOW (win), 600, 400);
  GtkWidget *scr = gtk_scrolled_window_new ();
  gtk_window_set_child (GTK_WINDOW (win), scr);

  char *array[] = {
    "one", "two", "three", "four", NULL
  };
  /* sl is owned by ns */
  /* ns and factory are owned by lv. */
  /* Therefore, you don't need to care about their destruction. */
  GtkStringList *sl =  gtk_string_list_new ((const char * const *) array);
  GtkNoSelection *ns =  gtk_no_selection_new (G_LIST_MODEL (sl));

  GtkListItemFactory *factory = gtk_signal_list_item_factory_new ();
  g_signal_connect (factory, "setup", G_CALLBACK (setup_cb), NULL);
  g_signal_connect (factory, "bind", G_CALLBACK (bind_cb), NULL);
  /* The following two lines can be left out. The handlers do nothing. */
  g_signal_connect (factory, "unbind", G_CALLBACK (unbind_cb), NULL);
  g_signal_connect (factory, "teardown", G_CALLBACK (teardown_cb), NULL);

  GtkWidget *lv = gtk_list_view_new (GTK_SELECTION_MODEL (ns), factory);
  gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), lv);
  gtk_window_present (GTK_WINDOW (win));
}

/* ----- main ----- */
#define APPLICATION_ID "com.github.ToshioCP.list1"

int
main (int argc, char **argv) {
  GtkApplication *app;
  int stat;

  app = gtk_application_new (APPLICATION_ID, G_APPLICATION_FLAGS_NONE);

  g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);

  stat =g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);
  return stat;
}

$ cat gtk-signal-list-item-factory.scm
#! /bin/sh
# -*- mode: scheme; coding: utf-8 -*-
exec guile -e main -s "$0" "$@"
!#

(eval-when (expand load eval)
    (use-modules (oop goops))

    (default-duplicate-binding-handler
        '(merge-generics replace warn-override-core warn last))

    (use-modules (g-golf))

    (g-irepository-require "Gtk" #:version "4.0")

    (for-each (lambda (name)
              (gi-import-by-name "Gdk" name))
        '("Display"))

    (for-each (lambda (name)
              (gi-import-by-name "Gtk" name))
        '("Application"
          "ApplicationWindow"
          "Label"
          "ListView"
          "NoSelection"
          "ScrolledWindow"
          "SignalListItemFactory"
          "StringList"
          "StringObject"))

    (for-each (lambda (name)
              (gi-import-by-name "Gio" name))
        '("ListStore")))

(define (activate app)
  (let* ((display (gdk-display-get-default))
         (window (make <gtk-application-window>
                   #:default-width 600
                   #:default-height 400
                   #:application app))
         (scr (make <gtk-scrolled-window>))

         (array '("one" "two" "three" "four"))

         (sl (make <gtk-string-list>
                #:strings array))
         (ns (make <gtk-no-selection>
                #:model sl))

         (signal-list-item-factory (make <gtk-signal-list-item-factory>))

         (lv (make <gtk-list-view>
                #:model ns
                #:factory signal-list-item-factory)))

    (connect signal-list-item-factory
        'setup
        (lambda (factory item)
            (let* ((lb (make <gtk-label>)))
                (set-child item lb))))
    (connect signal-list-item-factory
        'bind
        (lambda (factory item)
            (let* ((lb (get-child (item)))
                   (obj (get-item (item))))
                (set-label lb (get-string obj)))))

    (set-child window scr)
    (set-child scr lv)
    (show window)))

(define (main args)
  (let ((app (make <gtk-application>
               #:application-id "keele.g-golf.gtk-signal-list-item-factory")))
    (connect app 'activate activate)
    (let ((status (g-application-run app args)))
      (exit status))))



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: G-Golf - Help with ListView needed
  2023-03-04  9:09 G-Golf - Help with ListView needed Michele Lindroos
@ 2023-03-05  2:35 ` David Pirotte
  2023-03-06  4:07 ` David Pirotte
  1 sibling, 0 replies; 7+ messages in thread
From: David Pirotte @ 2023-03-05  2:35 UTC (permalink / raw)
  To: guile-user

[-- Attachment #1: Type: text/plain, Size: 360 bytes --]

Hello Michele,

> I'm trying to learn g-golf. It has been a blast, great technology!
> However, the last few days I've tried to get ListView working and now
> I'm stuck.

Thanks for both the C and scheme code - I will look at it and will get
back to you asap - hopefully tomorrow, within the next few days at most
... if no ones beats me ...

David

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: G-Golf - Help with ListView needed
  2023-03-04  9:09 G-Golf - Help with ListView needed Michele Lindroos
  2023-03-05  2:35 ` David Pirotte
@ 2023-03-06  4:07 ` David Pirotte
  2023-03-06 15:50   ` Michele Lindroos
  1 sibling, 1 reply; 7+ messages in thread
From: David Pirotte @ 2023-03-06  4:07 UTC (permalink / raw)
  To: guile-user

[-- Attachment #1: Type: text/plain, Size: 3502 bytes --]

Hello Michele,

> I'm trying to learn g-golf. It has been a blast, great technology!
> However, the last few days I've tried to get ListView working and now
> I'm stuck.

Below a working version.

In the C code, you should:

	app = gtk_application_new (APPLICATION_ID, G_APPLICATION_DEFAULT_FLAGS);
	
	/* so, not G_APPLICATION_FLAGS_NONE *?

In the scheme code, there were three problems

1.	you need to import "ListItem"

2.	 you must call the constructor gtk-string-list-new

	(gtk-string-list-new '("one" "two" "three" "four"))
and not
	(make <gtk-string-list> #:strings  '("one" "two" "three"
	"four"))

the later does not fail, but (get-n-items ...) => 0, instead of 4, and
then, the factory signal are never triggered ...

It is not obvious when you may and when you may not, but in the doc,
you'll see 'Readable no, ..., Construct no', Construct-only yes', then
try the constructor instead of the scheme idiomatic 'way' ... [of
course always prefer the scheme idiomatic way when allowed ...].

3.	in your factory 'bind signal callback, you called 

	... 
		(get-child (item))
		(get-item (item))
	...
	
instead of, it should be

	...
		(get-child item)
		(get-item item)
	...

Thanks,
David

#! /bin/sh
# -*- mode: scheme; coding: utf-8 -*-
exec guile -e main -s "$0" "$@"
!#

(eval-when (expand load eval)
    (use-modules (oop goops))

    (default-duplicate-binding-handler
        '(merge-generics replace warn-override-core warn last))

    (use-modules (g-golf))

    (g-irepository-require "Gtk" #:version "4.0")

    #;(for-each (lambda (name)
              (gi-import-by-name "Gdk" name))
        '("Display"))

    (for-each (lambda (name)
              (gi-import-by-name "Gtk" name))
        '("Application"
          "ApplicationWindow"
          "Label"
          "ListView"
          "ListItem"
          "NoSelection"
          "ScrolledWindow"
          "SignalListItemFactory"
          "StringList"
          "StringObject"))

    #;(for-each (lambda (name)
              (gi-import-by-name "Gio" name))
        '("ListStore")))

(define (activate app)
  (let* (#;(display (gdk-display-get-default))
         (window (make <gtk-application-window>
                   #:default-width 600
                   #:default-height 400
                   #:application app))
         (scr (make <gtk-scrolled-window>))
         (lst '("one" "two" "three" "four"))
         #;(sl (make <gtk-string-list> #:strings lst))
         (sl (gtk-string-list-new lst))
         (ns (make <gtk-no-selection> #:model sl))
         (factory (make <gtk-signal-list-item-factory>))
         (lv (make <gtk-list-view>
               #:model ns
               #:factory factory)))

    (connect factory
             'setup
             (lambda (factory item)
               (set-child item
                          (make <gtk-label>))))

    (connect factory
             'bind
             (lambda (factory item)
               (let* ((lb (get-child item))
                      (obj (get-item item)))
                 (set-label lb (get-string obj)))))

    (set-child window scr)
    (set-child scr lv)
    (show window)))

(define (main args)
  (let ((app (make <gtk-application>
               #:application-id "keele.g-golf.gtk-signal-list-item-factory")))
    (connect app 'activate activate)
    (let ((status (g-application-run app args)))
      (exit status))))



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: G-Golf - Help with ListView needed
  2023-03-06  4:07 ` David Pirotte
@ 2023-03-06 15:50   ` Michele Lindroos
  2023-03-06 22:09     ` David Pirotte
  0 siblings, 1 reply; 7+ messages in thread
From: Michele Lindroos @ 2023-03-06 15:50 UTC (permalink / raw)
  To: guile-user

Hello David,

Thank you so much, it works perfectly now!

BR,
Michele



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: G-Golf - Help with ListView needed
  2023-03-06 15:50   ` Michele Lindroos
@ 2023-03-06 22:09     ` David Pirotte
  2023-03-07 18:55       ` Michele Lindroos
  0 siblings, 1 reply; 7+ messages in thread
From: David Pirotte @ 2023-03-06 22:09 UTC (permalink / raw)
  To: Michele Lindroos; +Cc: guile-user

[-- Attachment #1: Type: text/plain, Size: 821 bytes --]

Hi Michele,

> Thank you so much, it works perfectly now!

Great.

I have to correct what I said, about how/when(or when not) one can
create a GObject (sub)class instance calling

	(make <the-class> #:prop-name prop-value ...)
	[ which internally calls g_object_new_with_properties ...

In this particular situation, the property exists since 4.10, but most
distributions still have 4.8.xx ... As soon as you have access to gtk
4.10 or later, you may revert your code to use the prefered scheme
idiomatic way

	(make <gtk-string-list> #:strings '("one" "two" "three" "four"))

Forget about what I wrote about the prop flags, 'Construct-only' ...
when the property exists, you may always (and should) use instance
creation mechanism:

	(make <a-class> #:prop-name prop-value ...)

Cheers,
David

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: G-Golf - Help with ListView needed
  2023-03-06 22:09     ` David Pirotte
@ 2023-03-07 18:55       ` Michele Lindroos
  2023-03-09 22:08         ` David Pirotte
  0 siblings, 1 reply; 7+ messages in thread
From: Michele Lindroos @ 2023-03-07 18:55 UTC (permalink / raw)
  To: guile-user

Hi David,

> In this particular situation, the property exists since 4.10, but most
> distributions still have 4.8.xx ... As soon as you have access to gtk
> 4.10 or later, you may revert your code to use the prefered scheme
> idiomatic way

You are right, I'm linking against gtk-4 shipped by the distribution
I'm using. In this case, I'm on Ubuntu 22.04 which, at the time of
writing this email, ships gtk-4 version 4.6.6.

This leads me to a few follow-up questions:

1) I did build G-Golf using automake which should figure out all
versions of the libraries I'm linking against. Should an error have
been raised when I called the incompatible constructor? Or maybe a
print in the console log?

2) Assuming I want to write shippable code, is it possible to know
which gtk-4 version is being used and which constructor to call?

3) Is gtk-string-list unique in this regard, or are there also other
classes which need to be instantiated using the non-idiomatic way?

Thanks a lot for all the help!

BR,
Michele



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: G-Golf - Help with ListView needed
  2023-03-07 18:55       ` Michele Lindroos
@ 2023-03-09 22:08         ` David Pirotte
  0 siblings, 0 replies; 7+ messages in thread
From: David Pirotte @ 2023-03-09 22:08 UTC (permalink / raw)
  To: Michele Lindroos; +Cc: guile-user

[-- Attachment #1: Type: text/plain, Size: 2531 bytes --]

Hi Michele,

> ...
> You are right, I'm linking against gtk-4 shipped by the distribution
> I'm using. In this case, I'm on Ubuntu 22.04 which, at the time of
> writing this email, ships gtk-4 version 4.6.6.

> This leads me to a few follow-up questions:
 
> 1) I did build G-Golf using automake which should figure out all
> versions of the libraries I'm linking against.

	there are two questions, here is the first answer:

G-Golf 'figures out' its own dependencies, and gtk is not a g-golf
dependency - note that this said, you need gtk+-3.0 to run make check,
but that is because it's needed to check the override mechanism, there
is 'no way out' - currently make checks also depends on clutter but i
am working to entirely remove the clutter dependency]

> Should an error have been raised when I called the incompatible
> constructor? Or maybe a print in the console log?

G-Golf can't do that, as by design, goops and the mop (meta object
protocl) allow 'other keyword(s)' (in a make call) - so this would
raise many false positive.

Also, as you may see in the peg-solitaire example, G-Golf users may
define GObject sub-classes that define direct slots that define
init-keyword, and those slots not registered as g-properties - ll
this is/are a feature, not a bug - this situation would also trigger
hundreds of false positive lanching then playing the game ...

You, as a G-Golf user and the author of a G-Golf based app, must know
your 'stuff', consult and double check the upstream lib doc ...
there is 'no way out either'.

> 2) Assuming I want to write shippable code, is it possible to know
> which gtk-4 version is being used and which constructor to call?

You will have to, assuming you use the autotool chain, add your own app
dependencies, like for example

	PKG_CHECK_MODULES(GTK, gtk+-4.0 >= 4.6.6)
	[or another version ofc, just an example ...
 
> 3) Is gtk-string-list unique in this regard, or are there also other
> classes which need to be instantiated using the non-idiomatic way?

Certainly not, but as i said, you write the app, you check (which is
easy really, and quite re insuring for your users ... as i said, you
must know your stuff, the upstream lib doc, its version, dperecation,
new interfces ... and try/doublecheck/verify when you face such a
situation ... there is no way out either, and be prepared, gtk and
libadwaita are in constant evolution ...

> Thanks a lot for all the help!

No problem,
Thanks for using G-Golf!
David

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2023-03-09 22:08 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-03-04  9:09 G-Golf - Help with ListView needed Michele Lindroos
2023-03-05  2:35 ` David Pirotte
2023-03-06  4:07 ` David Pirotte
2023-03-06 15:50   ` Michele Lindroos
2023-03-06 22:09     ` David Pirotte
2023-03-07 18:55       ` Michele Lindroos
2023-03-09 22:08         ` David Pirotte

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).