module Layout:sig..end
The main, all-purpose graphics container.
A layout is a "box" (a rectangle) whose purpose is to place onscreen the
various elements composing the GUI. It can contain a single widget, or a list
of sub-layouts (recursively). In Bogue, we use the housing metaphor: a layout
is a house that contains either a single resident, or several rooms. Each room can be seen as a sub-house, and can contain a resident or
sub-rooms. Houses and rooms have the type Layout.t, while a resident has the type
Widget.t.
Technically, the usual metaphor in computer science is a Tree. A layout is a tree, each vertex (or node) has any number of branches (or children). A leaf (terminal node: without any child) is either empty or contains a widget. However, the tree is upside-down (as often): we think of the trunk (or top-layout) to be a the top, and the leaves at the bottom.
type t
exception Fatal_error of (t * string)
type room_content =
| |
Rooms of |
| |
Resident of |
type adjust =
| |
Fit |
| |
Width |
| |
Height |
| |
Nothing |
Not implemented.
type background
Warning, the background type corresponds actually to the Style.t
type, which means it includes color backgrounds, image patterns, corner and
shadow styles.
val color_bg : Draw.color -> backgroundConstruct a background from an RGBA color.
val opaque_bg : Draw.rgb -> backgroundConstruct a background from an RGB (ie non-transparent) color.
val style_bg : Style.t -> backgroundConstruct a background from the given Style.
val theme_bg : backgroundThis is the background constructed from the current theme's BG_COLOR.
val set_background : t -> background option -> unit
val unload_background : t -> unitFree the texture associated with the background (if any). This can be used to force recreating it.
module Resize:sig..end
Resize strategies for Layout.flat and Layout.tower
Remark: all layouts have an optional name property, which is used only
for debugging.
val empty : ?name:string ->
?background:background ->
w:int -> h:int -> unit -> tAn empty layout can reserve some space without stealing focus.
val resident : ?name:string ->
?x:int ->
?y:int ->
?w:int ->
?h:int ->
?background:background ->
?draggable:bool ->
?canvas:Draw.canvas ->
?keyboard_focus:bool -> Widget.t -> tCreate a layout (=room) from a single Widget (=resident). The content of such a layout cannot be modified.
val flat_of_w : ?name:string ->
?sep:int ->
?h:int ->
?align:Draw.align ->
?background:background ->
?widget_bg:background ->
?canvas:Draw.canvas ->
?resize:Resize.strategy ->
?clip:bool -> Widget.t list -> tHorizontal arrangement of widgets. See Layout.flat.
val tower_of_w : ?name:string ->
?sep:int ->
?w:int ->
?align:Draw.align ->
?background:background ->
?widget_bg:background ->
?canvas:Draw.canvas ->
?resize:Resize.strategy ->
?clip:bool -> Widget.t list -> tVertical arrangement of widgets. See Layout.tower.
val flat : ?name:string ->
?sep:int ->
?adjust:adjust ->
?hmargin:int ->
?vmargin:int ->
?margins:int ->
?align:Draw.align ->
?background:background ->
?shadow:Style.shadow ->
?canvas:Draw.canvas ->
?resize:Resize.strategy ->
?clip:bool -> t list -> tCreate a horizontal arrangement from a list of rooms.
sep = horizontal space between two rooms (except on the right hand side
of a room of zero width).hmargin = horizontal margin (left and right).vmargin = vertical margin (top and bottom).margins is set, then sep, hmargin and vmargin are all set to this value.val tower : ?name:string ->
?sep:int ->
?margins:int ->
?hmargin:int ->
?vmargin:int ->
?align:Draw.align ->
?adjust:adjust ->
?background:background ->
?shadow:Style.shadow ->
?canvas:Draw.canvas ->
?resize:Resize.strategy ->
?clip:bool -> t list -> tCreate a vertical arrangement from a list of rooms. See Layout.flat.
val superpose : ?w:int ->
?h:int ->
?name:string ->
?background:background ->
?canvas:Draw.canvas ->
?center:bool -> ?scale_content:bool -> t list -> tCreate a new layout by superposing a list of layouts without changing
their (x,y) position. Warning: if a room in a superpose layout is later
moved out of the bounding box, it will never get mouse focus.
Remark: when creating a house (a layout) with flat*, tower*, or
superpose, the size of the inner rooms will be automatically updated
whenever the size of the house is modified. However, as soon as one
manually sets the size or the position of a room inside this house with
Layout.set_width, Layout.setx and likes, then the room will stop reacting to
changes of the house size.
val make_clip : ?w:int ->
?scrollbar:bool ->
?scrollbar_inside:bool ->
?scrollbar_width:int ->
?on_scroll:(int -> unit) -> h:int -> t -> tClip a layout inside a smaller container and make it scrollable, and
optionally add a scrollbar widget. The on_scroll function is called
anytime the scroll is modified, with the vertical offset as
parameter.
Currently, only vertical scrolling is implemented. The ?w variable is
not used.
val xpos : t -> intget current absolute x position of the layout (relative to the top-left corner of the window). Not necessarily up-to-date.
val ypos : t -> intsee Layout.xpos
val width : t -> int
val height : t -> int
val get_size : t -> int * intget_size l is equivalent to (width l, height l)
val get_physical_size : t -> int * intmultiplies get_size by the Theme scaling factor. This gives in principle
the correct size in physical pixels, up to an error of +/- 1pixel, due to
rounding error.
val getx : t -> intCompute the relative x position of the room with respect to its house,
using animations if any. Because of this, this function should not be
called by the animation itself! Use Layout.get_oldx instead.
val get_oldx : t -> intReturn the last computed value for the relative x position of the layout.
val gety : t -> int
val get_oldy : t -> int
val is_shown : t -> bool
val widget : t -> Widget.tReturn the resident widget, or
Not_found if the layout is not a leaf.val top_house : t -> tReturn the top of the layout tree (the "house" that contains the given layout and that is not contained in another layout). It is the only layout that is directly attached to a "physical" (SDL) window.
val get_content : t -> room_content
val get_rooms : t -> t list
val has_resident : t -> boolLayouts should be modified only by the main Thread. If you want to modify
a Layout within a Widget.connection without Main priority,
you should use Sync.push, or properly lock it using
Layout.lock/Layout.unlock.
val auto_scale : t -> unitSet the layout to automatically scale its inner rooms when the layout size is modified.
val resize_keep_margins : ?margin:int ->
?min_width:int ->
?min_height:int ->
?max_width:int -> ?max_height:int -> t -> unitWhen asked to resize, the layout will keep the initial 4 margins with respect to its house.
val disable_resize : t -> unitThis makes sure that nothing is executed when someone tries to resize the
layout (that is, when the size of the layout's house changes). Warning;
working with resize functions is tricky. disable_resize should in
general be called after the layout has been installed in a house, see
comments for Layout.on_resize.
val on_resize : t -> (unit -> unit) -> uniton_resize room f will execute f () upon resizing the room's house (or
the room's window, in case the room is the top house, see Layout.top_house),
in addition to the already registered resize functions. Warning: placing
the room in another layout will likely reset the resize function (unless
you set the resize flag to Keep, see eg. Layout.flat and the remark below
that). Hence on_resize should be called after the room is hosted in its
house.
val set_width : ?keep_resize:bool ->
?check_window:bool -> ?update_bg:bool -> t -> int -> unitset_width and similar functions will not work if there is an animation
running acting of the variable we want to set (here, the width). Most of
these functions will stop the automatic resizing mechanism of the
room. Use Layout.auto_scale to reactivate it.
val set_height : ?keep_resize:bool ->
?check_window:bool -> ?update_bg:bool -> t -> int -> unit
val set_size : ?keep_resize:bool ->
?check_window:bool ->
?update_bg:bool -> ?w:int -> ?h:int -> t -> unit
val setx : ?keep_resize:bool -> t -> int -> unit
val sety : ?keep_resize:bool -> t -> int -> unit
val set_show : t -> bool -> unit
val set_shadow : t -> Style.shadow option -> unit
val fix_content : t -> unitDisable automatic resizing of the rooms inside this layout.
val fit_content : ?sep:int -> t -> unitAdapt the size of the layout (and their houses) to the disposition of the contained rooms.
val set_rooms : t -> ?sync:bool -> t list -> unitModify the layout content by replacing the former content by a new list of
rooms. Use sync=true (the default) as much as possible in order to avoid
multi-threading problems. Then the changes will be applied by the main
thread at next frame (see Sync).
val replace_room : by:t -> t -> boolReplace room by by inside its "house" in lieu and place of the initial
room. No size adjustments are made.
Using replace_room can be dangerous, because it modifies both the
room's house and by. Beware of circular dependencies...
This function cannot be used for the top_house (the window layout)
because that layout has no house. Also, the function not accept to proceed
if by already belongs to a house.
true if successful.val set_enabled : t -> bool -> unitDisable or enable a layout and all its rooms recursively. A disabled layout will not accept any mouse or keyboard focus.
val iter_unload_textures : t -> unitUse this to free the textures stored by the layout (and its children) for reducing memory. The layout can still be used without any impact, the textures will be recreated on the fly.
val lock : t -> unit
val unlock : t -> unitIn general, modifying a layout should by done by the main Thread or by
using a Sync.push. However, in case you need a layout to be modified by
different threads, you should lock it with Layout.lock. Once a layout is
locked, another lock statement from another thread will wait for the
previous lock to be removed by Layout.unlock. Locking twice by the same thread
is allowed, and will not block, which allows recursive locking, but this
practice should be avoided because it is difficult to debug. If you need a
higher level locking API, wrap the layout in a Var.t variable.
Position, size, alpha channel, and rotation of Layouts use Avar
variables and hence can be easily animated. Most predefined animations have
a default duration of 300ms.
These functions assign an animated variable if type Avar.t to one
of the properties of the layout (position, width, etc.)
val animate_x : t -> int Avar.t -> unitAssign an Avar to the layout x position.
val animate_y : t -> int Avar.t -> unit
val stop_pos : t -> unitStop animations of the variables x and y.
val animate_w : t -> int Avar.t -> unit
val animate_h : t -> int Avar.t -> unit
val animate_alpha : t -> float Avar.t -> unit
val animate_angle : t -> float Avar.t -> unitval hide : ?duration:int -> ?towards:Avar.direction -> t -> unitSee Layout.show.
val show : ?duration:int -> ?from:Avar.direction -> t -> unitDoes nothing if the layout is already fully displayed. Only the
Avar.Top and Avar.Bottom directions are currently implemented. For
these directions, hide and show do not modify the position
variables (x,y) of the layout, they use a special variable called
voffset.
val fade_in : ?duration:int ->
?from_alpha:float -> ?to_alpha:float -> t -> unitAnimate the alpha channel of the layout. Can be combined with animations
involving the other animated variables. Does not modify the show
status of the layout. By default, from_alpha=0. (transparent) and
to_alpha=1. (opaque).
val fade_out : ?duration:int ->
?from_alpha:float -> ?to_alpha:float -> ?hide:bool -> t -> unitSee Layout.fade_in. WARNING: fading out to alpha=0 results in a completely
transparent layout, but the layout is still there (it's not
"hidden"). Which means it can still get mouse focus. If you want to hide
it, then use hide=true. By default, hide=false, from_alpha is the
current alpha of the layout, and to_alpha=0.
val rotate : ?duration:int -> ?from_angle:float -> angle:float -> t -> unitRotate all widgets inside the layout around their respective centers. For
a global rotation, use a Snapshot.
val slide_in : ?duration:int ->
?from:Avar.direction -> ?dst:t -> t -> unit
val slide_to : ?duration:int -> t -> int * int -> unitslide_to room (x0,y0) will translate the room to the position
(x0,y0).
val follow_mouse : ?dx:int ->
?dy:int ->
?modifierx:(int -> int) -> ?modifiery:(int -> int) -> t -> unit
val oscillate : ?duration:int -> ?frequency:float -> int -> t -> unit
val zoom : ?duration:int ->
from_factor:float -> to_factor:float -> t -> unit
val reflat : ?align:Draw.align ->
?hmargin:int ->
?vmargin:int -> ?margins:int -> ?duration:int -> t -> unitAdjust an existing layout to arrange its rooms in a "flat" fashion, as if
they were created by Layout.flat. Will be animated if duration <> 0.
val retower : ?align:Draw.align ->
?hmargin:int ->
?vmargin:int -> ?margins:int -> ?duration:int -> t -> unitAn SDL window is created for each Layout in the list sent to
Main.create.
val window_opt : t -> Tsdl.Sdl.window optionReturn the SDL window containing the layout. It will return None if the
window was not created yet, or was previously destroyed. Note that SDL
windows are created by Main.run, not before.
val show_window : t -> unitMake the window containing the layout appear onscreen, using set_show
and Sdl.show_window. (If the layout was hidden at startup,
Sdl.show_window is not enough to display the layout: use this function
instead.)
val hide_window : t -> unitHide the window containing the layout.
val set_window_pos : t -> int * int -> unitset_window_pos layout x y sets the position of the window containing
layout to (x,y), in physical pixels. (0,0) is top-left. This should be
run after Main.create.
val get_window_pos : t -> int option * int optionReturn the window position within the desktop, in physical pixels.
val push_close : t -> unitEmit the close-window event to the window containing the layout, as if the
user clicked on the close button. This should close the window at the next
graphics frame, or execute the function registered by
Window.on_close.
val destroy_window : t -> unitEmit the destroy_window event to ask Bogue to destroy the SDL window containing the layout.
val inside : t -> int * int -> bool
val claim_keyboard_focus : t -> unit
val set_cursor : t option -> unitSet the current cursor to the default value for this layout.
val containing_widget : Widget.t -> t optionSearch for the room containing the widget, if any.