Open define-private-public opened 5 years ago
Thanks for testing.
Yes I know that glade example was missing, I was too lazy to provide one and as number of gintro users was very close to zero in the last years it was no real problem.
I don't like glade too much myself, I used it NEd text editor, but that was with oldgtk3. Using an external xml file should be no problem with gintro I guess, linking it together with the executable may be more demanding I managed that for NEd editor, but it was not easy.
I will fix the wrong dll name in the next days and investigate glade example.
I had just a short look at the glade problems, and I remembered one reason why I did not provide one example for gintro. For GTK3 programs we can use the app style which you used in your Nim code, or we can use the traditional gtk2 style with gtk_init() and gtk_main(). For the later style I provided a glade example for oldgtk3. Your Python code seems to use that old style, and that style should work with gintro too, you would use t0.nim gintro example as a starting point.
Of course it would be nicer to use app style with glade. I assume that generally that will work, maybe with one exception: Maybe we can not take the main window from glade but have to use the app functions for that. I have to investigate that, have not yet found a nice example, maybe I have to ask at gtk mailing list.
Okay, I tested doing it based off of t0.nim
, the glade file now shows up.
Would you like an example of the new "app style" or the older one. Is there any benefit to the newer app style?
The app style is what is generally recommended for GTK3, see
https://developer.gnome.org/gtk3/stable/ch01s04.html#id-1.2.3.12.5
I assume that some of GTK3's functionality may not fully work with legacy style. And of course the visual appearance is different, for example the pulldown menu for rarely used actions on top of the screen (not on window header bar) is provide for apps. (But I heard that may disappear again for upcoming GTK4)
Indeed using app style with glade is not a big problem, see
Basically we only have to set the app for the top level window from glade. I have already a minimal working test for that, but the ugly part is
let window = cast[ApplicationWindow](getObject(builder, "window"))
We have this ugly unsecure cast for all widgets provided by glade currently. Ugly is that we have to write the cast at all, and that type check is only done by GTK3 itself at runtime when the widget is actually used. Currently I have the impression that gobject-intropspection does not provide functions for widget type tests at all. In C code these tests are generally done with C macros. I will see what I can do...
This is my current test code:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.12"/>
<object class="GtkApplicationWindow" id="window">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkGrid" id="grid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="button1">
<property name="label" translatable="yes">Button 1</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button2">
<property name="label" translatable="yes">Button 2</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="quit">
<property name="label" translatable="yes">Quit</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">2</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
import gintro/[gtk, glib, gobject, gio]
proc appActivate(app: Application) =
var
builder: Builder
value: Value
button: Button
builder = newBuilder()
discard addFromFile(builder, "builder.ui")
let window = cast[ApplicationWindow](getObject(builder, "window"))
#discard value.init(typeFromName("GObject"))
#value.setObject(app)
#setProperty(window, "application", value)
window.setApplication(app) # above 3 lines work, but just calling this function is simpler
proc main =
let app = newApplication("org.gtk.example")
connect(app, "activate", appActivate)
discard run(app)
main()
Well, we can do our own test at runtime with code like
echo toBool(g_type_check_instance_is_a(cast[ptr TypeInstance00](window.impl), typeFromName("GtkWindow")))
Maybe we should for each data type builder could provide add procs like getWindow(), getButton()... to replace casts like
let window = cast[ApplicationWindow](getObject(builder, "window"))
That getWindow()
, getButton()
does seem like a good solution. Alternatively, could it be possible that each class can take a constructor that could convert a GObject*
pointer to the type. E.g:
let
window = Window(getObject(builder, "window"))
button = Button(getObject(builder, "button"))
But that is more typing.
Hey, my old Nim code above doesn't work, but this here does:
import gintro/[gtk, glib, gobject, gio]
proc appActivate (app: Application) =
let builder = newBuilder()
discard builder.addFromFile("DiceRoll.glade")
let window = cast[ApplicationWindow](builder.getObject("diceRollWindow"))
window.setApplication(app)
window.showAll
proc main =
let app = newApplication("org.gtk.DiceRoll")
app.connect("activate", appActivate)
discard app.run
main()
If you are interested in merging in this Glade example, I'm willing to finish it up.
Seems you have missed a lot...
See latest issues
https://github.com/StefanSalewski/gintro/issues/45
and
https://github.com/StefanSalewski/gintro/issues/46
So all works fine, but connecting the signals from within glade/builder is still untested. Note that recently it was reported that gintro may not compile with 0.19.4 and 0.19.6 due to a missing bracket. Compiles fine for me with 0.19.9, so I hesitated to make a new gintro release just for that bracket.
Well, maybe I should add some docs about glade/builder. I should test connecting signals from within builder for this, and also using resource files -- is some work.
Working glade/builder example is now provided:
https://github.com/StefanSalewski/gintro#gtk-builderuser-interfaces-created-with-the-glade-tool
I'm a little confused. Do you still need to manually specify the signal -> handler connections in Nim?
I don't know, sorry.
I am not even sure if connecting signals from within glade files is possible at all -- from my memory I thought that it may be possible, but that memory is ten years ago, it may be wrong.
In the last months I have seen only glade examples where connecting the handlers to signals was done in the C code, and that works fine for Nim also.
So I guess we have to wait until someone uses gintro and complains that it is not working and points us maybe to an C example, or maybe tell us that it is working?
Currently I am working a bit on all the array parameters in GTK -- I have recently added support for cstringArray, which was needed in one of the latest new examples. But there seems to be many more arrays parameter be used in GTK, supporting all them is hard. Most of these functions I never heard about, so I have to learn how the parameters are used first. Then I have to investigate if we can generate code for support, or if we have to do that manually. The later may indicate adding a few hundred procs manually, which may be a few weeks fulltime work. One example for such a proc is
proc dragDestSet*(self: Widget; flags: DestDefaults; targets: TargetEntry00Array;
nTargets: int; actions: gdk.DragAction) =
with wrong parameter TargetEntry00Array. But there are many of these, and I have still to learn how all these work, so that I can start testing after fixing.
Another issue is emission of custom signals. For default signals we have type save handlers, but for custom signals it may be hard, maybe we can cover it all with closures? I have never used custom signals myself before.
And finally we may investigate using resource files with glade/builder. I did that for the NEd editor, but it was hard and I did not understand it really, so we have to investigate it for gintro.
Oh, and one more: I have still no idea how gintro may work with newruntime.
I noticed that this repo was missing a glade example and I wanted to contribute one; a little dice rolling app. I'm testing this on Linux right now.
Here is my glade file:
Before adding in the functionality, I wanted to make sure that the window would display. I have this in python, and the window does show up:
With this Nim code, the program is exiting in an instant without showing the window at all. The terminal output
Display Window
does show up though.Glade is an essential part of the Gtk ecosystem. Is it a bug or did I forgot something?