Documentation

Main structure of a V UI application

V UI is based on gg which itself relies on sokol.

Window instance

The first declaration needed to build a V UI example is a Window instance that is in charge to launch a graphical window in your OS.

To have the full list of arguments of its constructor ui.window(), have a look at here. The main arguments are:

  • title: the title of the window
  • width and height: size of the window
  • layout: root layout (should be: ui.BoxLayout, ui.Stack and ui.CanvasLayout)
  • children (if layout not provided): an array of graphical elements (Widgets/Layouts/Components)
  • mode: initial state of the window
  • bg_color: background color of the window
Important Note
One requirement (from now but maybe improved later) for application that requires some dynamical rebuild (like resizement of window) is to put at the root of the `children` tree (as the first element of the array) a Stack layout, i.e., a Column or a Row (See Layout section).

A widget is a graphical element that is correspond to a struct which is compliant to the Widget interface:

   1  pub interface Widget {
   2  mut:
   3      ui &UI
   4      id string
   5      x int
   6      y int
   7      z_index int
   8      offset_x int
   9      offset_y int
  10      hidden bool
  11      parent Layout
  12      init(Layout)
  13      set_pos(x int, y int)
  14      propose_size(w int, h int) (int, int)
  15      size() (int, int)
  16      point_inside(x f64, y f64) bool
  17      set_visible(bool)
  18      draw()
  19      draw_device(d DrawDevice)
  20      cleanup()
  21  }

In particular, a Layout (see next tab) is a (sub)interface of Widget to arrange many Widgets. The graphical elements of a V UI application is then represented by a sort of children tree.

A Layout is an interface to represent struct elements that allow us to arrange widgets together depending on the kind of the layout:

   1  pub interface Layout {
   2      id string
   3      get_ui() &UI
   4      size() (int, int)
   5      get_children() []Widget
   6      get_subscriber() &eventbus.Subscriber
   7  mut:
   8      resize(w int, h int)
   9      update_layout()
  10      draw()
  11  }

A component is a concept introduced to define composite element build from widgets, layouts or components. Technically speaking, a Component is based on:

  1. a struct gathering all the contents needed to make the component working
  2. a constructor (similar to the widgets constructor) returning a valid widget which is most of the time a layout (dedicated to arrange many elements together)
  3. a serie of methods (generally callbacks) to manage the interactions between the differents graphical elements constituting the component.
The key point of this concept is that all the elements (widgets/layouts/components) of the new component can be linked together thanks to a field component. A possible element of a component is then compliant to the following ComponentChild interface:
   1  pub interface ComponentChild {
   2  mut:
   3      id string
   4      component voidptr
   5  }

However, a developer that wants to create a new Component has no need to know that internal representation of a component child.

This is the template to fulfill in order to create a new component called Example (name that has to be changed):

   1  [heap]
   2  pub struct ExampleComponent {
   3  pub mut:
   4  	layout    &ui.Stack // or ui.CanvasLayout
   5  	// add all the needed fields related to the Example
   6  	...
   7  }
   8  
   9  [params]
  10  pub struct ExampleParams {
  11  	// fields used for the constructor
  12  }
  13  
  14  pub fn example_stack(p ExampleParams) &ui.Stack {
  15  	// define all the widgets/components you need
  16  	...
  17  	// define the layout that arrange all the previous widgets/components
  18  	mut layout := ...
  19      // define the example component
  20  	mut ex := &ExampleComponent{
  21  		layout: layout
  22  		...
  23  	}
  24  	// connect the layout and all the widgets/components with the component
  25  	ui.component_connect(ex, layout, ....)
  26  	// return the layout that could be added to the parent children tree
  27  	return layout
  28  }
  29  
  30  // this is the function to access the component from any component child (layout or widgets/components connected to the component)  
  31  pub fn example_component(w ui.ComponentChild) &ExampleComponent {
  32  	return &ExampleComponent(w.component)
  33  }