(Note that I don't care about a native look and feel, I'm more
interested in how the code looks.)
martin
_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs
The obvious alternative to lablgtk2 is of course labltk.
I personally think that labltk is still the easiest way to build a GUI,
but many do not like Tk's look&feel.
I'm not aware of other GUI toolkits for ocaml, but I think there are also
web-based UIs.
Jacques Garrigue
>
> What are the actively developed options for writing desktop GUI apps
> in OCaml? Anything other than lablgtk2 (which, at least from a brief
> look through the examples, looks rather ugly, codewise, compared to,
> say, vala or ruby/gtk)?
What is better looking in vala or ruby/gtk ?
> I'll use lablgtk2 in a pinch, but I'm curious
> as to whether anyone has been experimenting with toolkit bindings with
> an eye towards better syntax and APIs.
What you don't like in lablgtk ?
Something I definitely does not like with lablgtk are the type errors
(but I doubt ruby/gtk is better in that respect ...; I still prefer hard-to-read
type errors than no-type-checking).
If you're under Windows, you might be interested in the CSML tool. It
allows you to build quite easily your own binding to .Net libraries. The
CSML distribution contains an example of a mini-binding to Windows
Forms; you can also see that in screenshots:
LexiFi uses CSML to build Windows Forms application, but most of our
GUIs are managed by a higher-level layer, not direct calls to Windows
Forms. As a matter of fact, we generate most of the GUIs that are
intended to show or edit structured values, automatically from OCaml
type definitions.
We have a few local extensions to the OCaml compiler that makes it
easier to build nice APIs for GUI toolkits, with a functional flavor:
implicit subtyping and generalized recursion. Hopefully, I'll be able to
blog about these extensions and how they are used for GUI programming
some day.
Alain
That might be the problem, then. I was looking at the examples in the
translation of the gtk tutorial, and a lot of it seemed like C code
translated to OCaml. Could you point me to some example of code
written using the high level API?
> The obvious alternative to lablgtk2 is of course labltk.
> I personally think that labltk is still the easiest way to build a GUI,
> but many do not like Tk's look&feel.
Does labltk have any prospect of being updated for tk 8.5? I tried
using it but discovered I'd have to install tk8.4 first.
No, I'm on linux, but CSML does look very interesting. Does it work
well with Mono?
> We have a few local extensions to the OCaml compiler that makes it easier to
> build nice APIs for GUI toolkits, with a functional flavor: implicit
> subtyping and generalized recursion. Hopefully, I'll be able to blog about
> these extensions and how they are used for GUI programming some day.
I'd love to read that when you do. I was surprised not to see much
interest in GUI DSLs in OCaml. What is generalised recursion?
martin
The LablGTK tutorial I am aware of[1] uses the high-level API. The
high-level API isn't notably higher-level than the base API in terms of
what calls are necessary, but it wraps everything up in objects and
makes the data structures nicer. The API call sequences are roughly the
same.
- Michael
1. http://wwwfun.kurims.kyoto-u.ac.jp/soft/olabl/lablgtk.html
>>
>> That might be the problem, then. I was looking at the examples in the
>> translation of the gtk tutorial, and a lot of it seemed like C code
>> translated to OCaml. Could you point me to some example of code
>> written using the high level API?
>
> The LablGTK tutorial I am aware of[1] uses the high-level API. The
> high-level API isn't notably higher-level than the base API in terms of
> what calls are necessary, but it wraps everything up in objects and
> makes the data structures nicer. The API call sequences are roughly the
> same.
>
> - Michael
>
> 1. http://wwwfun.kurims.kyoto-u.ac.jp/soft/olabl/lablgtk.html
>
It's a design decision. As the author of LablGTK said above, one of
its goals was to stay as close to possible as the original C API. This
has advantages (easy to transfer knowledge and documentation to the
OCaml side), and disadvantages (you miss on providing a nicer API that
would be possible with a more expressive language).
In the end the LablGTK API is only a bit nicer than the C API, so the
GUI part of a LablGTK program would be similar to the equivalent C
version. Unfortunately if you want a higher-level GUI library, I don't
see any viable alternative in OCaml right now.
--
[]s, Andrei Formiga
It's not complete or a full-blown DSL, but I started a small Gtk-light
module a while ago. I haven't had the time to complete it, but it
shouldn't be too difficult to modify for your needs:
http://0ok.org/cgit/cgit.cgi/gtk-light/
Here is a brief example (uses the "open Module in" syntax extension):
http://0ok.org/cgit/cgit.cgi/gtk-light/tree/basic_gui_test.ml
With OCaml 3.12 the "open Module in" could be replaced by the new "let
open Module in" or Module.(...) syntax.
Hez
Yes, CSML itself has been adapted to work with Mono and I did a few
tests (some of screenshots show Windows Forms GUIs controlled by OCaml
code, under Linux with Mono). External users reported successful uses as
well.
At some point, we tried to run our main application under Mono (the
application is mostly OCaml, plus a very small amount of C#, and a lot
of CSML to make big parts of .Net libraries available to OCaml). We
quickly realized that some widgets which we use a lot in our application
simply don't work very well under Mono. For instance, the
WebBrowser control is quite broken under Mono. This really has nothing
to do with CSML, it's just that relying on Mono only to get nice GUIs
under Linux might not be optimal.
> I'd love to read that when you do. I was surprised not to see much
> interest in GUI DSLs in OCaml. What is generalised recursion?
Being able to write things like:
lazy let rec button1 =
button ~click:(fun () -> button2 # disable) "Button1"
and button2 =
button ~click:(fun () -> button1 # disable) "Button2"
in
..
As the lazy keyword suggests, we rely on lazy evaluation to evaluate
such recursive definitions. The code above is equivalent to:
let rec button1 =
lazy (button ~click:(fun () -> (Lazy.force button2) # disable) "Button1")
and button2 =
lazy (button ~click:(fun () -> (Lazy.force button1) # disable) "Button2"
in
..
(also replacing any instance of button1, resp. button2 in ... by
Lazy.force button1, resp. Lazy.force button1).
The little extension makes it easier to define in a single big
recursive definition several widgets with associated callbacks
and mutual interactions. Without the feature, the natural thing to do
is to create widgets first and then bind events, which looks less
functional (and less local).
Alain
This sounds very much like the presentation of value recursion in Don
Syme's ML 2005 paper:
http://research.microsoft.com/apps/pubs/default.aspx?id=79951
Out of interest, is your extension based on Don's work?
>
> On Wed, Nov 24, 2010 at 4:58 AM, Yoann Padioleau <pad...@wanadoo.fr> wrote:
>>
>> What is better looking in vala or ruby/gtk ?
>>
>> What you don't like in lablgtk ?
>
> Both ruby and vala make an effort to provide nice syntactic support
> for gtk code, so that it looks like a natural part of the language.
Could you give some example of code explaining that ?
Code in vala/ruby vs same code in lablgtk.
> The OCaml code from the gtk2 tutorial looks very C-ish, whereas I was
> hoping for something closer to a GUI DSL. Jacques Garrigue has pointed
> out that there is actually both a low-level and a high-level API, so
> I've probably just been put off by the low-level code.
Here's the table packing example in ruby and ocaml:
http://ruby-gnome2.sourceforge.jp/hiki.cgi?tut-gtk2-packing-tables-demo
http://plus.kaist.ac.kr/~shoh/ocaml/lablgtk2/lablgtk2-tutorial/x509.html
They both more or less follow the C API, but the ruby code looks like
natural ruby (perhaps because ruby has a more imperative flavour than
OCaml does), whereas the OCaml code looks there should be a more
declarative, higher-level way of doing things.
Vala is currently experimenting with gtkon, a declarative layout
language that embeds vala code "islands", and is compiled into pure
vala by a preprocessor.
http://code.google.com/p/gtkaml/wiki/Gtkon
This seems like a very promising direction, though I don't know how
well an equivalent approach would work in OCaml.
Yeah, I've been thinking of that too. Hezekiah's gtk-light library
that he mentioned upthread looks promising; I'd rather contribute to
that when I get some time than start yet another effort.
> On Sat, Nov 27, 2010 at 12:39 AM, Yoann Padioleau <pad...@wanadoo.fr> wrote:
>> On Nov 24, 2010, at 1:38 AM, Martin DeMello wrote:
>>>
>>> Both ruby and vala make an effort to provide nice syntactic support
>>> for gtk code, so that it looks like a natural part of the language.
>>
>> Could you give some example of code explaining that ?
>> Code in vala/ruby vs same code in lablgtk.
>
> Here's the table packing example in ruby and ocaml:
>
> http://ruby-gnome2.sourceforge.jp/hiki.cgi?tut-gtk2-packing-tables-demo
> http://plus.kaist.ac.kr/~shoh/ocaml/lablgtk2/lablgtk2-tutorial/x509.html
I honestly don't see any difference. Where do you see "nice syntactic support
for gtk code" in the ruby version ?
>
> They both more or less follow the C API, but the ruby code looks like
> natural ruby (perhaps because ruby has a more imperative flavour than
> OCaml does), whereas the OCaml code looks there should be a more
> declarative, higher-level way of doing things.
>
> Vala is currently experimenting with gtkon, a declarative layout
> language that embeds vala code "islands", and is compiled into pure
> vala by a preprocessor.
>
> http://code.google.com/p/gtkaml/wiki/Gtkon
>
> This seems like a very promising direction,
Again, I don't see the advantage of this JSON notation vs doing the same in plain OCaml.
> though I don't know how
> well an equivalent approach would work in OCaml.
In https://github.com/facebook/pfff/blob/master/commons/gui.ml
I've modified slightly the lablgtk API to be more compositional.
http://lambda-the-ultimate.org/node/1918
On Wed, Nov 24, 2010 at 4:57 PM, Hezekiah M. Carty <hca...@atmos.umd.edu>
wrote:
As Jacques said, lablgtk's api is close to gtk's one. I also believe
that was the best solution/approach. Binding that many C functions to
ocaml is already hard enough (not that it could be made easier, the
difficulty lies in the number of functions).
The drawback is of course that writing code using lablgtk is almost as
verbose as writing it directly in C with gtk.
Something nice would probably be to share more extensions and wrappers
around lablgtk. I've noticed Maxence Guesdon had made some available as
stand-alone libraries but I'm not aware of others. Or maybe they're
scattered around and it's hard to find them.
As far as I'm concerned I've started experimenting with the concept of
"tiling" (as used by tiling window managers) and zippers of horizontal
and vertical boxes. That's pretty much what xmonad (window manager
written in haskell) does. The zipper allows to nicely track the
"current" widget.
Next in my plans is a wrapper around treeviews/listviews and gtknotebook
to map a set of widgets to a list or tabs.
And, a last (long) point, a few months ago, I asked on this list about
lablgtk and FRP; I ended up doing something myself. It turned out that
my "lablgtk-react" is something like 50 lines of code. It's really
small and there wasn't much work, once you knew the guts of lablgtk and
gtk that is.
GTK defines properties and signals. Signals are regular "something
happened"-messages and properties are values stored inside objets. Each
property also defines a "${prop_name}::notify" signal that is emitted
each time the property is modified. This is unfortunately not exposed
through lablgtk but the connect_by_name function is enough.
Now, you may wonder whether FRP is *that* nice to use. One of the nicest
thing imho is the ability to use "fold":
let zipper = React.E.fold (zipper x config t) Zipper.empty tabs in
This means it's possible to move away from imperative data structures
with all their disadvantages.
There is currently one issue however: the API is quite bad.
install_sgn_event Entry.S.activate address_bar.as_e Signal.apply1
address_bar.activate
(* Entry.S.activate is emitted by a text entry upon pressing Return
* address_bar.as_e(ntry) returns the 'Gtk.entry Gtk.obj' because
* its's not possible (yet) to use the object layer here
* address_bar.activate is a potential previous signal handler for
* active, we'd uninstall it before install another one *)
Ideally, it'll become something like:
address_bar#react#activate#event
If you want to have a look at the module, I've put it on vpaste.net[1].
It's a bit old and several things have been changed but it still shows
how things are done.
--
Adrien Nader
Hi,
Of course, I forgot to mention one point: it's not hard to create an
"zipper_of_list" function, which means it'd be possible to have
something in the spirit of:
type t =
| Widget of Gtk.widget Gtk.obj
| Zipper of t list
val vertical : ?expand:bool -> widgets:(t list) -> t
Gtk.Zipper.(of_list [
vertical [
Widget menubar;
Widget toolbar;
horizontal ~expand:true [ Widget left_pane; Widget right_pane ];
Widget statusbar;
]])
That would create a standard view with menubar, toolbar, statusbar and
a central view split vertically in two panes.
That isn't ready yet and it'll take some time but I believe it's doable. :-)
Yeah, that would be great. Even if there were several incompatible
sugar libraries, they could borrow ideas from each other.
> As far as I'm concerned I've started experimenting with the concept of
> "tiling" (as used by tiling window managers) and zippers of horizontal
> and vertical boxes. That's pretty much what xmonad (window manager
> written in haskell) does. The zipper allows to nicely track the
> "current" widget.
>
> Next in my plans is a wrapper around treeviews/listviews and gtknotebook
> to map a set of widgets to a list or tabs.
That looks pretty exciting! Do you have any code up?
martin
It looks like rubyish code. There are objects, and callbacks bound by
way of blocks. It's pretty clear how to combine those objects into
larger widgets in an idiomatic, object-functional way. Basically, what
it comes down to is that it is about as abstract as I expect ruby code
to be.
>> Vala is currently experimenting with gtkon, a declarative layout
>> language that embeds vala code "islands", and is compiled into pure
>> vala by a preprocessor.
>>
>> http://code.google.com/p/gtkaml/wiki/Gtkon
>>
>> This seems like a very promising direction,
>
> Again, I don't see the advantage of this JSON notation vs doing the same in plain OCaml.
It makes simple things simple. It lets you define the layout
declaratively, which is something I'd love to see in OCaml (and,
indeed, in ruby)
> In https://github.com/facebook/pfff/blob/master/commons/gui.ml
> I've modified slightly the lablgtk API to be more compositional.
I like that.
Chris King's project was a major influence in the syntax I chose. I
started trying to mix in some FRP with the React module, but never
completed the work. I moved Gtk-light to the forge if anyone is
interested in working with the code:
http://gtk-light.forge.ocamlcore.org/
Thanks to the thelema folks for allowing me to use some of the
Batteries code for the index page.
FWIW, I've blogged about our extensions related to laziness:
https://www.lexifi.com/blog/ocaml-extensions-lexifi-semi-implicit-laziness
-- Alain
> On Mon, Nov 29, 2010 at 3:50 AM, Adrien <camar...@gmail.com> wrote:
> >
> > Something nice would probably be to share more extensions and
> > wrappers around lablgtk. I've noticed Maxence Guesdon had made some
> > available as stand-alone libraries but I'm not aware of others. Or
> > maybe they're scattered around and it's hard to find them.
>
> Yeah, that would be great. Even if there were several incompatible
> sugar libraries, they could borrow ideas from each other.
What about a lablgtk-extra project on ocamlcore.org forge ? If some
of you think it would help sharing convenient functions and modules
above lablgtk, I'm ready to move my code into such a project.
Regards,
--
Maxence Guesdon