Some weeks ago GTK 3.20 appeared, so I prepared the ten most important modules for Nim. Unfortunately it was a bit more work than estimated. I consider making the ten modules available for public access, maybe as tar file, on my own git server or under a new root directory at github. I will not delete the existing 3.15.xx wrappers from github yet, because they are already a bit tested and contain some examples, while the new ones are still untested.
If you are interested how the wrapper look now you may find the GtkSourceView one at http://ssalewski.de/tmp/gtksource.nim.
All wrappers are generated with current c2nim (0.9.8) with --nep1 option. nep1 was a big mistake unfortunately, its arbitrary inconsistent renaming of identifiers gave much trouble... But the new bitfield support saves some manual work.
I have not yet used the noforward pragma, because it was never really official advertised, so some reordering effort was still necessary.
For procs generally the prefix like gtkSource is removed, for most modules that is done for templates too. But not for low level modules like glib, so templates identifiers start with something like gType. I think removing that may result in too many name conflicts. For Widgets and many other types prefix is stripped, but the G prefix for GObject data types is preserved still. Type Button is identical with also available ButtonPtr, pointing to ButtonObj. For proc names like setColor or getColor aliases like .color and color= are available. For button_new_with_label() we have now plain newButton(). Types start generally with capital letter, like Gpointer or Gsize. Basic GTK types are replaced with identical Nim types, so we can use int32 instead of Gint32.
Wrapping GTK related modules with c2nim has become harder since 3.20 again because GTK developers define and use non trivial C macros now in header files. Since number is still low I expanded these macros to plain C with gcc -E and converted that with c2nim to Nim code. We may not really need these macros, but without it adapting C examples like application 10 from https://developer.gnome.org/gtk3/stable/ch01s04.html#id-1.2.3.12.5 or converting whole C tools like GEdit will not work. Maybe GObject Introspection is the way to go in the future, but I guess that will support not the full C example range.
All that is still without GC support. I think it should be easy to wrap the most important GTK types in Nim objects and make the compiler so smart that it passes automatically the pointer to the GTK object when the GTK function gets a Nim object. Andreas called that delegates in the past, but I am not sure if that is a good term for that. Converters may work also, and they work better when they behave like templates instead of procs. But I really think a smart compiler, which can do a simple argument substitution when a Nim object is passed to a C lib function is the better way. Maybe coupled to a special field name in the Nim object.
OK, it is available at github now:
No nimble install yet, I will try to read the nimble chapter of Dominiks book soom, so maybe it will become possible...
The toy chess is available, and a minimal test for each of the ten wrappers. Next task may be to add the missing C glib/gobject macros, so that all the C examples like application10 can be transfered directly to Nim.
For example, to try the toychess for Linux you may execute these commands:
cd
mkdir ngtk3
cd ngtk3
git clone https://github.com/ngtk3/common
git clone https://github.com/ngtk3/nim-atk
git clone https://github.com/ngtk3/nim-cairo
git clone https://github.com/ngtk3/nim-chess
git clone https://github.com/ngtk3/nim-gdk3
git clone https://github.com/ngtk3/nim-gdk_pixbuf
git clone https://github.com/ngtk3/nim-gio
git clone https://github.com/ngtk3/nim-glib
git clone https://github.com/ngtk3/nim-gobject
git clone https://github.com/ngtk3/nim-gtk3
git clone https://github.com/ngtk3/nim-gtksourceview
git clone https://github.com/ngtk3/nim-pango
cd nim-chess
ln -s ~/ngtk3/nim-gio/src/gio.nim
ln -s ~/ngtk3/nim-atk/src/atk.nim
ln -s ~/ngtk3/nim-glib/src/glib.nim
ln -s ~/ngtk3/nim-gdk3/src/gdk3.nim
ln -s ~/ngtk3/nim-gtk3/src/gtk3.nim
ln -s ~/ngtk3/nim-gobject/src/gobject.nim
ln -s ~/ngtk3/nim-cairo/src/cairo.nim
ln -s ~/ngtk3/nim-pango/src/pango.nim
ln -s ~/ngtk3/nim-pango/src/pango_cairo.nim
ln -s ~/ngtk3/nim-gdk_pixbuf/src/gdk_pixbuf.nim
nim c -d:release board.nim
./board
Legacy names like gtk_button_new() are not available any more -- the deprecated pragma caused confusion in most cases due to bug https://github.com/nim-lang/Nim/issues/2414 . And I just saw that bug https://github.com/nim-lang/Nim/issues/3449 may still exist, I have not tested that yet.
Thanks so much for all your work! I think I have cairo bindings floating around someplace. I may take them out of the nimble package list once yours go up.
The next step for this wrapper is probably making it so nim users can subclass gobjects and implement interfaces in pure nim. Given the fact that c2nim can actually deal with glib this could be a really native feeling GUI library wrapper.
It is one of the more complete wrappers out there (for any language) thanks to c2nim.
The Nim version of https://developer.gnome.org/gtk3/stable/ch01s04.html is now available.
It is basically a plain text editor, I have used the gtksourceview widget instead of the plain textview, so syntax highlight is available for many languages like C and Ruby. Nim highlight may be available if you ever installed Aporia. But you may better test with a C file first.
This Nim version is basically a plain conversion of the C example, only difficulty was building the C gobject macros in Nim. Of course we do not have to write GTK applications in this way, it is a bit strange using these macros. But the nice thing is that it is possible and adapting C examples is easy. I think for most other programming languages that will not work in this way.
The example may work in Linux for 64 bit -- for 32 bit the macros and templates may fail...
It was necessary to apply some small fixes for glib, gobject, gio and gtk3 modules.
I had no time to try nimble install, so you still have to do it manually. These instructions should work:
cd
mkdir ngtk3
cd ngtk3
git clone https://github.com/ngtk3/common
git clone https://github.com/ngtk3/nim-atk
git clone https://github.com/ngtk3/nim-cairo
git clone https://github.com/ngtk3/nim-chess
git clone https://github.com/ngtk3/nim-gdk3
git clone https://github.com/ngtk3/nim-gdk_pixbuf
git clone https://github.com/ngtk3/nim-gio
git clone https://github.com/ngtk3/nim-glib
git clone https://github.com/ngtk3/nim-gobject
git clone https://github.com/ngtk3/nim-gtk3
git clone https://github.com/ngtk3/nim-gtksourceview
git clone https://github.com/ngtk3/nim-pango
git clone https://github.com/ngtk3/nim-app
cd nim-chess
ln -s ~/ngtk3/nim-gio/src/gio.nim
ln -s ~/ngtk3/nim-atk/src/atk.nim
ln -s ~/ngtk3/nim-glib/src/glib.nim
ln -s ~/ngtk3/nim-gdk3/src/gdk3.nim
ln -s ~/ngtk3/nim-gtk3/src/gtk3.nim
ln -s ~/ngtk3/nim-gtksourceview/src/gtksource.nim
ln -s ~/ngtk3/nim-gobject/src/gobject.nim
ln -s ~/ngtk3/nim-cairo/src/cairo.nim
ln -s ~/ngtk3/nim-pango/src/pango.nim
ln -s ~/ngtk3/nim-pango/src/pango_cairo.nim
ln -s ~/ngtk3/nim-gdk_pixbuf/src/gdk_pixbuf.nim
nim c -d:release board.nim
cd ../nim-app
ln -s ~/ngtk3/nim-gio/src/gio.nim
ln -s ~/ngtk3/nim-atk/src/atk.nim
ln -s ~/ngtk3/nim-glib/src/glib.nim
ln -s ~/ngtk3/nim-gdk3/src/gdk3.nim
ln -s ~/ngtk3/nim-gtk3/src/gtk3.nim
ln -s ~/ngtk3/nim-gtksourceview/src/gtksource.nim
ln -s ~/ngtk3/nim-gobject/src/gobject.nim
ln -s ~/ngtk3/nim-cairo/src/cairo.nim
ln -s ~/ngtk3/nim-pango/src/pango.nim
ln -s ~/ngtk3/nim-pango/src/pango_cairo.nim
ln -s ~/ngtk3/nim-gdk_pixbuf/src/gdk_pixbuf.nim
bash prepair
bash make_it
#nim c -d:release main.nim
./main exampleapp.nim
Building the application is a bit complicated, because xml resource files are used, which have to be built in advance with gcc. We can avoid resource files and load GUI elements from plain text files if we want, see comments in the source text for that.
I have pushed latest Nim GTK3 editor to github:
http://ssalewski.de/tmp/NEd.png
Of course that is more a test and example for GTK3 than a real editor like Vim or Emacs :-)
But "Check" and "Goto Definition" from nimsuggest is really useful, method suggestions may need still some investigation.
No mimble support due to the well known name conflicts, if you really want to test it, you may use the instructions from above as for the chess game. Replace
git clone https://github.com/ngtk3/nim-chess
with
git clone https://github.com/ngtk3/NEd
go into NEd directory and execute "bash make_it".
That is a bit ugly and works only for gcc, the reason is that we have to build resource files from the XML definitions.
A Nim syntax file and the dark color scheme is included, you have to copy it where it may belong.
Not really tested yet, maybe recent cleanup has introduced errors. (It uses GSettings for storing user font selection and color scheme, unfortunately I do not know how to reset GSettings for a fresh, clean test. So it may occur that it will not work really nice for you. And I tested only with 64 bit Linux and GTK 3.18) In the next days I will add some docs to github README.
And I do indeed intend to use it for Nim coding!
Ctrl E: Mark errors Ctrl D: Goto definition, for example move text cursor over a proc name and try... Ctrl F: Find word under cursor or selected text -- press again to toggle. Ctrl Space: Method suggestions, type 1.2. and Ctrl Space when cursor is on right side of period. Or type begining of an identifier and then Ctrl Space.
Cool, I will try it out! what would it take to merge this project with Aporia?
I am a bit surprised, I know that you have your own editor called NimEdit (and you have some hope for NimX and LibUI )
Extending this one with stuff from Aporia should be not too much work. Indeed I used Aporia for an early test of my first GTK3 wrapper too years ago, and after some minor fixes it was compiling and most stuff was working on Linux. But I do not know much about Dom's recent tweaks for Mac OSX or Windows. Generally I know that GTK3 is not very popular currently.
[ADD]
reset GSettings for a fresh, clean test.
Indeed, shipping software untested or in the hope nobody will use it at all is no good idea...
rm /home/stefan/.config/dconf/user
seems to reset GSettings, and that proved a color parsing problem when user had not already selected a color scheme. I have just fixed that in file ned.nim at github by adding a few if statements, hope that it will work for now (was not a too serious problem, after selectiong a color scheme all was fine.). Later I will do some more carefully investigations. An Ascii-Doc README should be available at github soon.
In the last days I added multiview support -- looks really not that bad, at least on Linux.
Unfortunately I have to clean up the code and do some testing before I can push code to github...
http://ssalewski.de/tmp/NEd.png
And no, the window layout and content is not saved. I am not sure if Aporia may do that, but I think it would require much effort for arbitrary layout. And personally I would not use that feature, my layouts change from day to day. What I will add is saving main window size and an option to recover last saved file.
@dom96, ok, I'll look there from time to time.
@Stefan_Salewski, seems that RsvgHandle has not svg data it's nil instead... I have troubles with RSVG: https://pp.vk.me/c638428/v638428447/163f4/kS8kbEjzctU.jpg If I'll comment line 59 - I'll have the same error in line 63. File exists, I checked. Handle created, I checked... Why when trying to readclose it it writes that it's trying to read from nil ?
Asked in gtk+ and Nim channel - have not resolved. Code: https://github.com/vlad1777d/Omega_Chess
Thanks.
@Stefan_Salewski, seems that RsvgHandle has not svg data it's nil instead
Of course making such a gtk related wrapper is not fully trivial.
I think I once said that RSVG is not a very big library, so it should not be too much work to make the wrapper. Unfortunately I have never used RSVG myself, so I would have to read about it first a bit, so that I can do at least some minimal testing. So for me I assume it would be about one week fulltime. May be justified when people really need it.
[Edit]
Short remark to your bugs:
Why when trying to readclose it it writes
Are you sure that you are expected to close the file? Or maybe to unref only when you need it no longer? Well, I never used RSVG, had a short look into docs, but I am not sure. Do you have a C example?
Sure, there is no sense for you in spending time for that, that is needed to nobody. I just added there functions, that I need, I had spent on it 10 minutes. If I'll need other functions - I'll add them in the same way.
Here: https://developer.gnome.org/rsvg/2.40/rsvg-Using-RSVG-with-GdkPixbuf.html is written: """Note that the pixbuf may not be complete until rsvg_handle_close has been called.""" So I decided to do this. But if I'll comment that line, the next function, which must extract GdkPixbuf from handle, will have similar error too (attempt to read from nil). So I'm a bit confused. I'm trying to resolve this.
Generally you should check the result of functions which returns a pointer like the "newFromFile" ones. That functions generally return nil if something went wrong, in that case you can find error info in the error var. And you may look for C examples. Do you have the Krause book?
And, as GTK messages tells you, you should not reuse the same error var when an error has occurred.
I have to admit that I am currently not too much motivated doing the RSVG wrapper. Currently you are the only active NIm GTK3 developer, you may loose interest or have no spare time soon, so there will be no RSVG user left.
But maybe I will do, I may have some free days between Christmas and new year. But of course also many other task, Araq asked me to make nimble packages for GTK3...
For your bugs, maybe your wrapper is wrong, or maybe your SVG file is invalid? Can you test with another SVG file? Maybe write some C code and try to use your SVG file?
And one more remark:
You defined
RsvgObject = object of GObject
Are you sure that RsvgObject is a ptr in this way? GObject is a pointer, when it is from my modules. I did the type definitions in a other way, so I am not sure currently, and I am too tired to investigate. Of course RsvgObject has to be a ptr.
No, please, do not create RSVG wrapper =) Take your time for rest and making other useful things.
Thanks for pointing me to that. I'm confused in all that pointer-reference-object_itself stuff =) I'll try to check this tomorrow.
SVG works, I created GdkPixbuf from it successfully:
fill_cell_with_new_image(color_cells[index], "/images/cells/general_dark.svg")
proc fill_cell_with_new_image (cell:ref cell_type, image_name:string) {.discardable.} =
#[ Fills given cell's image field with specified in "image_name".
]#
var image = gtk3.newImage()
var pixbuf: gdk_pixbuf.GdkPixbuf =
gdk_pixbuf.newPixbufFromFileAtSize(os.getAppDir() & image_name, cell_size.cint(), cell_size.cint(), dummy_error)
image.setFromPixbuf(pixbuf)
cell.image = image
and all worked and displayed (I posted screenshot earlier).
I have many books on my PocketBook reader: about Java, Javascript, Python (near 7 pieces), many other (I found them in Internet for free) =) But I have no books about Nim, Gtk. Besides, the only book I read - Mark Lutz - Learning Python =)
Thanks for help and suggestion, I'll try to fix this tomorrow.
I'm confused in all that pointer-reference-object_itself stuff
I have already downloaded the source code of librsvg-2.40.16. Seems to be really a tiny lib, and the c headers contains not many strange macros, so building the wrapper should be easy. (There are bitfields used, but fortunately latest c2nim supports that :-)
I do not understand that lib well, so testing will be some work. For example I still wonder about your mentioned rsvg_handle_close (). From the API documentation: "Closes handle , to indicate that loading the image is complete. This will return TRUE if the loader closed successfully. Note that handle isn't freed until g_object_unref is called.". No idea currently.
I think the wrapper will be finished in a few days, but maybe I will just ignore testing.
I have just uploaded the initial release of nim-rsvg:
https://github.com/ngtk3/nim-rsvg
The API is really tiny, so it was not much work making the wrapper.
I have decided to remove the Rsvg prefix from data types, as we generally do. If that should give too many type name conflicts we may add that prefix again.
Currently I have only this tiny test program, it reads a SVG file and generates a PNG file. Note that we do not need the close() proc here, the close proc may be needed when proc rsvg_handle_write () is used.
import cairo
import rsvg
import glib
import gobject
const FileName = "/usr/share/gnome-chess/pieces/simple/whiteKing.svg" # you may try other files!
var
s: Surface
cr: Context
error: GError
handle: rsvg.Handle
s = imageSurfaceCreate(FORMAT.ARGB32, 1250, 1250) # that is the svg size displayed by eog!
cr = create(s)
handle = newHandle(FileName, error)
if error != nil:
echo error.message
free(error)
assert handle != nil
assert renderCairo(handle, cr)
objectUnref(handle)
discard writeToPng(s, "image.png")
destroy(cr)
destroy(s)
again I missed a book )
Stefan_Salewski, it's good news =) I had some work several days, so I'll try to test it as soon as possible =) Thank you all =)