[ANN] Bogue, the OCaml GUI

I’m not sure if it’s an idea you want to consider @sanette but with my GUI library (which might not be ready for public use ever :sweat_smile: and is still not ready for private use) I think I have an okay-ish solution to the extensibility problem.

Simplifying it a bit, the main widget (= drawable) type is defined like this:

type 'model drawable =
  | Empty (* No widget here, so do nothing; for example, you might give a button a child or not *)
  | Widget of {
      f_draw : (* Minimum type signature required for draw function *);
      f_size : (* Minimum type signature required for getting the size, if you want to stack one widget on top of another in a column or row for example *);
      mouse_update : (* Minimum type signature for returning a new 'model given mouse events *);
      key_update : (* Minimum type signature for returning a new 'model given keyboard events *);
    }

This method lets me implement new widgets without having to extend the drawable type. The only things I need in order to create a new widget are four functions in a Widget { … } that satisfy the Widget case. If a widget needs more information (like a margin will need to know the width and height around a child widget), you can use partial application to build up those four minimum type signatures, just like in here:
https://github.com/hummy123/reylm/blob/af0a0bd531c946b9e2d3e207175acf063f0f682e/lib/layout/margin.ml#L44 .

The event loop functions (size, draw, mouse/key update) can supply the rest of the needed to execute the Widget case in just a few simple lines of code (see here).

I think of Widget { … } as being similar to an interface in OOP land (specifying the parameters and return type of whatever functions you need) and the actual widgets like Margin which I linked before as being like object constructors which may require various parameters not essential to the interface itself (but essential to this particular object).

Here’s a very very simple (runnable but non-interactive) program showing how widgets compose for the user. I find that it works for me and it might work for you as well (or maybe the approach you already have is fine which would be cool; I also thought today about disallowing extensibility in my library to make widget state management easier for an end-user as described here but still thinking about it).

1 Like