type=list layouts

<layout type="list" id="option-list">
  <append_items>

    <!-- ... -->

  </append_items>
</layout>

The contents of a layouts with type=list specify the list layout manager methods that get invoked to generate() its contents.

Creating type=list layouts

A container with a type=list creates a container that uses the list layout manager.

uigenerator5.C is an example of creating a list container using a theme file:

/*
** Copyright 2019 Double Precision, Inc.
** See COPYING for distribution information.
*/

#include "config.h"
#include <x/mpobj.H>
#include <x/exception.H>
#include <x/destroy_callback.H>
#include <x/pidinfo.H>
#include <x/config.H>
#include <x/w/main_window.H>
#include <x/w/listlayoutmanager.H>
#include <x/w/listitemhandle.H>
#include <x/w/uielements.H>
#include <x/w/uigenerators.H>
#include <x/w/screen_positions.H>
#include <x/w/callback_trigger.H>
#include <string>
#include <iostream>
#include <sstream>

#include "close_flag.H"

static inline void create_main_window(const x::w::main_window &main_window,
				      const x::w::screen_positions &pos)
{
	std::string me=x::exename(); // My path.
	size_t p=me.rfind('/');

	// Load "uigenerator5.xml" from the same directory as me

	x::w::const_uigenerators generator=
		x::w::const_uigenerators::create(me.substr(0, ++p) +
						 "uigenerator5.xml", pos);

	x::w::uielements element_factory;
	x::w::gridlayoutmanager layout=main_window->get_layoutmanager();

	layout->generate("main-window-grid",
			 generator, element_factory);

	x::w::listitemhandle h=element_factory.get_listitemhandle("option_1");

	h->on_status_update
		([]
		 (ONLY IN_THREAD,
		  const x::w::list_item_status_info_t &i)
		 {
			 if (i.selected)
				 std::cout << "Option 1" << std::endl;
		 });

	h=element_factory.get_listitemhandle("option_2");

	h->on_status_update
		([]
		 (ONLY IN_THREAD,
		  const x::w::list_item_status_info_t &i)
		 {
			 if (i.selected)
				 std::cout << "Option 2" << std::endl;
		 });
}

void uigenerator5()
{
	x::destroy_callback::base::guard guard;

	// Configuration filename where we save the window's position.

	std::string configfile=
		x::configdir("uigenerator5@examples.w.libcxx.com")
		+ "/windows";

	x::w::main_window_config config;

	auto pos=x::w::screen_positions::create(configfile);

	config.restore(pos, "main");

	auto close_flag=close_flag_ref::create();

	auto main_window=x::w::main_window
		::create(config,
			 [&]
			 (const auto &main_window)
			 {
				 create_main_window(main_window, pos);
			 },

			 x::w::new_gridlayoutmanager{});

	main_window->set_window_title("List");

	main_window->set_window_class("main",
				      "uigenerator5@examples.w.libcxx.com");

	guard(main_window->connection_mcguffin());

	main_window->on_disconnect([]
				   {
					   _exit(1);
				   });

	main_window->on_delete
		([close_flag]
		 (ONLY IN_THREAD,
		  const x::w::busy &ignore)
		 {
			 close_flag->close();
		 });

	main_window->show_all();

	close_flag->wait();

	main_window->save(pos);
	pos->save(configfile);
}

int main(int argc, char **argv)
{
	try {
		uigenerator5();
	} catch (const x::exception &e)
	{
		e->caught();
		exit(1);
	}
	return 0;
}
<?xml version="1.0" encoding="utf-8"?>
<theme version="1"
       xmlns:xi="http://www.w3.org/2003/XInclude">

  <layout id="main-window-grid" type="grid">
    <append_row>
      <name>main-window-contents</name>
    </append_row>
  </layout>

  <factory id="main-window-contents" type="grid">
    <container>
      <type>list</type>
      <name>main-window-list</name>
      <config>
	<selection_type>single_optional</selection_type>
	<columns>2</columns>
	<height>
	  <variable />
	</height>

	<row_alignment>
	  <column>0</column>
	  <valign>middle</valign>
	</row_alignment>
      </config>
    </container>
  </factory>

  <layout id="main-window-list" type="list">
    <append_items>
      <items>
	<name>header</name>
	<label> </label>
	<label type="theme_text">-- Options --</label>

	<separator />

	<name>option_1</name>
	<hierindent>1</hierindent>
	<shortcut>Alt-1</shortcut>
	<image>checkbox1</image>
	<label type="theme_text">This is option #1</label>

	<name>option_2</name>
	<hierindent>1</hierindent>
	<shortcut>Alt-2</shortcut>
	<image>checkbox1</image>
	<label type="theme_text">This is option #2</label>
      </items>
    </append_items>
  </layout>
</theme>

Initializing x::w::new_listlayoutmanagers

