0

I want to create a modal popup window, containing a number of uiedit, uimenu and uipushbutton controls. This modal popup window should appear on top of a MATLAB app (built with the app designer; not with GUIDE). The parent app UIFigure should be grayed out while the modal popup is active, similar to what happens when a uiconfirm dialog box is opened. Is there an undocumented way or some other workaround to implement this type of UI element?

The idea is that the user clicks on a "settings" button on the main app and the modal dialog pops up, while deactivating the main app controls, to allow adjustment of settings.

1 Answers1

0

Have a look at the documentation for uiwait which explains exactly how to achieve your desired effect.

In the interest of adhering to best practices for providing meaningful answers, I might approach this problem as follows.

Create a callback for the "settings" button which:

  • "grays out" desired main app's UI elements by setting their Enable property to 'off'
  • instantiates the *.mlapp you've created for the settings UI

From here, there are a number of possibilities. One approach would be to uiwait on the settings mlapp's UIFigure since, by default, it is contained in a public property of the mlapp definition. If you want to wait until the settings UI is closed, you can get away with, simply, uiwait(settingsApp.UIFigure);. Once the settings UI is closed, you can re-enable all your main app components to un-"gray" them.

For example, your "Settings button" callback could look like:

function onRequestSettings(app, event)
  % set main figure's UI elements gray
  % Assuming you want all elements gray
  set(app.UIFigure.Children, 'Enable', 'off');

  % create the settings UI by instantiating it here
  settingsApp = settingsUI();

  % wait until the figure closes
  uiwait(settingsApp.UIFigure);

  % ... SEE NOTE BELOW CODE BLOCK! ... %

  % Now that the settings UI is closed,
  % set main figure's UI elements back to normal.
  % Again, assuming all elements here
  set(app.UIFigure.Children, 'Enable', 'on');
end

Note:

While the above code block will produce your desired behavior, I have not shown how to share the data between the settings app and the main app. I assume, since you do not explicitly ask for this, that you have some way in mind. If not, I will point you to the documentation for creating multi-window apps and sharing data within app designer and also to this answer. Alternatively, you can leverage the fact that mlapps are members of the handle super-class and thus have a builtin event, ObjectBeingDestroyed. You can construct a listener (see addlistener and this) for this event and bind it to a method in your main app which then updates the main app according to changes made on the settings app.

Alternatively:

If the settingsUI is stored in a property of the main app, say app.settingsUI, and is instantiated, but perhaps hidden, by the main app's startupFcn, then instead of re-instantiating every time the "Settings button" is pressed you could simply bring it forward with figure(app.settingsUI.UIFigure);. Then make it "modal" with uiwait(app.settingsUI.UIFigure); and override the settingsUI closeRequestFcn to release the code execution halt with uiresume. The close callback could look like:

classdef settingsUI < matlab.apps.AppBase

...

  function UIFigureCloseRequest(app,event)
    % override close request to prevent deleting the app
    % hide the settings window to appear as though it was closed
    app.UIFigure.Visible = 'off';

    % resume code execution so that main app can continue to run.
    uiresume(app.UIFigure);
  end

...

end

-Cheers

Khlick
  • 260
  • 1
  • 9