General purpose GUI (Graphical user interface) library for Ocaml.
Bogue is a lightweight and fast GUI for developing desktop applications, games, or for easy debugging of non-GUI programs.
Bogue is entirely written in ocaml except for the hardware accelerated graphics library SDL2.
This documentation is best viewed on this page. (While on ocaml.org some links may be broken.)
Quick start
For a quick start, see Bogue's general principles, the minimal example, and the tutorials. (Again, if the links don't work, make sure you are viewing this page from here.)
The main modules are
Main
(creating, running, and quitting your app),Layout
(arranging widgets to form sophisticated interfaces like table, menus, etc.) andWidget
(the building blocks, like labels, buttons, etc.).
indexlist
List of Modules
The only thing that open Bogue
does is to bring these modules into your namespace. They have quite common names, so beware of conflict. In case of doubt, don't open Bogue
, and access the modules by using the Bogue
prefix, for instance Bogue.Widget.label
. The Widget
and Layout
modules are probably the ones that you will find yourself using the most, so it's a good idea to alias them:
module W = Bogue.Widget
module L = Bogue.Layout
Global variables with mutex.
Basic audio mixer for sound effects.
Synchronized execution queue.
Low-level graphics and colors.
Mouse and touchscreen information.
Unions of ranges of integers
Widgets are building blocks of the GUI. They also receive all events (mouse focus, etc.) and contain the intelligence of your GUI, through connections (or callbacks, see Widget.connection
). However, in order to be displayed, they need to be packed into layouts (Layout.t
).
The main module for dealing with widgets is Widget
.
Important: Each widget possesses two access levels: a frontend and a backend. The frontend has type Widget.t
and is used for creation, connections, insertion into a layout, and simple access like Widget.get_text
. The backend contains all the low-level operations to run and display the widget; it has a specific type, for instance Label.t
. Sometimes you want to access these specialized functions; for this you may obtain the backend object using the conversion (downcasting) functions: for instance Widget.get_label
.
Button widget with text or icon.
One-line text-input widget.
Creating widgets and giving life to them
Layouts
Layouts are rectangular graphical placeholders, in which you should pack all your widgets in order to display your GUI. Sophisticated gadgets are usually obtained by combining several layouts together.
The main, all-purpose graphics container.
Adjust various spacing and sizes of layouts.
Convert Bogue objects to strings for debugging.
Create an image from a Layout.
Predefined Layouts
These modules help you create commonly used layouts: lists, menus, etc.
Handle large lists by not displaying all elements at once.
Switch between layouts using Tabs.
Check list with a single choice.
Tables with sortable columns and selectable rows.
module
File
: file chooser and file monitor
Opening windows and running your app with the Bogue mainloop
Because a GUI continuously waits for user interaction, everything has to run inside a loop. You open your GUI window(s) and start the loop with Main.run
, and this is usually the last command of your Bogue code.
Sourcemodule Main : sig ... end
Control the workflow of the GUI mainloop.
Put layouts on top of others, or in new windows.
File dialog and file monitor
Example
Here is a minimal example with a label and a check box.
open Bogue
module W = Widget
module L = Layout
let main () =
let b = W.check_box () in
let l = W.label "Hello world" in
let layout = L.flat_of_w [b;l] in
let board = Bogue.of_layout layout in
Bogue.run board;;
let () =
main ();
Bogue.quit ()
This can be compiled to bytecode with
ocamlfind ocamlc -package bogue -linkpkg -o minimal -thread minimal.ml
and to native code with
ocamlfind ocamlopt -package bogue -linkpkg -o minimal -thread minimal.ml
Then execute the compiled code:
./minimal
A window should open which should look like this:
You may also evaluate this code in a Toplevel! (for instance utop
, or in an emacs
session...). Just insert
#thread;;
#require "bogue";;
at the top, then paste the example code above, and add ;;
at the end.