How to implement a button into Simulink Subsystem Mask? - matlab

As I need to specify a local variable to a Subsystem, I created a mask. Doing that I lose the easy access to the subsystem. Right-click and navigating to "Look under mask" is supposed to be too complicated.
So I thought about a workaround and built the following:
The dialog callback code behind the "Get deeper!" checkbox is:
myParameter = %Parameter set by checking Get deeper!
path = gcb(gcs);
if strcmp(get_param(gcb,'myParameter'),'on')
open_system(path,'tab');
end
Everytime when I check the box, the subsystem gets opened and also by every double click on the subsystem, in case the box was checked before. Hence the code does what it should, but thats actualy not the common way how one would realize/visualize something like this.
What I want is a button "Look under mask" in my mask - so the subsystem just gets opened by clicking on that button. Basically the button should call the function: open_system(gcb(gcs),'tab'). Looks so easy, but Simulink doesn't offer me any option to implement this. Can anybody help?
The main issue whith the current solution is also that with every execution of the model all subsystems open up, where the box is checked. That's not the idea.

Matlab 2012b adds exactly what you want: masked blocks have a button on the botton left that is a shortcut to "Look under mask".
Unfortunately, I don't think it is possible to add a button in a mask.
You may want to change your function to automatically set the "Get deeper!" checkbox off after the user clicks on it. That would avoid the automatic opening of the subsystems when the model is loaded. You could do that adding set_param(path,'myParameter','off') just after the open_system(path,'tab');
Finally, as another workaround, you may want to set the OpenFcn callback to call open_system(gcb,'tab'). This will make the system work as if it isn't masked at all. You can put two open_system calls, one to look under mask and the other to open the mask dialog box, if you prefer.

Related

Programmatic Method of Handling Matlab Dialog Windows

I have a rather large Matlab program that is GUI based. I am looking into creating automated tests for it, as the current way of checking for bugs before a release is simply using all its functionality like a user would.
I would rather not use a GUI testing program that just records clicks and what not, so I was thinking of adding testing code that would call the button callbacks directly. The problem that I have run into with this is that we have a lot of warndlg and msgbox popups, and I would like my tester code to be able to see these.
Is there any way for Matlab code to tell if a function it called created a warndlg or msgbox? If so, is there any way to click 'ok' on these popups?
In a similar vein, is it possible to handle popups that block code execution (using uiwait or an inputdlg)?
If it matters I didn't use GUIDE, and all the GUI elements are created programmatically
Two ways. The first one is more elegant
Let the functions return an extra variable and return the status of the function. For example, 1: success, 2: success with warning, 3: error...
Create some global variables and make the function change them if a warndlg or msbgbox shows up. The main window would then check if the status of the global variable.
You can tell if a warning dialog was created by looking for it's tag using the findobj function. A warning dialog created using warndlg will have the tag "Msgbox_Warning Dialog". So code like this would tell you if the warning dialog exists:
set(0,'ShowHiddenHandles', 'on')
h = findobj('Tag', 'Msgbox_Warning Dialog');
warn_exists = ~isempty(h)
set(0,'ShowHiddenHandles', 'off')
to close the warning dialog, you can call delete, like this:
delete(h)
For the message box, I would store the handle when you create a message box, then look at the children to find the buttons, then look at their callbacks. You should be able to call the callbacks to simulate picking a button.

How do I display data/information with Matlab App Designer?

I would like to display some information to the user via Matlab App Designer's GUI. I am new to this program and can't seem to find a widget that provides what I feel should be a simple function. Am I missing something? Examples would include showing the user:
The path of the file that he/she selected
Errors such as "No files detected" that are printed in a Matlab script called on by the GUI code.
Other print statements in code such as "Done!", etc that will inform the user when a process is complete.
Is there a way to capture the output in the Matlab command line and report these in a window of some sort in the GUI? Thanks in advance!
You can use a TextArea to display information for the user. Here's how I made a simple example:
Drag a button to the app in design view.
Drag in a text area also. I changed the label to Feedback.
Select the button and use the Callbacks tab in the bottom right of app designer to add a callback with the default name it gives you.
Edit the callback to contain
answer = 'what your want to display';
app.FeedbackTextArea.Value = answer;
When you push the button the text area gets filled. In your code, instead of just setting 'answer' to some string, set a variable using whatever code is dealing with your user's information. The key is to store what you want the user to see in a variable and then assign that to the "Value" parameter of the text area or other widget where you want them to see the results.

How to block GUI while function with output executes?

