GUI example 04

Automatically build uicontrols for runtime settings.

Allows GUI customisation by users who aren't confident GUI designers.

All of the UICONTROLS in the image below are built automatically!



This example will show how you can very easily add runtime customisation to the GUI using the framework.  You may have settings or switches that your user can manipulate at runtime to change the behaviour of your GUI. 

You could manually build all the uicontrols to do this, or you could use the feature in the GUI framework to do it for you automatically.  The fact this can be done automatically allows for people to develop backend code without requiring knowledge of how the front end code works.

This example will show:
  1. How to build the variable to input to the framework to allow it to build the settings page.
  2. How to customise the controls which are created.
  3. What the framework does with the variable and how you can use it.
The easiest way to create the settings is to build a structure which has the settings you want to add, the GUI will then build the uicontrols based on the type of variable it finds in the structure.  It expects to find:
  • Boolean - a checkbox will be created
  • char - an edit box is created
  • 1 x N cell array - a popup menu is created
  • N x 1 cell array - a listbox is created
  • Otherwise if it is numeric a edit box is created (but the internal "settings" is always numeric).
The structure you create can have sub structs - if that's the case then the code knows this is a sub setting and creates an extra listbox to allow you to select the appropriate sub field.

This is best explained via some examples:

In the example below the user has input a structure:

settings.files.setUpFiles.startDir = pwd;

settings.files.setUpFiles.configFile = mfilename;

settings.files.setUpFiles.protected = 'protected.mat';

settings.files.setUpFiles.lists = {'A.mat'; 'B.mat'; 'C.mat' };

settings.files.setUpFiles.popup = {'A.mat' 'B.mat' 'C.mat' };

settings.custom.myBoolean = true;

settings.custom.myEdit = 'a string is a string...';

settings.custom.myValue = 10;

At the top level in the struct there is two fields (files and custom), this items are placed in the top left listbox, if files is selected - the code knows that it has a sub struct (setUpFiles) so the 2nd listbox on the left is created.  Then the subfields are interpreted and all the uicontrols are created on the right side of the GUI.


Each setting can be customised, the following types of customisation are available:
  • Select a directory by changing the edit box description to be a pushbutton (see above startDir)
  • Select a file by changing the edit box description to be a pushbutton (see above configFile)
  • Set to read only (see protected above)
  • Can add your own callback for when an item changed

The settings can be retrieved at any time in your code by the following code:

    settings = Tab ( 'settings', hTab );

If you have changed the settings ( in your code) you can update it by the following:

    Tab ( 'updatesettings', hTab, settings );

At runtime when the user changes an setting in the GUI, then the internal settings variable is automatically update by the internal callback.  You can add your own global callback which will also be executed when a setting is changed (shown in the code below) as well as an individual callback for each setting.

If you setting is numeric initially, it has to be converted to a string to display in an edit box - however the code knows that it was originally numeric and hence it will be converted back to a number in the internal settings variable.


The code to add build the GUI shown above.

hFig = dialog ( 'windowstyle', 'normal', 'name', 'Matpi Website Example 4', 'resize', 'on' );

hTab = matpigui ( hFig, 'position', [0 0 1 1] );

% Create the main pages accessed via menu system

hTab.addTab ( 'Main Page', 0.2, 'enable', 'on' )

hTab.addTab ( 'SettingsPage', 0.2, 'enable', 'on' )

% hTab.toggleButtons ( 'off' );

% Build a settings struct, the code will read this struct and create the

% GUI depending on what it finds in the structure.

settings.files.setUpFiles.startDir = pwd;

settings.files.setUpFiles.configFile = mfilename;

settings.files.setUpFiles.protected = 'protected.mat';

% A list

settings.files.setUpFiles.lists = {'A.mat'; 'B.mat'; 'C.mat' };

settings.files.setUpFiles.popup = {'A.mat' 'B.mat' 'C.mat' };

settings.custom.myBoolean = true;

settings.custom.myEdit = 'a string is a string...';

settings.custom.myValue = 10;

% You can add a callback when ANY setting is altered using this method:

hTab.addSettingsUI( 'SettingsPage', settings, 'Callback', @(a,b) disp ( rand(1) ) );

% Each individual setting can be customised as shown below

hTab.customiseSettings ( 'files', 'setUpFiles', 'startDir', 'uigetdir', 1 );

hTab.customiseSettings ( 'files', 'setUpFiles', 'configFile', 'uigetfile', 1 );

hTab.customiseSettings ( 'files', 'setUpFiles', 'protected', 'readonly', 1 );

% You can also add your own callback to execute when an individual setting is changed:

hTab.customiseSettings ( 'custom', 'myBoolean', 'uiCallback', {@rand 10} );

% Add a menu

uimenu ( 'parent', hFig, 'Label', 'File' )

tMenu = uimenu ( 'parent', hFig, 'Label', 'My Pages' );

hTab.uimenu ( tMenu );

% Select the settings tab to start with

hTab.selectTab ( 'SettingsPage' )