{"id":26,"date":"2008-08-13T16:45:53","date_gmt":"2008-08-13T21:45:53","guid":{"rendered":"https:\/\/blogs.mathworks.com\/seth\/2008\/08\/13\/dynamic-mask-dialogs\/"},"modified":"2015-03-09T17:48:15","modified_gmt":"2015-03-09T22:48:15","slug":"dynamic-mask-dialogs","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/simulink\/2008\/08\/13\/dynamic-mask-dialogs\/","title":{"rendered":"Dynamic Mask Dialogs"},"content":{"rendered":"When configuring a Simulink block, you usually use a\r\ngraphical user interface (GUI).\u00a0 In this post I\u2019m going to investigate the\r\nbasics of programming a dynamic GUI using the mask editor.\r\n\r\n<strong>The Saturation block features<\/strong>\r\n\r\nIn &lt;a\r\nhref=\"https:\/\/blogs.mathworks.com\/seth\/2008\/08\/05\/advanced-masking-concepts\/\"&gt;my\r\nlast post, I introduced the example of a Saturation block that can use\r\nfixed limits set in the mask dialog or dynamic limits set via input signals.\r\nHere is an animation of the mask GUI that configures the block for these\r\ndifferent modes.\r\n\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2008Q3\/dynamicBlock.gif\" alt=\"Animation of the saturation block mask.\" border=\"1\" \/>\r\n\r\nWhen the Upper and Lower Limit Sources are internal, the\r\nblock has a single input port.\u00a0 When the Upper\/Lower Limit Source is set to\r\nexternal, the block grows additional ports to accept signals that provide those\r\nlimits.\r\n\r\nMask dialogs can associate actions with its components.\u00a0 Most\r\nSimulink block GUIs have a standard row of buttons along the bottom. These four\r\nbuttons provide a consistent interface for Simulink blocks, and when you use\r\nthe mask editor, you get them free.\r\n<ul>\r\n\t<li>OK \u2013 apply changes and dismiss the GUI<\/li>\r\n\t<li>Cancel \u2013 abandon changes made in the GUI and do not change the\r\nblock<\/li>\r\n\t<li>Help \u2013 display documentation for the block<\/li>\r\n\t<li>Apply \u2013 apply changes made in the GUI<\/li>\r\n<\/ul>\r\nI added the other elements of the Saturation GUI through the\r\nparameters tab of the mask editor:\r\n\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2008Q3\/SaturationMaskEditor.png\" alt=\"Mask editor parameters page for the Saturation block.\" \/>\r\n\r\nEach parameter of the mask has a row in the Dialog\r\nParameters table.\u00a0 The <em>Prompt<\/em> (1) is the text displayed next to the\r\nwidget that sets the value.\u00a0 The <em>Variable<\/em> (2) is the name of the\r\nvariable set in the mask workspace when the GUI is applied.\u00a0 The <em>Type <\/em>(3)\r\ncontrols the widget used for the parameter.\u00a0 You can choose edit, checkbox or\r\npopup.\u00a0 I picked popup for the parameters Upper Limit Source and Lower Limit\r\nSource parameters.\u00a0 I set the popups (4) to display <em>internal<\/em> or <em>external<\/em>.\r\nThe Upper Limit and Lower Limit parameters use the edit type.\r\n\r\nEach of the parameters also has an <em>Evaluate<\/em> (5) and <em>Tunable<\/em>\r\n(6) setting.\u00a0 I want uplim and lowlim to have the values that are entered into\r\nthe dialog.\u00a0 If a MATLAB expression (like 'sin(x)+1') is used to set the value\r\nof the Upper Limit, I want that to be evaluated.\u00a0 I don\u2019t want the variable to\r\nhold the string that was typed into the edit field.\u00a0 Tunable means the value of\r\nthe parameter can change during the simulation.\u00a0 Upper and Lower Limits will be\r\ntunable through the dialog if internal limits are used.\u00a0 The Limit Source\r\nparameters are not tunable because they change the configuration of the block.\r\nIt is not possible to reconfigure the model structurally in mid simulation.\r\n\r\n<strong>Dialog Callbacks<\/strong>\r\n\r\nDialog callbacks (7) are called when the parameter is changed in\r\nthe mask.\u00a0 Use dialog callback for error checking and controlling the\r\nvisibility and enabled\/disabled setting of other parameters in the mask\r\ndialog.\u00a0 In the Saturation mask dialog, the Upper Limit Source and Lower Limit\r\nSource parameters fire a Dialog callback when you click on them.\u00a0 This is the\r\nmechanism for enabling and disabling the Upper Limit and Lower Limit Edit\r\nfields in the GUI.\r\n\r\n<strong><em>Key Point:<\/em><\/strong> Just like a handle graphics GUI,\r\nthe <em>Dialog callbacks<\/em> run in the MATLAB base workspace. Program the\r\ncallback as if you are running it from the MATLAB command line.\r\n\r\nHere is the uplimsrc_cb called when the uplimsrc parameter\r\nchanges:\r\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt; line-height: &lt;br \/&gt;normal; text-autospace: none;\"><span style=\"font-size: 12.0pt; font-family: 'Courier New'; &lt;br \/&gt;color: forestgreen;\">% uplimsrc_cb Dialog Callback<\/span><\/p>\r\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt; line-height: &lt;br \/&gt;normal; text-autospace: none;\"><span style=\"font-size: 12.0pt; font-family: 'Courier New'; &lt;br \/&gt;color: blue;\">function<\/span><span style=\"font-size: 12.0pt; font-family: 'Courier New'; &lt;br \/&gt;color: black;\"> uplimsrc_cb(blk)<\/span><\/p>\r\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt; line-height: &lt;br \/&gt;normal; text-autospace: none;\"><span style=\"font-size: 12.0pt; font-family: 'Courier New'; &lt;br \/&gt;color: black;\">en = get_param(blk,<\/span><span style=\"font-size: 12.0pt; &lt;br \/&gt;font-family: 'Courier New'; color: #a020f0;\">'MaskEnables'<\/span>&lt;span\r\nstyle='font-size:12.0pt;font-family:\"Courier New\";color:black'&gt;);<\/p>\r\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt; line-height: &lt;br \/&gt;normal; text-autospace: none;\"><span style=\"font-size: 12.0pt; font-family: 'Courier New'; &lt;br \/&gt;color: blue;\">switch<\/span><span style=\"font-size: 12.0pt; font-family: 'Courier New'; &lt;br \/&gt;color: black;\"> get_param(blk,<\/span><span style=\"font-size: 12.0pt; font-family: &lt;br \/&gt;'Courier New'; color: #a020f0;\">'uplimsrc'<\/span><span style=\"font-size: 12.0pt; &lt;br \/&gt;font-family: 'Courier New'; color: black;\">)<\/span><\/p>\r\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt; line-height: &lt;br \/&gt;normal; text-autospace: none;\"><span style=\"font-size: 12.0pt; font-family: 'Courier New'; &lt;br \/&gt;color: black;\">\u00a0\u00a0\u00a0 <\/span><span style=\"font-size: 12.0pt; font-family: 'Courier New'; &lt;br \/&gt;color: blue;\">case<\/span> <span style=\"font-size: 12.0pt; font-family: 'Courier New'; &lt;br \/&gt;color: #A020F0;\">'external'<\/span><\/p>\r\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt; line-height: &lt;br \/&gt;normal; text-autospace: none;\"><span style=\"font-size: 12.0pt; font-family: 'Courier New'; &lt;br \/&gt;color: black;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 en{2} = <\/span><span style=\"font-size: 12.0pt; font-family: &lt;br \/&gt;'Courier New'; color: #a020f0;\">'off'<\/span><span style=\"font-size: 12.0pt; &lt;br \/&gt;font-family: 'Courier New'; color: black;\">;<\/span><\/p>\r\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt; line-height: &lt;br \/&gt;normal; text-autospace: none;\"><span style=\"font-size: 12.0pt; font-family: 'Courier New'; &lt;br \/&gt;color: black;\">\u00a0\u00a0\u00a0 <\/span><span style=\"font-size: 12.0pt; font-family: 'Courier New'; &lt;br \/&gt;color: blue;\">case<\/span> <span style=\"font-size: 12.0pt; font-family: 'Courier New'; &lt;br \/&gt;color: #A020F0;\">'internal'<\/span><\/p>\r\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt; line-height: &lt;br \/&gt;normal; text-autospace: none;\"><span style=\"font-size: 12.0pt; font-family: 'Courier New'; &lt;br \/&gt;color: black;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 en{2} = <\/span><span style=\"font-size: 12.0pt; font-family: &lt;br \/&gt;'Courier New'; color: #a020f0;\">'on'<\/span><span style=\"font-size: 12.0pt; &lt;br \/&gt;font-family: 'Courier New'; color: black;\">;<\/span><\/p>\r\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt; line-height: &lt;br \/&gt;normal; text-autospace: none;\"><span style=\"font-size: 12.0pt; font-family: 'Courier New'; &lt;br \/&gt;color: black;\">\u00a0\u00a0\u00a0 <\/span><span style=\"font-size: 12.0pt; font-family: 'Courier New'; &lt;br \/&gt;color: blue;\">otherwise<\/span><\/p>\r\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt; line-height: &lt;br \/&gt;normal; text-autospace: none;\"><span style=\"font-size: 12.0pt; font-family: 'Courier New'; &lt;br \/&gt;color: black;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 disp(<\/span><span style=\"font-size: 12.0pt; font-family: &lt;br \/&gt;'Courier New'; color: #a020f0;\">'Should never get here'<\/span>&lt;span\r\nstyle='font-size:12.0pt;font-family:\"Courier New\";color:black'&gt;)<\/p>\r\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt; line-height: &lt;br \/&gt;normal; text-autospace: none;\"><span style=\"font-size: 12.0pt; font-family: 'Courier New'; &lt;br \/&gt;color: blue;\">end<\/span><\/p>\r\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt; line-height: &lt;br \/&gt;normal; text-autospace: none;\"><span style=\"font-size: 12.0pt; font-family: 'Courier New'; &lt;br \/&gt;color: black;\">set_param(blk,<\/span><span style=\"font-size: 12.0pt; font-family: &lt;br \/&gt;'Courier New'; color: #a020f0;\">'MaskEnables'<\/span><span style=\"font-size: 12.0pt; &lt;br \/&gt;font-family: 'Courier New'; color: black;\">,en)<\/span><\/p>\r\n&nbsp;\r\n\r\nWhen you click on the uplimsrc popup and change it, this\r\ncallback fires.\u00a0 The callback:\r\n<ul>\r\n\t<li>Gets the MaskEnables, which is a cell array of on\/off values, one\r\nfor each parameter<\/li>\r\n\t<li>Assigns the second element (corresponding to uplim) to off if\r\nuplimsrc is external, on if uplimsrc is internal<\/li>\r\n\t<li>Sets the MaskEnables to use the updated on\/off values<\/li>\r\n<\/ul>\r\nIf the block uses an external limit source, the\r\ncorresponding fixed limit is disabled.\r\n\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2008Q3\/satDialogMaskEnables.png\" alt=\"Saturation block dialog, with parameter enables on and off\" \/>\r\n\r\n<strong>Mask Dialog Callback Confusion<\/strong>\r\n\r\nI have found callbacks that modify the block contents are a\r\nmajor source of problems.\r\n\r\n<strong><em>Key Point:<\/em> <\/strong>The mask dialog callback is for modifying\r\nthe mask dialog, not the system.\r\n\r\nThe documentation on <a href=\"https:\/\/www.mathworks.com\/help\/simulink\/ug\/block-callbacks.html\">mask\u00a0callbacks<\/a> also discusses this subject.\u00a0 If you need to modify the contents\r\nof your system, do that in the Mask Initialization, which runs when you click\r\nthe Apply or OK button.\u00a0 That will be the topic of my next post.\r\n\r\n<strong>Now it\u2019s your turn<\/strong>\r\n\r\nDo you have dynamic masks? Leave a comment &lt;a\r\nhref=\"https:\/\/blogs.mathworks.com\/seth\/?p=26&amp;#comment\"&gt;here.","protected":false},"excerpt":{"rendered":"<p>When configuring a Simulink block, you usually use a\r\ngraphical user interface (GUI).\u00a0 In this post I\u2019m going to investigate the\r\nbasics of programming a dynamic GUI using the mask editor.\r\n\r\nThe... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/simulink\/2008\/08\/13\/dynamic-mask-dialogs\/\">read more >><\/a><\/p>","protected":false},"author":40,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[47],"tags":[48,441],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/26"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/users\/40"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/comments?post=26"}],"version-history":[{"count":3,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/26\/revisions"}],"predecessor-version":[{"id":4475,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/26\/revisions\/4475"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/media?parent=26"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/categories?post=26"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/tags?post=26"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}