Icon Editor

The Example

This example creates a GUI that enables the user to create or edit an icon. The figure below shows the editor.

plot of five random numbers

The Components

The GUI includes the following components:

Using the Icon Editor

These are the basic steps to create an icon:

  1. Start the icon editor with a command such as

    myicon = iconEditor('iconwidth',32,'iconheight',56);

    where the iconwidth and iconheight properties specify the icon size in pixels.

  2. Color the squares in the grid.

  3. Erase the color in some squares.

  4. Click OK to close the GUI and return, in myicon, the icon you created – as a 32-by-65-by-3 array. Click Cancel to close the GUI and return an empty array [] in myicon.

Techniques Used in the Example

This example illustrates the following GUI programming techniques:

View and Run the Completed GUI M-Files

If you are reading this in the MATLAB Help browser, you can click the following links to display the MATLAB Editor with a complete listing of the code that is discussed in the following sections.

Subfunction Summary

The icon editor example includes the callbacks listed in the following table.

Function

Description

hMainFigureWindowButtonDownFcn

Executes when the user clicks a mouse button anywhere in the GUI figure. It calls localEditColor.

hMainFigureWindowButtonUpFcn

Executes when the user releases the mouse button.

hMainFigureWindowButtonMotionFcn

Executes when the user drags the mouse anywhere in the figure with a button pressed. It calls localEditColor.

hIconFileEditCallback

Executes after the user manually changes the filename of the icon to be edited. It calls localUpdateIconPlot.

hIconFileEditButtondownFcn

Executes the first time the user clicks the Icon file edit box.

hOKButtonCallback

Executes when the user clicks the OK push button.

hCancelButtonCallback

Executes when the user clicks the Cancel push button.

hIconFileButtonCallback

Executes when the user clicks the Icon file push button . It calls localUpdateIconPlot.

The example also includes the helper functions listed in the following table.

Function

Description

localEditColor

Changes the color of an icon data point to the currently selected color. Call the function mGetColorFcn returned by the colorPalette function. It also calls localUpdateIconPlot.

localUpdateIconPlot

Updates the icon preview. It also updates the axes when an icon is read from a file.

processUserInputs

Determines if the property in a property/value pair is supported. It calls localValidateInput.

localValidateInput

Validates the value in a property/value pair.

prepareLayout

Makes changes needed for look and feel and for running on multiple platforms.

M-File Structure

The iconEditor is programmed using nested functions. Its M-file is organized in the following sequence:

  1. Comments displayed in response to the help command.

  2. Data creation. Because the example uses nested functions, defining this data at the top level makes the data accessible to all functions without having to pass them as arguments.

  3. GUI figure and component creation.

  4. Command line input processing.

  5. GUI initialization.

  6. Block execution of the program until the GUI user clicks OK or Cancel.

  7. Return output if requested.

  8. Callback definitions. These callbacks, which service the GUI components, are subfunctions of the iconEditor function and so have access to the data and component handles created at the top level, without their having to be passed as arguments.

  9. Helper function definitions. These helper functions are subfunctions of the iconEditor function and so have access to the data and component handles created at the top level, without their having to be passed as arguments.

GUI Programming Techniques

This topic explains the following GUI programming techniques as they are used in the creation of the iconEditor.

Returning Only After the User Makes a Choice

At the end of the initialization code, and just before returning, iconEditor calls uiwait with the handle of the main figure to make the GUI blocking.

% Make the GUI blocking
uiwait(hMainFigure);

% Return the edited icon CData if it is requested
mOutputArgs{1} =hMainFigure;
mOutputArgs{2} =mIconCData;
if nargout>0
    [varargout{1:nargout}] = mOutputArgs{:};
end

Placement of the call to uiwait is important. Calling uiwait stops the sequential execution of the iconEdit M-file after the GUI is initialized and just before the file would return the edited icon data.

When the user clicks the OK button, its callback, hOKButtonCallback, calls uiresume which enables the M-file to resume execution where it stopped and return the edited icon data.

function hOKButtonCallback(hObject, eventdata)
% Callback called when the OK button is pressed
    uiresume;
    delete(hMainFigure);
end

When the user clicks the Cancel button, its callback, hOCancelButtonCallback, effectively deletes the icon data then calls uiresume. This enables the M-file to resume execution where it stopped but it returns a null matrix.

function hCancelButtonCallback(hObject, eventdata)
% Callback called when the Cancel button is pressed
    mIconCData =[];
    uiresume;
    delete(hMainFigure);
end

Passing Input Arguments to a GUI

Inputs to the GUI are custom property/value pairs. iconEdit allows three such properties: IconWidth, IconHeight, and IconFile. The names are caseinsensitive.

Definition and Initialization of the Properties.   The iconEdit first defines a variable mInputArgs as varargin to accept the user input arguments.

mInputArgs = varargin;  % Command line arguments when invoking
                        % the GUI