<container>
  <name>option-list</name>
  <type>list</type>
  <style>bullet</style>
  <config>
    <height>
      <min_rows>4</min_rows>
      <max_rows>4</max_rows>
    </height>
  </config>
</container>

The optional style's value is highlight (default) or bullet.

<config>
  <selection_type>multiple</selection_type>
</config>

An optional config element sets non-default values of the x::w::new_listlayoutmanager that creates the container:

selection_type

Sets the x::w::new_listlayoutmanager's selection_type:

<config>
  <selection_type>multiple</selection_type>
</config>

The value of a selection_type is one of: single, single_optional, multiple, or node.

height

This element invokes one of x::w::new_listlayoutmanager's overloaded height() methods:

<config>
  <height>
    <min_rows>4</min_rows>
    <max_rows>4</max_rows>
  </height>
</config>

Specifies the list height in the range of a minimum and maximum number of rows, calculated using the default list font's height.

<config>
  <height>
    <variable />
  </height>
</config>

Invokes variable_height() method.

<config>
  <height>
    <min>list-min</min>
    <preferred>list-preferred</preferred>
    <max>list-max</max>
  </height>
</config>

A height element with an x::w::dim_axis_arg value invokes height() with this explicit value.

width

Invokes one of x::w::new_listlayoutmanager's methods that specifies the list's width:

<config>
  <width>
    <default />
  </width>
</config>

This invokes the default_width() method.

<config>
  <width>
    <variable />
  </width>
</config>

This invokes the variable_width() method.

<config>
  <width>
    <min>list-width-min</min>
    <preferred>list-width-preferred</preferred>
    <max>list-width-max</max>
  </width>
</config>

A width element with an x::w::dim_axis_arg value invokes width() with this explicit value.

columns

Sets the x::w::new_listlayoutmanager's columns value:

<config>
  <columns>2</columns>
</config>

This sets columns to 2, creating a list with two columns.

requested_col_width

Initializes x::w::new_listlayoutmanager's requested_col_widths map:

<config>
  <requested_col_width>
    <column>0</column>
    <percentage>25</percentage>
  </requested_col_width>
  <requested_col_width>
    <column>1</column>
    <percentage>75</percentage>
  </requested_col_width>
</config>

Each requested_col_width contains a column number and a percentage value from 0 to 100.

col_alignment

Initializes x::w::new_listlayoutmanager's col_alignments map:

<config>
  <col_alignment>
    <column>0</column>
    <halign>right</halign>
  </col_alignment>
</config>

Each col_alignment contains a column number and an halign x::w::halign value.

row_alignment

Initializes x::w::new_listlayoutmanager's row_alignments map:

<config>
  <row_alignment>
    <column>0</column>
    <valign>middle</valign>
  </row_alignment>
</config>

Each col_alignment contains a column number and an valign x::w::valign value.

column_border

Initializes x::w::new_listlayoutmanager's column_border map:

<config>
  <column_border>
    <column>1</column>
    <border>divider</border>
  </column_border>
</config>

<!-- ... -->

<border id="divider">

  <!-- ... -->

</border>

Each column_border contains a column number and a border reference.

minimum_column_width

Initializes x::w::new_listlayoutmanager's minimum_column_widths map:

<config>
  <minimum_column_width>
    <column>0</column>
    <width>10.0</width>
  </minimum_column_width>
</config>

Each minimum_column_width contains a column number and a width value.

synchronized_columns

Initializes x::w::new_listlayoutmanager's synchronized_columns object:

<config>
  <synchronized_columns>table_columns</synchronized_columns>
</config>

All generate()d selection lists with the same synchronized_columns name have the same x::w::synchronized_axis handle. The element's name is an opaque label. x::w::synchronized_axis objects get automatically created, internally, and associated with their name.

lr_padding

Initializes x::w::new_listlayoutmanager's lr_paddings map:

<config>
  <lr_padding>
    <column>1</column>
    <left>l-padding</left>
    <right>r-padding</right>
  </lr_padding>
</config>

<!-- ... -->

<dim id="l-padding">0</dim>
<dim id="r-padding">4</dim>

Each lr_padding contains a column number; and a left and right values that reference dim elements in the theme file.

horizontal_scrollbar and vertical_scrollbar

These elements initialize the corresponding x::w::new_listlayoutmanager members:

<config>
  <vertical_scrollbar>always</vertical_scrollbar>
</config>

The horizontal_scrollbar and vertical_scrollbar elements contain x::w::scrollbar_visibility values.

appearance

Sets the x::w::new_listlayoutmanager's appearance value:

<config>
  <appearance>options</appearance>
</config>

<appearance id="options" type="list">

  <!-- ... -->

</appearance>

The value of the element specifies an appearance object of type=list.

configure_for_pane

This configures the list (or a table) in a pane container. An optional <synchronized/> flag indicates that the new list/table's columns are synchronized with another list/table in the same pane container.