I am creating a MATLAB application in GUIDE and now I'm facing a problem. I need to call a function that takes a long time to execute and returns a value but while executing the function I want the GUI to wait for the returned value.
I tried with waitfor but this way I can still interact with the GUI and I can't take the returned value...
waitfor(function);
I can think of something that disables all the GUI then enables it back but I have both enabled and disabled objects...
Do you know any solution to this problem?
A simple solution is to create a modal dialog box with a message "Please wait..." just before executing your long-running function, and then to close the dialog box just after it completes. A modal dialog will be in front of the GUI, and will not allow interactions with the window behind.
It's possible for the user to click the "Close" button on the dialog, but you can override this by setting the "CloseRequestFcn" property of the dialog, so that the close button does nothing (unfortunately you can't easily hide the button).
I like the modal dialog proposed by Sam Roberts. There is no mystery and it is user friendly.
Another dirty and easy solution may be to hide the GUI completely, if it is okay:
set(hFig, 'Visible', 'off');
And set it to 'on' after done. It will be good practice to make sure to set it to 'on' in catch block, to avoid disappearing GUI due to error during execution.

Inner Workings of Unity3d's GUI.Button

I'm still pretty new to scripting in Unity3D, and I'm following along with a tutorial that uses GUI.Button() to draw a button on the screen.
I am intrigued by how this function works. Looking through the documentation, the proper use of GUI.Button is to invoke the function in an if statement and put the code to be called when the button is pushed within the if statement's block.
What I want to know is, how does Unity3D "magically" delay the code in the if statement until after the button is clicked? If it was being passed in as a callback function or something, then I could understand what was going on. Perhaps Unity is using continuations under the hood to delay the execution of the code, but then I feel like it would cause code after the if statement to be executed multiple times. I just like to understand how my code is working, and this particular function continues to remain "magical" to me.
I don't know if it's the right term, but I usually refer to such system as immediate mode GUI.
how does Unity3D "magically" delay the code in the if statement until
after the button is clicked?
GUI.Button simply returns true if a click event happened inside the button bounds during last frame. Basically calling that function you are polling: every frame for every button asking the engine if an event which regards that button (screen area) is happened.
If it was being passed in as a callback function or something, then I
could understand what was going on
You are probably used to an MVC like pattern, where you pass a controller delegate that's called when an UI event is raised from the view. This is something really different.
Perhaps Unity is using continuations under the hood to delay the
execution of the code, but then I feel like it would cause code after
the if statement to be executed multiple times.
No. The function simply returns immediately and return true only if an event happened. If returns false the code after the if won't be executed at all.
Side notes:
That kind of system is hard to maintain, especially for complex structured GUI.
It has really serious performance implications (memory allocation, 1 drawcall for UI element)
Unless you are writing an editor extension or custom inspector code, I'd stay away from it. If you want to build a menu implement your own system or use an external plugin (there are several good ones NGUI, EZGUI,..).
Unity has already announced a new integrated UI System, it should be released soon.
Good question. The unity3d gui goes through several event phases, or in the documentation
Events correspond to user input (key presses, mouse actions), or are UnityGUI layout or rendering events.
For each event OnGUI is called in the scripts; so OnGUI is potentially called multiple times per frame. Event.current corresponds to "current" event inside OnGUI call."
In OnGUI you can find out which event is currently happening with >Event.current
The following events are processed link:
Types of UnityGUI input and processing events.
-MouseDown
-MouseUp,mouse button was released
-MouseMove,Mouse was moved (editor views only)
-MouseDrag,Mouse was dragged
-KeyDown, A keyboard key was pressed
-KeyUp A keyboard key was released.
-ScrollWheel The scroll wheel was moved.
-Repaint A repaint event. One is sent every frame.
-Layout A layout event.
-DragUpdated Editor only: drag & drop operation updated.
-DragPerform Editor only: drag & drop operation performed.
-DragExited Editor only: drag & drop operation exited.
-Ignore Event should be ignored.
-Used Already processed event.
-ValidateCommand Validates a special command (e.g. copy & paste).
-ExecuteCommand Execute a special command (eg. copy & paste).
-ContextClick User has right-clicked (or control-clicked on the mac).
Unity GUI has much improved lately and is quite usefull if you want to handle things programmatically. If you want to handle things visually, i recommend looking at the plugins heisenbug refers to.
If you decide to use unity gui, i recommend using only one object with ongui, and let this object handle all your gui.

MATLAB - callback excecution of edit box

As it is referenced in MATLAB documentation for edit box uicontrol or stated in this
post, when another component or menu bar or background GUI is clicked, the edit box callback gets executed. But in my attempts to use this functionality, I haven't been able so far to see the callback execution unless there is a change of edit box text or Enter key is pressed. What I'm trying to achieve is to execute edit box callback whenever there is focus loss from edit box even when nothing has been entered. Please enlighten me about what I'm missing here and how I can do this?
Thanks in advance.
The underlying Java object has a callback called FocusLostCallback that'll do what you want - execute when the object's focus is lost, even if you changed nothing.
You'll need findjobj from the MATLAB File Exchange. Then, get the Java handle and set the callback as usual (make sure the uicontrol is visible when you try to get the Java handle):
jh = findjobj(myEditBox); % myEditBox is a uicontrol handle
set(jh, 'FocusLostCallback', #myCallback);
A more complete list of the undocumented uicontrol callbacks can be found at Yair Altman's Undocumented MATLAB blog.
This method work perfectly with single-line textbox, but it has any effect with multi-line textbox (uicontrol, style edit, max = 2)