The iconEdit function then defines the valid custom properties in a 3-by-3 cell array.

mPropertyDefs = {...    % Supported custom property/value 
                        % pairs of this GUI
               'iconwidth',   @localValidateInput, 'mIconWidth';
               'iconheight',  @localValidateInput, 'mIconHeight';
               'iconfile',    @localValidateInput, 'mIconFile'};

iconEdit then initializes the properties with default values.

mIconWidth = 16;   % Use input property 'iconwidth' to initialize
mIconHeight = 16;  % Use input property 'iconheight' to initialize
mIconFile = fullfile(matlabroot,'/toolbox/matlab/icons/');

The values of mIconWidth and mIconHeight are interpreted as pixels. The fullfile function builds a full filename from parts.

Processing the Input Arguments.   The processUserInputs helper function processes the input property/value pairs. iconEdit calls processUserInputs after the layout is complete and just before it needs the inputs to initialize the GUI.

% Process the command line input arguments supplied when 
% the GUI is invoked 
processUserInputs();
  1. processUserInputs sequences through the inputs, if any, and tries to match each property name to a string in the first column of the mPropertyDefs cell array.

  2. If it finds a match, processUserInputs assigns the value that was input for the property to its variable in the third column of the mPropertyDefs cell array.

  3. processUserInputs then calls the helper function specified in the second column of the mPropertyDefs cell array to validate the value that was passed in for the property.

Retrieving Output on Return from a GUI

If you call iconEditor with an output argument, it returns a truecolor image as an n-by-m-by-3 array.

The data definition section of the M-file creates a cell array to hold the output:

mOutputArgs = {};  % Variable for storing output when GUI returns

Following the call to uiwait, which stops the sequential execution of the M-file, iconEdit assigns the constructed icon array, mIconEdit, to the cell array mOutputArgs and then assigns mOutputArgs to varargout to return the arguments.

mOutputArgs{} =mIconCData;
if nargout>0
    [varargout{1:nargout}] = mOutputArgs{:};
end

This code is the last that iconEditor executes before returning. It executes only after clicking the OK or Cancel button triggers execution of hOKButtonCallback or hCancelButtonCallback, which call uiresume to resume execution.

Protecting a GUI from Inadvertent Access

The prepareLayout utility function protects the iconEditor from inadvertently being altered from the command line by setting the HandleVisibility properties of all the components. The iconEditor calls prepareLayout with the handle of the main figure, in the initialization section of the M-file.

% Make changes needed for proper look and feel and running on
% different platforms 
prepareLayout(hMainFigure);

prepareLayout first uses findall to retrieve the handles of all objects contained in the figure. The list of retrieved handles includes the colorPalette, which is embedded in the iconEditor, and its children. The figure's handle is passed to prepareLayout as the input argument topContainer.

allObjects = findall(topContainer);

prepareLayout then sets the HandleVisibility properties of all those objects that have one to Callback.

% Make GUI objects available to callbacks so that they cannot
% be changed accidentally by other MATLAB commands
set(allObjects(isprop(allObjects,'HandleVisibility')),...
    'HandleVisibility','Callback');

Setting HandleVisibility to Callback causes the GUI handles to be visible from within callback routines or functions invoked by callback routines, but not from within functions invoked from the command line. This ensures that command-line users cannot inadvertently alter the GUI when it is the current figure.

Running a GUI on Multiple Platforms

The prepareLayout utility function sets various properties of all the GUI components to enable the GUI to retain the correct look and feel on multiple platforms. The iconEditor calls prepareLayout with the handle of the main figure, in the initialization section of the M-file.

% Make changes needed for proper look and feel and running on
% different platforms 
prepareLayout(hMainFigure);

First, prepareLayout uses findall to retrieve the handles of all objects contained in the figure. The list of retrieved handles also includes the colorPalette, which is embedded in the iconEditor, and its children. The figure's handle is passed to findall as the input argument topContainer.

function prepareLayout(topContainer)
   ...
   allObjects = findall(topContainer);

Background Color.   The default component background color is the standard system background color on which the GUI is running. This color varies on different computer systems, e.g., the standard shade of gray on the PC differs from that on UNIX® system, and may not match the default GUI background color.

The prepareLayout function sets the background color of the GUI to be the same as the default component background color. This provides a consistent look within the GUI, as well as with other application GUIs.

It first retrieves the default component background color from the root object. Then sets the GUI background color using the figure's Color property.

defaultColor = get(0,'defaultuicontrolbackgroundcolor');
if isa(handle(topContainer),'figure')

    ...

    % Make figure color match that of GUI objects
    set(topContainer, 'Color',defaultColor);
end

Selecting Units.   The prepareLayout function decides what units to use based on the GUI's resizability. It uses strcmpi to determine the value of the GUI's Resize property. Depending on the outcome, it sets the Units properties of all the objects to either Normalized or Characters.

