Windows
Overview
The Layouts API is accessible through io.Layouts
.
Layout Operations
Current Global Layout
Available since io.Connect Desktop 9.3
To get the currently restored Global Layout, use the GetCurrentLayout()
method:
ILayout currentLayout = await io.Layouts.GetCurrentLayout();
Listing All Layouts
To get a collection of all currently available Layouts synchronously, use the List()
method:
ILayout[] layouts = io.Layouts.List();
To get a collection of all currently available Layouts asynchronously, use the ListAsync()
method:
ILayout[] layouts = await io.Layouts.ListAsync();
Specific Layout
To get a specific Layout, use the AwaitLayout()
method and pass a predicate function to find the desired Layout:
ILayout myLayout = await io.Layouts.AwaitLayout(layout => findMyLayout(layout));
Save
To save a Layout, use the Save()
method and pass a SaveOptions
object with a required Name
property. If a Layout with that name already exists, it will be replaced. The method resolves with the saved Layout:
SaveOptions options = new SaveOptions { Name = "My Layout" };
ILayout savedLayout = await io.Layouts.Save(options);
Available since io.Connect Desktop 9.1
When saving a Layout, you can specify whether to set it as the currently active Global Layout by using the SetAsCurrent
property of the SaveLayoutOptions
object:
SaveOptions options = new SaveOptions
{
Name = "My Layout",
SaveLayoutOptions = new SaveLayoutOptions { SetAsCurrent = true }
};
ILayout savedLayout = await io.Layouts.Save(options);
Restore
To restore a Layout, use the Restore()
method and pass the Layout object as a first argument. You can also pass a RestoreOptions
object as a second argument in which to specify options for the restored Layout:
RestoreOptions options = new RestoreOptions { RestoreMode = CurrentInstances.CloseAndReuse };
ILayout restoredLayout = await io.Layouts.Restore(myLayout, options);
Rename
To rename a Layout, use the Rename()
method. You must pass the Layout object to rename as a first argument and the new name for the Layout as a second argument:
await io.Layouts.Rename(myLayout, "My New Layout");
Remove
To remove a layout, use the Remove()
method and pass the Layout object to be removed:
ILayout removedLayout = await io.Layouts.Remove(myLayout);
Export & Import
You can export all currently available Layout objects with the ExportLayouts()
method. Exported Layouts can be stored to a database and then be used as restore points, or can be sent to another user and imported on their machine:
Tuple<ILayout, Value>[] exportedLayouts = await io.Layouts.ExportLayouts();
To import exported Layouts, use the ImportLayouts()
method. Specify the ImportMode
as a first argument and pass the collection of Layout objects to import as a second argument:
await io.Layouts.ImportLayouts(ImportMode.Merge, myLayouts);
The ImportMode
controls the import behavior. If set to ImportMode.Replace
, all existing Layouts will be removed and will be replaced by the imported ones. If set to ImportMode.Merge
, the imported Layouts will be added to the existing ones, replacing any of them with conflicting names.
Events
The Layouts API allows your app to react to Layout events - adding, removing, updating or renaming a Layout:
// Notifies when a new Layout is added.
io.Layouts.LayoutAdded += LayoutsManagerOnLayoutEvent;
// Notifies when a Layout is removed.
io.Layouts.LayoutRemoved += LayoutsManagerOnLayoutEvent;
// Notifies when a Layout is changed.
io.Layouts.LayoutChanged += LayoutsManagerOnLayoutEvent;
// Notifies when a Layout is renamed.
io.Layouts.LayoutRenamed += LayoutsManagerOnLayoutEvent;
private void LayoutsManagerOnLayoutEvent(object sender, LayoutEventArgs e)
{
switch (e.LayoutEvent)
{
case LayoutEvent.OnLayoutAdded:
HandleLayoutEvent(() => OnLayoutAdded(e.Layout));
break;
case LayoutEvent.OnLayoutChanged:
HandleLayoutEvent(() => OnLayoutChanged(e.Layout));
break;
case LayoutEvent.OnLayoutRemoved:
HandleLayoutEvent(() => OnLayoutRemoved(e.Layout));
break;
case LayoutEvent.OnLayoutRenamed:
HandleLayoutEvent(() => OnLayoutRenamed(e.Layout, e.PrevLayout));
break;
default:
throw new ArgumentOutOfRangeException();
}
}
Saving Context
When a Layout is saved, apps can store context data in it. When the Layout is restored, the context data is also restored and returned to the apps. Context data can be saved in all Layout types.
⚠️ Note that saving large volumes of custom data as window context (e.g., thousands of lines of table data) can lead to significant delays when saving a Layout. A Layout usually contains several (in some cases - many) apps and/or Workspaces (which can also contain many apps) and if one or more of the apps saves large amounts of context data each time a Layout is saved, this will significantly slow down the saving process. The methods for saving custom context work best with smaller amounts of data. If your app needs to save large amounts of data, you have to think about how to design this process better - for instance, you may store IDs, indices, etc., as context data, save the actual data to a database and when you restore the Layout, fetch the data using the data IDs saved as window context.
To save custom data, apps can subscribe for Layout save requests. The callback passed as an argument will be invoked when a Layout save is requested.
You can define your own typed configuration for your app:
public class AppState
{
public string SelectedClient { get; set; }
public bool DarkThemeOn { get; set; }
}
When initializing the library, you can specify the save/restore endpoint as a typed/untyped callback:
var options = new InitializeOptions();
options.SetSaveRestoreStateEndpoint(
saveState => new AppState
{
DarkThemeOn = false,
SelectedClient = "clientID"
}.AsCompletedTask(),
restoreState =>
{
AppState stateToRestore = restoreState;
// Handle the restore state.
}
);
Glue42 io = await Glue42.InitializeGlue(options);
For convenience, the save state endpoint requires a Task
, so you can save your app state asynchronously.
Alternatively, you can restore your app state by extracting it from the io.Connect library instance after it has been initialized:
var options = new InitializeOptions();
// Specify only a save state callback.
options.SetSaveRestoreStateEndpoint(
saveState => new AppState
{
DarkThemeOn = false,
SelectedClient = "some client"
}.AsCompletedTask()
);
Glue42 io = await Glue42.InitializeGlue(options);
AppState restoreState = io.GetRestoreState<AppState>();
// Handle the restore state.
If you want to return any object and work in an untyped manner, use object
instead of specifying a generic type, and use the OnSaveState
property of the library initialization object:
var options = new InitializeOptions
{
OnSaveState = saveState => new Dictionary<string, object>().AsCompletedTask<object>()
};
Glue42 io = await Glue42.InitializeGlue(options);
var restoreState = io.GetRestoreState<Dictionary<string, object>>();
Default Global Layout
io.Connect Desktop allows you to specify a default Global Layout that will be automatically loaded on start. You can get, set and clear the default Global Layout programmatically.
To get the current default Global Layout, use the GetDefaultLayout()
method:
// May return `null` if no default Global Layout has been set.
ILayout defaultLayout = await io.Layouts.GetDefaultLayout();
To set a default Global Layout, use the SelectDefaultLayout()
method and pass a Layout object as an argument:
ILayout defaultLayout = await io.Layouts.SelectDefaultLayout(myLayout);
To clear the default Global Layout, use the DeselectDefaultLayout()
method:
await io.Layouts.DeselectDefaultLayout();