% Make the GUI run properly across multiple platforms by using
% the proper units
if strcmpi(get(topContainer, 'Resize'),'on')
    set(allObjects(isprop(allObjects,'Units')),...
        'Units','Normalized');
else
    set(allObjects(isprop(allObjects,'Units')),...
        'Units','Characters');
end

For a resizable figure, normalized units map the lower-left corner of the figure and of each component to (0,0) and the upper-right corner to (1.0,1.0). Because of this, component size is automatically adjusted to its parent's size when the GUI is displayed.

For a nonresizable figure, character units automatically adjusts the size and relative spacing of components as the GUI displays on different computers.

Character units are defined by characters from the default system font. The width of a character unit equals the width of the letter x in the system font. The height of a character unit is the distance between the baselines of two lines of text. Note that character units are not square.

Making a GUI Modal

iconEditor is a modal figure. Modal figures remain stacked above all normal figures and the MATLAB command window. This forces the user to respond without being able to interact with other windows. iconEditor makes the main figure modal by setting its WindowStyle property to modal.

hMainFigure = figure(...
 ...
              'WindowStyle','modal',...

See the Figure Properties in the MATLAB Function Reference documentation for more information about using the WindowStyle property.

Sharing Data Between Two GUIs

The iconEditor embeds a GUI, the colorPalette, to enable the user to select colors for the icon cells. The colorPalette returns the selected color to the iconEditor via a function handle.

The colorPalette GUI.   Like the iconEditor, the colorPalette defines a cell array, mOutputArgs, to hold its output arguments.

mOutputArgs = {};  % Variable for storing output when GUI returns

Just before returning, colorPalette assigns mOutputArgs the function handle for its getSelectedColor helper function and then assigns mOutputArgs to varargout to return the arguments.

% Return user defined output if it is requested
mOutputArgs{1} =@getSelectedColor;
if nargout>0
    [varargout{1:nargout}] = mOutputArgs{:};
end

The iconEditor executes the colorPalette's getSeclectedColor function whenever it invokes the function that colorPalette returns to it.

function color = getSelectedColor
% function returns the currently selected color in this
% colorPlatte
    color = mSelectedColor;

The iconEditor GUI.   The iconEditor function calls colorPalette only once and specifies its parent to be a panel in the iconEditor.

% Host the ColorPalette in the PaletteContainer and keep the
% function handle for getting its selected color for editing 
% icon.
mGetColorFcn = colorPalette('parent', hPaletteContainer);

This call creates the colorPalette as a component of the iconEditor and then returns a function handle that iconEditor can call to get the currently selected color.

The iconEditor's localEditColor helper function calls mGetColorFcn, the function returned by colorPalette, to execute the colorPalette's getSelectedColor function.

function localEditColor
% helper function that changes the color of an icon data 
% point to that of the currently selected color in 
% colorPalette 
    if mIsEditingIcon
        pt = get(hIconEditAxes,'currentpoint');
        x = ceil(pt(1,1));
        y = ceil(pt(1,2));
        color = mGetColorFcn();
        % update color of the selected block
        mIconCData(y, x,:) = color;
        localUpdateIconPlot();
    end
end

Achieving Proper Resize Behavior

The prepareLayout utility function sets the Units properties of all the GUI components to enable the GUI to resize correctly on multiple platforms. The iconEditor calls prepareLayout with the handle of the main figure, in the initialization section of the M-file.

prepareLayout(hMainFigure);

First, prepareLayout uses findall to retrieve the handles of all objects contained in the figure. The list of retrieved handles includes the colorPalette, which is embedded in the iconEditor, and its children. The figure's handle is passed to findall as the input argument topContainer.

function prepareLayout(topContainer)
   ...
   allObjects = findall(topContainer);

Then, prepareLayout uses strcmpi to determine if the GUI is resizable. Depending on the outcome, it sets the Units properties of all the objects to either Normalized or Characters.

if strcmpi(get(topContainer, 'Resize'),'on')
    set(allObjects(isprop(allObjects,'Units')),...
        'Units','Normalized');
else
    set(allObjects(isprop(allObjects,'Units')),...
        'Units','Characters');
end

Resizable Figure.   Normalized units map the lower-left corner of the figure and of each component to (0,0) and the upper-right corner to (1.0,1.0). Because of this, when the GUI is resized, component size is automatically changed relative its parent's size.

Nonresizable Figure.   Character units automatically adjusts the size and relative spacing of components as the GUI displays on different computers.

Character units are defined by characters from the default system font. The width of a character unit equals the width of the letter x in the system font. The height of a character unit is the distance between the baselines of two lines of text. Note that character units are not square.

  


 © 1984-2008- The MathWorks, Inc.    -   Site Help   -   Patents   -   Trademarks   -   Privacy Policy   -   Preventing Piracy   -   RSS