<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Iliya Romm &#8211; Undocumented Matlab</title>
	<atom:link href="https://undocumentedmatlab.com/articles/tag/iliya-romm/feed" rel="self" type="application/rss+xml" />
	<link>https://undocumentedmatlab.com</link>
	<description>Professional Matlab consulting, development and training</description>
	<lastBuildDate>Tue, 11 Apr 2023 09:40:02 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.2</generator>
	<item>
		<title>Matlab callbacks for uifigure JavaScript events</title>
		<link>https://undocumentedmatlab.com/articles/matlab-callbacks-for-uifigure-javascript-events?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=matlab-callbacks-for-uifigure-javascript-events</link>
					<comments>https://undocumentedmatlab.com/articles/matlab-callbacks-for-uifigure-javascript-events#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Wed, 15 Aug 2018 15:00:10 +0000</pubDate>
				<category><![CDATA[Figure window]]></category>
		<category><![CDATA[Guest bloggers]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[High risk of breaking in future versions]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[Iliya Romm]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[uifigure]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=7913</guid>

					<description><![CDATA[<p>Matlab callback code can be attached to JavaScript events in web-based uifigures. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-uifigure-javascript-events">Matlab callbacks for uifigure JavaScript events</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-java-events" rel="bookmark" title="Matlab callbacks for Java events">Matlab callbacks for Java events </a> <small>Events raised in Java code can be caught and handled in Matlab callback functions - this article explains how...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-java-events-in-r2014a" rel="bookmark" title="Matlab callbacks for Java events in R2014a">Matlab callbacks for Java events in R2014a </a> <small>R2014a changed the way in which Java objects expose events as Matlab callbacks. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/detecting-window-focus-events" rel="bookmark" title="Detecting window focus events">Detecting window focus events </a> <small>Matlab does not have any documented method to detect window focus events (gain/loss). This article describes an undocumented way to detect such events....</small></li>
<li><a href="https://undocumentedmatlab.com/articles/enabling-user-callbacks-during-zoom-pan" rel="bookmark" title="Enabling user callbacks during zoom/pan">Enabling user callbacks during zoom/pan </a> <small>Matlab zoom, pan and rotate3d modes hijack the user's figure callbacks, but this can be overridden. ...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p><i>I would like to welcome back guest blogger Iliya Romm of Israel&#8217;s Technion <a href="http://bcukurel.net.technion.ac.il" rel="nofollow" target="_blank">Turbomachinery and Heat Transfer Laboratory</a>. Today Iliya will discuss how to assign Matlab callbacks to JavaScript events in the new web-based uifigures. Other posts on customizations of web-based Matlab GUI can be <a href="https://undocumentedmatlab.com/articles/tag/uifigure" target="_blank">found here</a>.</i><br />
On several occasions (including <a href="https://undocumentedmatlab.com/articles/customizing-web-gui-uipanel" target="_blank">the previous post</a> by Khris Griffis) I came across people who were really missing the ability to have Matlab respond to various JavaScript (JS) events. While MathWorks are working on their plans to incorporate something similar to this in future releases, we&#8217;ll explore the internal tools already available, in the hopes of finding a suitable intermediate solution.<br />
Today I&#8217;d like to share a technique I&#8217;ve been experimenting with, allowing Matlab to respond to pretty much any JS event to which we can attach a listener. This is an overview of how it works:</p>
<ol>
<li>create a UIFigure with the desired contents, and add to it (at least) one more dummy control, which has an associated Matlab callback.</li>
<li>execute a JS snippet that programmatically interacts with the dummy control, whenever some event-of-interest happens, causing the Matlab callback to fire.</li>
<li>query the <code>webWindow</code>, from within the Matlab callback, to retrieve any additional information (“payload”) that the JS passed.</li>
</ol>
<p>This approach allows, for example, to easily respond to mouse events:<br />
<center><img decoding="async" src="https://undocumentedmatlab.com/images/XHDcA.gif" alt="Attaching Matlab callback to a uifigure JavaScript event" title="Attaching Matlab callback to a uifigure JavaScript event" width="80%" style="max-width:1135px;"/></center><br />
<span id="more-7913"></span><br />
Consider the code below, which demonstrates different ways of responding to JS events. To run it, save the <i>.m</i> file function below (<a href="/files/jsEventDemo.m" rel="nofollow" target="_blank">direct download link</a>) and the four accompanying <i>.js</i> <a href="#JS">files</a> in the same folder, then run <code>jsEventDemo(demoNum)</code>, where <code>demoNum</code> is 1..4. Note: this code was developed on R2018a, unfortunately I cannot guarantee it works on other releases.</p>
<pre lang="matlab">
function varargout = jsEventDemo(demoNum)
   % Handle inputs and outputs
   if ~nargin
      demoNum = 4;
   end
   if ~nargout
      varargout = {};
   end
   % Create a simple figure:
   hFig = uifigure('Position',[680,680,330,240],'Resize','off');
   hTA = uitextarea(hFig, 'Value', 'Psst... Come here...!','Editable','off');
   [hWin,idTA] = mlapptools.getWebElements(hTA);
   % Open in browser (DEBUG):
   % mlapptools.waitForFigureReady(hFig); mlapptools.unlockUIFig(hFig); pause(1);
   % web(hWin.URL,'-browser')
   % Prepare the JS command corresponding to the requested demo (1-4)
   switch demoNum
      % Demo #1: Respond to mouse events, inside JS, using "onSomething" bindings:
      case 1
         % Example from: https://dojotoolkit.org/documentation/tutorials/1.10/events/#dom-events
         jsCommand = sprintf(fileread('jsDemo1.js'), idTA.ID_val);
      % Demo #2: Respond to mouse click events, inside JS, using pub/sub:
      case 2
         % Example from: https://dojotoolkit.org/documentation/tutorials/1.10/events/#publish-subscribe
         hTA.Value = 'Click here and see what happens';
         jsCommand = sprintf(fileread('jsDemo2.js'), idTA.ID_val);
      % Demo #3: Trigger Matlab callbacks programmatically from JS by "pressing" a fake button:
      case 3
         hB = uibutton(hFig, 'Visible', 'off', 'Position', [0 0 0 0], ...
                       'ButtonPushedFcn', @fakeButtonCallback);
         [~,idB] = mlapptools.getWebElements(hB);
         jsCommand = sprintf(fileread('jsDemo3.js'), idTA.ID_val, idB.ID_val);
      % Demo 4: Trigger Matlab callbacks and include a "payload" (i.e. eventData) JSON:
      case 4
         hB = uibutton(hFig, 'Visible', 'off', 'Position', [0 0 0 0],...
                      'ButtonPushedFcn', @(varargin)smartFakeCallback(varargin{:}, hWin));
         [~,idB] = mlapptools.getWebElements(hB);
         jsCommand = sprintf(fileread('jsDemo4.js'), idTA.ID_val, idB.ID_val);
   end % switch
   % Execute the JS command
   hWin.executeJS(jsCommand);
end
% Matlab callback function used by Demo #3
function fakeButtonCallback(obj, eventData) %#ok<inusd>
   disp('Callback activated!');
   pause(2);
end
% Matlab callback function used by Demo #4
function smartFakeCallback(obj, eventData, hWin)
   % Retrieve and decode payload JSON:
   payload = jsondecode(hWin.executeJS('payload'));
   % Print payload summary to the command window:
   disp(['Responding to the fake ' eventData.EventName ...
         ' event with the payload: ' jsonencode(payload) '.']);
   % Update the TextArea
   switch char(payload.action)
      case 'enter',  act_txt = 'entered';
      case 'leave',  act_txt = 'left';
   end
   str = ["Mouse " + act_txt + ' from: '; ...
          "(" + payload.coord(1) + ',' + payload.coord(2) + ')'];
   obj.Parent.Children(2).Value = str;
end
</pre>
<p>Several thoughts:</p>
<ul>
<li>The attached <i>.js</i> files will not work by themselves, rather, they require <i><b>sprintf</b></i> to replace the <code>%s</code> with valid widget IDs. Of course, these could be made into proper JS functions.</li>
<li>Instead of loading the JS files using <i><b>fileread</b></i>, we could place the JS code directly in the <code>jsCommand</code> variable, as a Matlab string (char array)</li>
<li>I tried getting it to work with a <a href="https://www.w3schools.com/tags/tag_textarea.asp" rel="nofollow" target="_blank"><code>textarea</code> control</a>, so that we would get the payload right in the callback&#8217;s <code>eventData</code> object in Matlab, Unfortunately, I couldn&#8217;t get it to fire programmatically (solutions <a href="https://stackoverflow.com/a/36648958/3372061" rel="nofollow" target="_blank">like this</a> didn&#8217;t work). So instead, I store the payload as JSON, and retrieve it with <code>jsondecode(hWin.executeJS('payload'))</code> in the <code>smartFakeCallback</code> function.</li>
</ul>
<h3 id="JS">JavaScript files</h3>
<ol>
<li id="jsDemo1"><b>jsDemo1.js</b> (<a href="https://gist.github.com/Dev-iL/7bd222efb01b3bf9fc0ed5d5645d53e7/raw/872d3d7d00a7b2e18e87257e0ff7c2b6efaa4e45/jsDemo1.js" rel="nofollow" target="_blank">direct download link</a>):
<pre lang="javascript">
require(["dojo/on", "dojo/dom", "dojo/dom-style", "dojo/mouse"],
	function(on, dom, domStyle, mouse) {
		var myDiv = dom.byId("%s");
		on(myDiv, mouse.enter, function(evt){
			domStyle.set(myDiv, "backgroundColor", "red");
		});
		on(myDiv, mouse.leave, function(evt){
			domStyle.set(myDiv, "backgroundColor", "");
		});
	});
</pre>
</li>
<li id="jsDemo2"><b>jsDemo2.js</b> (<a href="https://gist.github.com/Dev-iL/7bd222efb01b3bf9fc0ed5d5645d53e7/raw/872d3d7d00a7b2e18e87257e0ff7c2b6efaa4e45/jsDemo2.js" rel="nofollow" target="_blank">direct download link</a>):
<pre lang="javascript">
require(["dojo/on", "dojo/topic", "dojo/dom"],
	function(on, topic, dom) {
		var myDiv = dom.byId("%s");
		on(myDiv, "click", function() {
			topic.publish("alertUser", "Your click was converted into an alert!");
		});
		topic.subscribe("alertUser", function(text){
			alert(text);
		});
	});
</pre>
</li>
<li id="jsDemo3"><b>jsDemo3.js</b> (<a href="https://gist.github.com/Dev-iL/7bd222efb01b3bf9fc0ed5d5645d53e7/raw/872d3d7d00a7b2e18e87257e0ff7c2b6efaa4e45/jsDemo3.js" rel="nofollow" target="_blank">direct download link</a>):
<pre lang="javascript">
require(["dojo/on", "dojo/dom", "dojo/dom-style", "dojo/mouse"],
	function(on, dom, domStyle, mouse) {
		var myDiv = dom.byId("%s");
		var fakeButton = dom.byId("%s");
		on(myDiv, mouse.enter, function(evt){
			fakeButton.click();
		});
	});
</pre>
</li>
<li id="jsDemo4"><b>jsDemo4.js</b> (<a href="https://gist.github.com/Dev-iL/7bd222efb01b3bf9fc0ed5d5645d53e7/raw/872d3d7d00a7b2e18e87257e0ff7c2b6efaa4e45/jsDemo4.js" rel="nofollow" target="_blank">direct download link</a>):
<pre lang="javascript">
var payload = [];
require(["dojo/on", "dojo/dom", "dojo/topic", "dojo/mouse"],
	function(on, dom, topic, mouse) {
		var myDiv = dom.byId("%s");
		var fakeButton = dom.byId("%s");
		topic.subscribe("sendToMatlab", function(data){
			payload = data;
			fakeButton.click();
		});
		on(myDiv, mouse.enter, function(evt){
			data = {action: "enter",
				coord: [evt.clientX, evt.clientY]};
			topic.publish("sendToMatlab", data);
		});
		on(myDiv, mouse.leave, function(evt){
			data = {action: "leave",
				coord: [evt.clientX, evt.clientY]};
			topic.publish("sendToMatlab", data);
		});
	});
</pre>
</li>
</ol>
<h3 id="Conclusions">Conclusions</h3>
<p>As you can see, this opens some interesting possibilities, and I encourage you to experiment with them yourself! This feature will likely be added to the <a href="https://github.com/StackOverflowMATLABchat/mlapptools" rel="nofollow" target="_blank"><code>mlapptools</code> toolbox</a> as soon as an intuitive API is conceived.<br />
If you have any comments or questions about the code above, or just want to tell me how you harnessed this mechanism to upgrade your uifigure (I would love to hear about it!), feel free to leave a message below <a href="https://gist.github.com/Dev-iL/7bd222efb01b3bf9fc0ed5d5645d53e7" rel="nofollow" target="_blank">the gist</a> on which this post is based (this way I get notifications!).</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-uifigure-javascript-events">Matlab callbacks for uifigure JavaScript events</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-java-events" rel="bookmark" title="Matlab callbacks for Java events">Matlab callbacks for Java events </a> <small>Events raised in Java code can be caught and handled in Matlab callback functions - this article explains how...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-java-events-in-r2014a" rel="bookmark" title="Matlab callbacks for Java events in R2014a">Matlab callbacks for Java events in R2014a </a> <small>R2014a changed the way in which Java objects expose events as Matlab callbacks. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/detecting-window-focus-events" rel="bookmark" title="Detecting window focus events">Detecting window focus events </a> <small>Matlab does not have any documented method to detect window focus events (gain/loss). This article describes an undocumented way to detect such events....</small></li>
<li><a href="https://undocumentedmatlab.com/articles/enabling-user-callbacks-during-zoom-pan" rel="bookmark" title="Enabling user callbacks during zoom/pan">Enabling user callbacks during zoom/pan </a> <small>Matlab zoom, pan and rotate3d modes hijack the user's figure callbacks, but this can be overridden. ...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/matlab-callbacks-for-uifigure-javascript-events/feed</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Customizing web-GUI uipanel</title>
		<link>https://undocumentedmatlab.com/articles/customizing-web-gui-uipanel?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=customizing-web-gui-uipanel</link>
					<comments>https://undocumentedmatlab.com/articles/customizing-web-gui-uipanel#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Wed, 01 Aug 2018 18:00:13 +0000</pubDate>
				<category><![CDATA[Guest bloggers]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[High risk of breaking in future versions]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[AppDesigner]]></category>
		<category><![CDATA[Iliya Romm]]></category>
		<category><![CDATA[Khris Griffis]]></category>
		<category><![CDATA[uifigure]]></category>
		<category><![CDATA[uipanel]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=7804</guid>

					<description><![CDATA[<p>We can customize Matlab's new web-based GUI  panels in many interesting ways. Here's how... </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/customizing-web-gui-uipanel">Customizing web-GUI uipanel</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-3" rel="bookmark" title="Customizing uifigures part 3">Customizing uifigures part 3 </a> <small>As I have repeatedly posted in recent years, Matlab is advancing towards web-based GUI. The basic underlying technology is more-or-less stable: an HTML/Javascript webpage that is created-on-the-fly and rendered in a stripped-down browser window (based on Chromium-based jxBrowser in recent...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-2" rel="bookmark" title="Customizing uifigures part 2">Customizing uifigures part 2 </a> <small>Matlab's new web-based uifigures can be customized using custom CSS and Javascript code. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-matlab-uipanels" rel="bookmark" title="Customizing Matlab uipanels">Customizing Matlab uipanels </a> <small>Matlab uipanel controls can be customized using Java in ways that are impossible with plain Matlab. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-axes-part-3-backdrop" rel="bookmark" title="Customizing axes part 3 &#8211; Backdrop">Customizing axes part 3 &#8211; Backdrop </a> <small>Matlab HG2 axes can be customized in many different ways. This article explains some of the undocumented aspects. ...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p><i>I would like to introduce guest blogger <a href="https://github.com/Khlick" rel="nofollow" target="_blank">Khris Griffis</a>. Today, Khris will continue the series of posts on <a href="https://undocumentedmatlab.com/articles/tag/uifigure" target="_blank">web-based uifigure customization</a> with an article showing how to create scrollable/customizable panels in web-based uifigures. This post follows <a href="https://undocumentedmatlab.com/articles/scrollable-gui-panels" target="_blank">last-week&#8217;s article</a>, about placing controls/axes within a scroll-panel in non-web (Java-based) figures. Users interested in advanced aspects and insights on the development roadmap of web-based Matlab GUI should also read <a href="https://blogs.mathworks.com/loren/2018/07/25/the-state-of-app-building-in-matlab" rel="nofollow" target="_blank">Loren Shure&#8217;s blog post from last week</a>.</i></p>
<h3 id="Motivation">Motivation</h3>
<p>As a retinal physiologist, I spend a lot of time in Matlab creating GUIs to visualize and analyze electrophysiological data. The data often requires a lot of processing and quality control checks before it can be used for interpretation and publication. Consequently, I end up with many control elements taking up precious space on my GUI.<br />
In Java-based (legacy/GUIDE) figures, this wasn&#8217;t a huge problem because, depending on what GUI components I needed, I could use a pure Matlab approach (a child panel within a parent panel, with a couple of control sliders moving the child panel around), or a number of Java approaches (which are always more fun; Yair <a href="https://undocumentedmatlab.com/articles/scrollable-gui-panels" target="_blank">described such an approach</a> last week).<br />
Unfortunately, the web-based (App-Designer) figure framework doesn&#8217;t support Java, and the pure/documented Matlab approach just doesn&#8217;t look good or function very well:<br />
<!--
If you're like me, you've once (or twice) queried your favorite search engine with "<i>Matlab scrolling uipanel</i>" and found 2 useful methods: a pure Matlab approach and <a href="https://undocumentedmatlab.com/articles/scrollable-gui-panels" target="_blank">a fun Java approach</a> (sticking objects in a <code>JScrollPane</code>, as explained in last week's post). Now, we read <i>Undocumented Matlab</i>, so we typically opt for the Java approach and our app is beautiful and the world is right... and countless hours of my life will go completely unnoticed by everyone using my app. But then the internet gets fast enough, servers get big enough, or for whatever reason, browser-/web-based apps are now <i>the</i> thing, so The Mathworks Inc. went and developed the <i><b>uifigure</b></i> to, you know, catch up.
The problem is, the new web framework eliminates our ability to use the Java approach and severely dampens the aesthetic of a pure Matlab approach (a child panel within a parent panel, with a couple of control sliders moving the child panel around). And that approach was already pretty ugly, if you care about that kind of stuff. So how can we make a scrolling <i><b>uipanel</b></i> to hold all these fancy, new <i><b><a href="https://www.mathworks.com/help/matlab/ref/uiknob.html" rel="nofollow" target="_blank">uiknob</a></b></i> controls?
--><br />
<center style="font-size:12px;"><img fetchpriority="high" decoding="async" src="https://undocumentedmatlab.com/images/uipanel_badscrolls.png" alt="AppDesigner uislider is not a good scrollbar, no matter what we do to it!" title="AppDesigner uislider is not a good scrollbar, no matter what we do to it!" width="473" height="187" /><br />
AppDesigner <i><b>uislider</b></i> is not a good scrollbar, no matter what we do to it!</center><br />
Fortunately, the new web framework allows us to use HTML, CSS and JavaScript (JS) to modify elements in the <i><b>uifigure</b></i>, i.e. its web-page <a href="https://en.wikipedia.org/wiki/Document_Object_Model" rel="nofollow" target="_blank">DOM</a>. It turns out that the <i><b>uipanel</b></i> object is essentially just a <code>&lt;div&gt;</code> with a Matlab-designed CSS style. We can customize it with little effort.<br />
The main goal here is to create a scrollable customizable <i><b>uipanel</b></i> containing many uicontrol elements, which could look something like this:<br />
<center style="font-size:12px;"><img decoding="async" src="https://undocumentedmatlab.com/images/uipanel_ADfig_1.png" alt="Running app demo" title="Running app demo" width="450" height="355" style="max-width:804px;"/></center><br />
<span id="more-7804"></span></p>
<h3 id="Example">A simple command-window example</h3>
<p>Since we are building on the series of <i><b>uifigure</b></i> customizations, I expect you have already read the preceding related <i>Undocumented Matlab</i> posts:</p>
<ol>
<li><a href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-1" target="_blank">Customizing uifigures part 1</a></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-2" target="_blank">Customizing uifigures part 2</a></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-3" target="_blank">Customizing uifigures part 3</a></li>
</ol>
<p>Also, I <i>highly recommend</i> cloning (or at least downloading) the <a href="https://github.com/StackOverflowMATLABchat/mlapptools" rel="nofollow" target="_blank">mlapptools toolbox</a> repo on Github (thanks <a href="http://bcukurel.net.technion.ac.il" rel="nofollow" target="_blank">Iliya Romm</a> et al.). We will use it to simplify life today.<br />
<!--
Alright, let's say your GUI calls for a scroll-panel full of knobs, because who doesn't love having a plethora of knobs around?
<center><img decoding="async" src="https://undocumentedmatlab.com/images/uipanel_scrollApp.gif" alt="A scrollable panel can hide control widgets easily!" title="A scrollable panel can hide control widgets easily!" width="80%" style="max-width:822px;" /></center>
--><br />
Using the <code>mlapptools</code> toolbox, we need just a few lines of code to set up a scrollable panel. The important thing is knowing how big the panel needs to be to hold all of our control objects. Once we know this, we simply set the panel&#8217;s <b>Position</b> property accordingly. Then we can use simple CSS to display scrollbars and define the viewing dimensions.<br />
For example, if we need 260px in width by 720px in height to hold our control widgets, but only have 200px height available, we can solve this problem in 3 steps:</p>
<ol>
<li>Set the <i><b>uipanel</b></i>&#8216;s <b>Dimension</b> property to be 260px wide by 720px tall.</li>
<li>Set the viewing height using <code>mlapptools.setStyle(scrollPane,'height','200px')</code> for the panel&#8217;s CSS <code>height</code> style attribute.</li>
<li>Display the vertical scrollbar by calling <code>mlapptools.setStyle(scrollPane,'overflow-y','scroll')</code> for the panel&#8217;s CSS <code>overflow-y='scroll'</code> style attribute.</li>
</ol>
<pre lang="matlab">
% Create the figure
fig = uifigure('Name', 'Scroll Panel Test');
% Place a uipanel on the figure, color it for fun
scrollPane = uipanel(fig, 'BackgroundColor', [0.5,0.4,1]);
% Define the space requirements for the controls
totalWidth  = 260; %px
totalHeight = 720; %px
viewHeight  = 200; %px
% STEP 1: set the uipanel's Position property to the required dimensions
scrollPane.Position(3) = totalWidth;  % WIDTH
scrollPane.Position(4) = totalHeight; % HEIGHT
% STEP 2: set the viewing height
mlapptools.setStyle(scrollPane, 'height', sprintf('%dpx', viewHeight));
% STEP 3: display the vertical scrollbar
mlapptools.setStyle(scrollPane, 'overflow-y', 'scroll');
% Add control elements into the uipanel
...
</pre>
<p><center style="font-size:12px;"><img decoding="async" src="https://undocumentedmatlab.com/images/uipanel_exampleFig.png" alt="Example scrollable uipanel in a Matlab uifigure" title="Example scrollable uipanel in a Matlab uifigure" width="70%" style="max-width:450px;"/><!-- 619px --><br />
Example scrollable uipanel in a Matlab uifigure</center><br />
Because this is a web-based GUI, notice that you can simply hover your mouse over the panel and scroll with your scroll wheel. Awesome, right?<br />
Note that the CSS <code>height</code>/<code>width</code> style attributes don&#8217;t affect the actual size of our panel, just how much of the panel we can see at once (&#8220;viewport&#8221;).<br />
The CSS <code>overflow</code> style attribute has a number of options. For example, <code>setStyle(scrollPane,'overflow','auto')</code> causes scrollbars to automatically hide when the viewing area is larger than panel&#8217;s dimensions. Review the <a href="https://www.w3schools.com/css/css_overflow.asp" rel="nofollow" target="_blank">CSS <code>overflow</code> attribute</a> to learn about other related settings that affect the panel&#8217;s behavior.</p>
<h3 id="Scrollbars">Styling the scrollbars</h3>
<p>The <code>mlapptools</code> toolbox utilizes <i>dojo.js</i> to query the DOM and set styles, which is essentially setting inline styles on the DOM element, i.e. <code>&lt;div ... style="color: red;background:#FEFEFE;..."&gt; ... &lt;/div&gt;</code>. This has the added benefit of overriding any CSS classes Matlab is imposing on the DOM (see <a href="https://css-tricks.com/precedence-css-order-css-matters" rel="nofollow" target="_blank">CSS precedence</a>). We can inject our own classes into the page&#8217;s <code>&lt;head&gt;</code> tag and then use <code>dojo.setClass()</code> to apply our classes to specific GUI elements. For example, we can style our bland scrollbars by using CSS to define a custom <code>scrollpane</code> style class:</p>
<pre lang="css">
/* CSS To stylize the scrollbar */
.scrollpane::-webkit-scrollbar {
  width: 20px;
}
/* Track */
.scrollpane::-webkit-scrollbar-track {
  background-color: white;
  box-shadow: inset 0 0 5px white;
  border-radius: 10px;
}
/* Handle */
.scrollpane::-webkit-scrollbar-thumb {
  background: red;
  border-radius: 10px;
}
/* Handle on hover */
.scrollpane::-webkit-scrollbar-thumb:hover {
  background: #b30000;
}
</pre>
<p>To get the CSS into the document header, we need to first convert (&#8220;stringify&#8221;) it in Matlab:</p>
<pre lang="matlab">
% CSS styles 'stringified' for MATLAB
%  note that the whole style tag is wrapped in single quotes, that is required!
%  i.e. '<style>...</style>' which prints to the command window as:
%   ''<style>...</style>''
cssText = [...
  '''<style>\n', ...
  '  .scrollpane::-webkit-scrollbar {\n', ...
  '    width: 20px;\n', ...
  '  }\n', ...
  '  /* Track */\n', ...
  '  .scrollpane::-webkit-scrollbar-track {\n', ...
  '    background-color: white;\n', ...
  '    box-shadow: inset 0 0 5px white;\n', ...
  '    border-radius: 10px;\n', ...
  '  }\n', ...
  '  /* Handle */\n', ...
  '  .scrollpane::-webkit-scrollbar-thumb {\n', ...
  '    background: red; \n', ...
  '    border-radius: 10px;\n', ...
  '  }\n', ...
  '  /* Handle on hover */\n', ...
  '  .scrollpane::-webkit-scrollbar-thumb:hover {\n', ...
  '    background: #b30000; \n', ...
  '  }\n', ...
  '</style>''' ...
  ];
</pre>
<p>As explained in <a href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-1" target="_blank">Customizing uifigures part 1</a>, we can execute JavaScript (JS) commands through the <code>webWindow</code> object. To simplify it, we use the method from <a href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-2" target="_blank">Customizing uifigures part 2</a> to obtain the <code>webWindow</code> object for our GUI window and and use the <code>executeJS()</code> method to add our HTML into the document&#8217;s <code>&lt;head&gt;</code> tag. It is worth checking out the properties and methods of <a href="https://www.w3schools.com/jsref/dom_obj_document.asp" rel="nofollow" target="_blank">the JS <code>document</code> object</a>.</p>
<pre lang="matlab">
% get the webWindow object
webWindow = mlapptools.getWebWindow(fig);
% inject the CSS
webWindow.executeJS(['document.head.innerHTML += ',cssText]);
</pre>
<p>Now the tricky part is that we have to assign our new CSS <code>scrollpane</code> class to our <i><b>uipanel</b></i>. We need 2 things: the <code>webWindow</code> object and the <code>data-tag</code> (our panel&#8217;s unique ID) attribute.</p>
<pre lang="matlab">
% get the uipanel data-tag attr.
[webWindow, panelID] = mlapptools.getWebElements(scrollPane);
%make a dojo.js statement (use addClass method)
setClassString = sprintf(...
  'dojo.addClass(dojo.query("[%s = ''%s'']")[0], "%s")',...
  panelID.ID_attr, panelID.ID_val, 'scrollpane');
% add class to DOM element
webWindow.executeJS(setClassString);
</pre>
<p><center style="font-size:12px;"><img decoding="async" src="https://undocumentedmatlab.com/images/uipanel_styledScroll.gif" alt="The results of applying our scrollpane CSS style on our scroll-pane's scrollbars" title="The results of applying our scrollpane CSS style on our scroll-pane's scrollbars" width="70%" style="max-width:450px;"/><!-- 566px --><br />
The results of applying our <code>scrollpane</code> CSS style on our scroll-pane&#8217;s scrollbars</center><br />
Note: Unfortunately, because of CSS precedence rules, we may have to use the dreaded <a href="https://www.smashingmagazine.com/2010/11/the-important-css-declaration-how-and-when-to-use-it" rel="nofollow" target="_blank"><code>!important</code> CSS qualifier</a> to get the desired effect. So if the result doesn&#8217;t match your expectations, try adding <code>!important</code> to the CSS class attributes.</p>
<h3 id="uipanel">Styling the <i>uipanel</i></h3>
<p>Each <i><b>uipanel</b></i> appears to be composed of 4 <code>&lt;div&gt;</code> HTML elements: a wrapper, internal container for the panel title, a separator, and the panel&#8217;s body (contents). We first use <code>mlapptools.getWebElements()</code> to get the <code>data-tag</code> ID for the wrapper node. We can then apply styles to the wrapper, or any child node, with CSS and JS.<br />
For example, we can use CSS3 patterns (such as one in <a href="http://lea.verou.me/css3patterns/#" rel="nofollow" target="_blank">this CSS3 gallery</a>) to liven up our panel. We can also use CSS to define a block element that will replace the title container with some static text. The CSS below would be appended to the <code>cssText</code> string we made for styling the scrollbars above:</p>
<pre lang="css">
/* DECORATE THE BACKGROUND */
/* Stars modified from: http://lea.verou.me/css3patterns/#stars */
.scrollpane {
  overflow: auto;
  background:
  linear-gradient(324deg, #232927 4%,   transparent 4%)   -70px 43px,
  linear-gradient( 36deg, #232927 4%,   transparent 4%)    30px 43px,
  linear-gradient( 72deg, #e3d7bf 8.5%, transparent 8.5%)  30px 43px,
  linear-gradient(288deg, #e3d7bf 8.5%, transparent 8.5%) -70px 43px,
  linear-gradient(216deg, #e3d7bf 7.5%, transparent 7.5%) -70px 23px,
  linear-gradient(144deg, #e3d7bf 7.5%, transparent 7.5%)  30px 23px,
  linear-gradient(324deg, #232927 4%,   transparent 4%)   -20px 93px,
  linear-gradient( 36deg, #232927 4%,   transparent 4%)    80px 93px,
  linear-gradient( 72deg, #e3d7bf 8.5%, transparent 8.5%)  80px 93px,
  linear-gradient(288deg, #e3d7bf 8.5%, transparent 8.5%) -20px 93px,
  linear-gradient(216deg, #e3d7bf 7.5%, transparent 7.5%) -20px 73px,
  linear-gradient(144deg, #e3d7bf 7.5%, transparent 7.5%)  80px 73px !important;
  background-color: #232977 !important;
  background-size: 100px 100px !important;
}
/* STYLES TO CENTER A TEXT BLOCK ON A WHITE SEMI-TRANSPARENT BACKGROUND BLOCK */
/* White block div */
.blockdiv {
  color: black;
  font: 25px Arial, sans-serif !important;
  background: rgba(255,255,255,0.75);
  width: 100%;
  height: 30px;
}
/* Text container centered in .blockdiv */
.textdiv {
  position: relative;
  float: left;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
</pre>
<p>To insert a static text element and its container, we can create a small JS routine that creates parent and child nodes that replace the panel&#8217;s title container:</p>
<pre lang="matlab">
% Make a nodeID string to make the JS call more generic
nodeID = sprintf('''[%s="%s"]''', panelID.ID_attr, panelID.ID_val);
% JS that creates a div within a div, each with their own classes
% The inner div gets the text and is centered within the outer div
% These elements are added before the node MATLAB will use for any controls
% added to scrollPane
js = sprintf( ...
  [ ...
    'var d = document.createElement("div");', ...
    'var t = document.createElement("div");', ...
    'd.classList.add("blockdiv");',...
    't.classList.add("textdiv");', ...
    't.innerHTML= "Some Static Text";', ...
    'd.appendChild(t);', ...
    'document.querySelectorAll(%s)[0]',...
    '.replaceChild(d,document.querySelectorAll(%s)[0].firstChild);' ...
  ], ...
  nodeID, nodeID ...
);
% execute the JS
webWindow.executeJS(js);
</pre>
<p><center style="font-size:12px;"><img decoding="async" src="https://undocumentedmatlab.com/images/uipanel_bgScroll.gif" alt="Panel background and static elements" title="Panel background and static elements" width="70%" style="max-width:450px;"/><!-- 566px --><br />
Panel background and static elements</center><br />
It seems to me that this approach might help to make lighter-weight apps, instead of having to make all those <i><b>app.Label</b></i> objects in Matlab&#8217;s App-Designer.</p>
<h3 id="Recap">Quick recap</h3>
<p>So let&#8217;s restate the process:</p>
<ol>
<li>Create a <i><b>uipanel</b></i> with the <b>Position</b> property set accordingly large enough for your control elements.</li>
<li>Use <code>mlapptools.setStyle()</code> to set the <a href="https://www.w3schools.com/css/css_overflow.asp" rel="nofollow" target="_blank"><code>overflow</code> style attribute</a> as desired.</li>
<li>Use <code>mlapptools.setStyle()</code> to set the <code>width</code> and/or <code>height</code> style attributes to the viewing size (this is how big the viewing area of the panel needs to be in order to fit nicely in your app).</li>
<li>Add your control elements with the scrolling <i><b>uipanel</b></i> as the parent.</li>
<li>If you want some special styles, create a stylesheet and inject it into the <code>&lt;head&gt;</code> and be sure to add the class to your panel&#8217;s HTML <code>classList</code>.</li>
</ol>
<p>The order of items 2-4 are not really important. You just need to ensure that the panel is large enough (via its <b>Position</b> property) to include all your elements/controls.<br />
I really hope that one day soon MathWorks will add CSS and JS hooks to <i><b>uifigure</b></i> GUI components (perhaps as settable <b>CSS</b>/<b>JS</b> properties that accept strings?), so that Matlab users could attach their own CSS and JS customizations directly within AppDesigner, without having to go through such undocumented hoops as I&#8217;ve shown here. In Loren Shure&#8217;s latest blog post, Matlab product manager <a href="https://blogs.mathworks.com/loren/2018/07/25/the-state-of-app-building-in-matlab/#573b536f-26bc-4a14-8d6b-38ed3c88b8d6" rel="nofollow" target="_blank">Dave Garisson indicated</a> that this is indeed planned for a near-future Matlab release (at least for JS, but hopefully also for CSS):</p>
<blockquote><p>&#8220;we are also investigating ways to provide a documented solution for integrating 3rd party JavaScript components in MATLAB apps.&#8221;</p></blockquote>
<h3 id="Example">A complete working example</h3>
<p>I created a complete working example in Matlab&#8217;s App Designer while figuring this whole thing out. The code (<i>CWE.m</i>) can be <a href="https://github.com/Khlick/matlabUiHacks/blob/master/scrollingUIPanel/CWE.m" rel="nofollow" target="_blank">downloaded here</a>, and then run directly from Matlab&#8217;s command window. Alternatively, the corresponding App Designer file (<i>CWE.mlapp</i>) can be <a href="https://github.com/Khlick/matlabUiHacks/blob/master/scrollingUIPanel/CWE.mlapp" rel="nofollow" target="_blank">downloaded here</a>. You are welcome to use/adapt the code in your own project. Just to be clear, I love wild colors and crazy themes, but I don&#8217;t recommend going this overboard for a real project.<br />
<center style="font-size:12px;"><img decoding="async" src="https://undocumentedmatlab.com/images/uipanel_ADfig_1.png" alt="Running app demo" title="Running app demo" width="80%" style="max-width:804px;"/><br />
Running app demo</center><br />
<!--


<h3 id="hijack">Hijacking the uipanel altogether</h3>


In the previous example, we replaced the <code>&lt;div&gt;</code> container for the title part of the <i><b>uipanel</b></i>. We can insert other types of DOM nodes into the <i><b>uipanel</b></i> as well, for example a JS-generated table.
Every <i><b>uifigure</b></i> is essentially a web page running within a browser. Using JS, we can query the <a href="https://www.w3schools.com/js/js_window_navigator.asp" rel="nofollow" target="_blank"><code>navigator</code> object</a>, which contains a lot of information on the browser (<a href="http://help.dottoro.com/ljcsokrr.php" rel="nofollow" target="_blank">see here</a>). These <code>navigator</code> properties can be displayed in a JS-generated table within a Matlab <i><b>uipanel</b></i> (<a href="https://undocumentedmatlab.com/files/browserInfo.m" target="_blank">downloadable source code</a>):
<center style="font-size:12px;"><img decoding="async" src="https://undocumentedmatlab.com/images/uipanel_matlabBrowserInfo.gif" alt="HTML table built with JS from the navigator object" title="HTML table built with JS from the navigator object" width="80%" style="max-width:700px;"/>
HTML table built with JS from the navigator object</center>
Note that these <code>navigator</code> properties correspond to my specific Matlab R2018a installation:


<pre lang="matlab">
>> version %MATLAB
    '9.4.0.813654 (R2018a)'
>> mlapptools.aboutJSLibs()  % display the loaded JS
  struct with fields:
        dojo: '1.11.2.91fa0cb'
    react_js: '0.14.7'
</pre>


--><br />
I can&#8217;t thank Yair enough for suggesting that I turn this tip into a guest post for you readers. And I want to give a huge thank you to you, the reader, for persevering all the way to the end of this post&#8230;<br />
Cheers!<br />
-Khris<br />
<b><u>Addendum September 17, 2018</u></b>: Scrolling panels in uifigures are now a fully-supported documented functionality via the new <a href="https://www.mathworks.com/help/matlab/ref/matlab.ui.container.tree.scroll.html" rel="nofollow" target="_blank"><i><b>scroll</b></i></a> function and <a href="https://www.mathworks.com/help/matlab/ref/matlab.ui.figureappd-properties.html#propname_Scrollable" rel="nofollow" target="_blank"><b>Scrollable</b></a> property, starting with Matlab release R2018b. You can still use the mechanism described above, which also works for older Matlab releases.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/customizing-web-gui-uipanel">Customizing web-GUI uipanel</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-3" rel="bookmark" title="Customizing uifigures part 3">Customizing uifigures part 3 </a> <small>As I have repeatedly posted in recent years, Matlab is advancing towards web-based GUI. The basic underlying technology is more-or-less stable: an HTML/Javascript webpage that is created-on-the-fly and rendered in a stripped-down browser window (based on Chromium-based jxBrowser in recent...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-2" rel="bookmark" title="Customizing uifigures part 2">Customizing uifigures part 2 </a> <small>Matlab's new web-based uifigures can be customized using custom CSS and Javascript code. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-matlab-uipanels" rel="bookmark" title="Customizing Matlab uipanels">Customizing Matlab uipanels </a> <small>Matlab uipanel controls can be customized using Java in ways that are impossible with plain Matlab. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-axes-part-3-backdrop" rel="bookmark" title="Customizing axes part 3 &#8211; Backdrop">Customizing axes part 3 &#8211; Backdrop </a> <small>Matlab HG2 axes can be customized in many different ways. This article explains some of the undocumented aspects. ...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/customizing-web-gui-uipanel/feed</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Customizing uifigures part 3</title>
		<link>https://undocumentedmatlab.com/articles/customizing-uifigures-part-3?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=customizing-uifigures-part-3</link>
					<comments>https://undocumentedmatlab.com/articles/customizing-uifigures-part-3#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Mon, 27 Nov 2017 15:00:24 +0000</pubDate>
				<category><![CDATA[Figure window]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[High risk of breaking in future versions]]></category>
		<category><![CDATA[UI controls]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[AppDesigner]]></category>
		<category><![CDATA[Iliya Romm]]></category>
		<category><![CDATA[uifigure]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=7169</guid>

					<description><![CDATA[<p>As I have repeatedly posted in recent years, Matlab is advancing towards web-based GUI. The basic underlying technology is more-or-less stable: an HTML/Javascript webpage that is created-on-the-fly and rendered in a stripped-down browser window (based on Chromium-based jxBrowser in recent years). However, the exact mechanism by which the controls (&#8220;widgets&#8221;) are actually converted into visible [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-3">Customizing uifigures part 3</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-2" rel="bookmark" title="Customizing uifigures part 2">Customizing uifigures part 2 </a> <small>Matlab's new web-based uifigures can be customized using custom CSS and Javascript code. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-1" rel="bookmark" title="Customizing uifigures part 1">Customizing uifigures part 1 </a> <small>Matlab's new web-based uifigures can be customized in a variety of undocumented ways. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-web-gui-uipanel" rel="bookmark" title="Customizing web-GUI uipanel">Customizing web-GUI uipanel </a> <small>We can customize Matlab's new web-based GUI panels in many interesting ways. Here's how... ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-uifigure-javascript-events" rel="bookmark" title="Matlab callbacks for uifigure JavaScript events">Matlab callbacks for uifigure JavaScript events </a> <small>Matlab callback code can be attached to JavaScript events in web-based uifigures. ...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>As I have repeatedly posted in recent years, Matlab is advancing towards web-based GUI. The basic underlying technology is more-or-less stable: an HTML/Javascript webpage that is created-on-the-fly and rendered in a stripped-down browser window (based on Chromium-based <a href="https://www.teamdev.com/jxbrowser" rel="nofollow" target="_blank">jxBrowser</a> in recent years). However, the exact mechanism by which the controls (&#8220;widgets&#8221;) are actually converted into visible components (currently based on the <a href="https://dojotoolkit.org" rel="nofollow" target="_blank">Dojo toolkit</a> and its Dijit UI library) and interact with Matlab (i.e., the internal Matlab class structures that interact with the browser and Dojo) is still undergoing changes and is not quite as stable.<br />
Customization hacks reported on this blog last year (<a href="/articles/customizing-uifigures-part-1" target="_blank">part 1</a>, <a href="/articles/customizing-uifigures-part-2" target="_blank">part 2</a>) may fail in some cases due to the changing nature of the undocumented internals. Some examples are the way by which we can extract the uifigure&#8217;s URL (which <a href="/articles/customizing-uifigures-part-2#comment-407215" target="_blank">changed in R2017a</a>), the ability to display and debug uifigures in a standard webbrowser with associated dev tools (which seems to have stopped working in R2017b), and the way by which we can extract the Dijit reference of displayed uicontrols.<br />
Greatly assisting in this respect is Iliya Romm, who was the guest blogger for <a href="/articles/customizing-uifigures-part-2" target="_blank">part 2</a> of this series last year. Iliya co-authored the open-source (GitHub) <a href="https://github.com/StackOverflowMATLABchat/mlapptools" rel="nofollow" target="_blank">mlapptools toolbox</a>, which enables accessing and customizing uifigure components using standard CSS, without users having to bother about the ugly hacks discussed in the previous parts of the series. This toolbox is really just a single Matlab class (<code>mlapptools</code>), contained within a single m-file (<i>mlapptools.m</i>). In addition to this class, the toolbox includes a <i>README.md</i> mark-down usage documentation, and two demo functions, <i>DOMdemoGUI.m</i> and <i>TableDemo.m</i>.<br />
Here is the effect of using <i>TableDemo</i>, that shows how we can customize individual uitable cells (each uitable cell is a separate Dijit widget that can be customized individually):<br />
<center><figure style="width: 363px" class="wp-caption aligncenter"><img decoding="async" alt="CSS customizations of uifigure components" src="https://undocumentedmatlab.com/images/uifigure_uitable_colors.png" title="CSS customizations of uifigure components" width="363" height="188" /><figcaption class="wp-caption-text">CSS customizations of uifigure components</figcaption></figure></center><br />
<span id="more-7169"></span><br />
The <i>mlapptools</i> class contains several static methods that can be used individually:</p>
<ul>
<li><i><b>textAlign</b>(uielement, alignment)</i> &#8211; Modify text horizontal alignment (<code>'left'</code>, <code>'center'</code>, <code>'right'</code>, <code>'justify'</code> or <code>'initial'</code>)</li>
<li><i><b>fontWeight</b>(uielement, weight)</i> &#8211; Modify font weight (<code>'normal'</code>, <code>'bold'</code>, <code>'bolder'</code>, <code>'lighter'</code> or <code>'initial'</code>), depending on availability in the font-face used</li>
<li><i><b>fontColor</b>(uielement, color)</i> &#8211; Modify font color (e.g. <code>'red'</code>, <code>'#ff0000'</code>, <code>'rgb(255,0,0)'</code> or <a href="https://www.w3.org/TR/css3-color/" rel="nofollow" target="_blank">other variants</a>)</li>
<li><i><b>setStyle</b>(uielement, styleAttr, styleValue)</i> &#8211; Modify a specified <a href="https://www.w3schools.com/cssref/" rel="nofollow" target="_blank">CSS style</a> attribute</li>
<li><i><b>aboutDojo</b>()</i> &#8211; Return version information about the Dojo toolkit</li>
<li><i><b>getHTML</b>(hFig)</i> &#8211; Return the full HTML code of a uifigure</li>
<li><i><b>getWebWindow</b>(hFig)</i> &#8211; Return a webwindow handle from a uifigure handle</li>
<li><i><b>getWebElements </b>(hControl)</i> &#8211; Return a webwindow handle and a widget ID for the specified uicontrol handle</li>
<li><i><b>getWidgetList</b>(hFig, verboseFlag)</i> &#8211; Return a cell-array of structs containing information about all widgets in the uifigure</li>
<li><i><b>getWidgetInfo</b>(hWebwindow, widgetId, verboseFlag)</i> &#8211; Return information about a specific dijit widget</li>
<li><i><b>setTimeout</b>(hFig, seconds)</i> &#8211; Override the default timeout (=5 secs) for dojo commands, for a specific uifigure</li>
</ul>
<p>A few simple usage examples:</p>
<pre lang="matlab">
mlapptools.fontColor(hButton,'red')  % set red text color
mlapptools.fontWeight(hButton,'bold')  % set bold text font
mlapptools.setStyle(hButton,'border','2px solid blue')  % add a 2-pixel solid blue border
mlapptools.setStyle(hButton,'background-image','url(https://www.mathworks.com/etc/designs/mathworks/img/pic-header-mathworks-logo.svg)')  % add background image
</pre>
<p>Once you download <i>mlapptools</i> and add its location to the Matlab path, you can use it in any web-based GUI that you create, either programmatically or with Add-Designer.<br />
The <i>mlapptools</i> is quite well written and documented, so if you are interested in the inner workings I urge you to take a look at this class&#8217;s private methods. For example, to understand how a Matlab uicontrol handle is converted into a Dojo widget-id, which is then used with the built-in <i>dojo.style()</i> Javascript function to modify the CSS attributes of the HTML <code>&lt;div&gt;</code> or <code>&lt;span&gt;</code> that are the control&#8217;s visual representation on the webpage. An explanation of the underlying mechanism can be found in <a href="/articles/customizing-uifigures-part-2" target="_blank">part 2</a> of this series of articles on uifigure customizations. Note that the <i>mlapptools</i> code is newer than the article and contains some new concepts that were not covered in that article, for example searching through Dijit&#8217;s registry of displayed widgets.<br />
<b>Note</b>: web-based GUI is often referred to as &#8220;App-Designed&#8221; (AD) GUI, because using the Matlab App Designer is the typical way to create and customize such GUIs. However, just as great-looking GUIs could be created programmatically rather than with GUIDE, so too can web-based GUIS be created programmatically, using regular built-in Matlab commands such as <i><b>uifigure</b></i>, <i><b>uibutton</b></i> and <i><b>uitable</b></i> (an example of such programmatic GUI creation can be found in Iliya&#8217;s <i>TableDemo.m</i>, discussed above). For this reason, I believe that the new GUIs should be referred to as &#8220;uifigures&#8221; or &#8220;web GUIs&#8221;, and not as &#8220;AD GUIs&#8221;.<br />
If you have any feature requests or bugs related to <i>mlapptools</i>, please report them on its <a href="https://github.com/StackOverflowMATLABchat/mlapptools/issues" rel="nofollow" target="_blank">GitHub issues page</a>. For anything else, please add a comment below.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-3">Customizing uifigures part 3</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-2" rel="bookmark" title="Customizing uifigures part 2">Customizing uifigures part 2 </a> <small>Matlab's new web-based uifigures can be customized using custom CSS and Javascript code. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-1" rel="bookmark" title="Customizing uifigures part 1">Customizing uifigures part 1 </a> <small>Matlab's new web-based uifigures can be customized in a variety of undocumented ways. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-web-gui-uipanel" rel="bookmark" title="Customizing web-GUI uipanel">Customizing web-GUI uipanel </a> <small>We can customize Matlab's new web-based GUI panels in many interesting ways. Here's how... ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-uifigure-javascript-events" rel="bookmark" title="Matlab callbacks for uifigure JavaScript events">Matlab callbacks for uifigure JavaScript events </a> <small>Matlab callback code can be attached to JavaScript events in web-based uifigures. ...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/customizing-uifigures-part-3/feed</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Customizing uifigures part 2</title>
		<link>https://undocumentedmatlab.com/articles/customizing-uifigures-part-2?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=customizing-uifigures-part-2</link>
					<comments>https://undocumentedmatlab.com/articles/customizing-uifigures-part-2#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Wed, 07 Sep 2016 17:00:57 +0000</pubDate>
				<category><![CDATA[Figure window]]></category>
		<category><![CDATA[Guest bloggers]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[High risk of breaking in future versions]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Iliya Romm]]></category>
		<category><![CDATA[uifigure]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=6635</guid>

					<description><![CDATA[<p>Matlab's new web-based uifigures can be customized using custom CSS and Javascript code. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-2">Customizing uifigures part 2</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-3" rel="bookmark" title="Customizing uifigures part 3">Customizing uifigures part 3 </a> <small>As I have repeatedly posted in recent years, Matlab is advancing towards web-based GUI. The basic underlying technology is more-or-less stable: an HTML/Javascript webpage that is created-on-the-fly and rendered in a stripped-down browser window (based on Chromium-based jxBrowser in recent...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-1" rel="bookmark" title="Customizing uifigures part 1">Customizing uifigures part 1 </a> <small>Matlab's new web-based uifigures can be customized in a variety of undocumented ways. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-web-gui-uipanel" rel="bookmark" title="Customizing web-GUI uipanel">Customizing web-GUI uipanel </a> <small>We can customize Matlab's new web-based GUI panels in many interesting ways. Here's how... ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-uifigure-javascript-events" rel="bookmark" title="Matlab callbacks for uifigure JavaScript events">Matlab callbacks for uifigure JavaScript events </a> <small>Matlab callback code can be attached to JavaScript events in web-based uifigures. ...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p><i>I would like to introduce guest blogger Iliya Romm of Israel&#8217;s Technion <a href="http://bcukurel.net.technion.ac.il" target="_blank" rel="nofollow">Turbomachinery and Heat Transfer Laboratory</a>. Today Iliya will discuss how Matlab&#8217;s new web-based figures can be customized with user-controlled CSS and JavaScript code.</i><br />
When we compare the documented properties of a &#8220;classic&#8221; <a href="http://www.mathworks.com/help/matlab/ref/uicontrol-properties.html" target="_blank" rel="nofollow"><code>uicontrol</code></a> with an App Designer control such as <a href="http://www.mathworks.com/help/matlab/ref/checkboxappdesigner-properties.html" target="_blank" rel="nofollow"><code>uicheckbox</code></a>, we see lists of 42 and 15 properties, respectively. At first glance, this implies that our ability to customize App Designer elements is relatively very limited. This is surely a disquieting conclusion, especially for those used to being able to change most aspect of their Matlab figures via Java. Fortunately, such a conclusion is quite far from reality, as we will shortly see.<br />
To understand this claim, we need to consider a <a href="/articles/customizing-uifigures-part-1" target="_blank" rel="nofollow">previous post on this blog</a>, where Yair discussed how uifigures are actually HTML webpages rendered by Matlab. As such, they have a DOM that can be accessed and manipulated through JavaScript commands to achieve various visual customizations. Today we&#8217;ll explore the structure of the uifigure webpage; take a look at some possibilities provided by the Dojo Toolkit; and see how to use Dojo to customize uifigure controls visually using CSS styles and/or HTML attributes.<br />
<center><a href="/images/uifigure_css1.gif" rel="nofollow" target="_blank"><img decoding="async" alt="User customizations of Matlab uifigures (click to zoom-in)" src="https://undocumentedmatlab.com/images/uifigure_css1.gif" title="User customizations of Matlab uifigures (click to zoom-in)" width="75%" style="max-width:1135px;" /></a><br />
User customizations of Matlab uifigures (click to zoom-in)</center><br />
<span id="more-6635"></span></p>
<h3 id="css">A brief introduction to CSS</h3>
<p><b>CSS</b> stands for <b>C</b>ascading <b>S</b>tyle <b>S</b>heets. As described on <a href="https://www.w3.org/standards/webdesign/htmlcss#whatcss" target="_blank" rel="nofollow">the official webpage</a> of W3C (which governs web standards):</p>
<blockquote><p>CSS is the language for describing the presentation of Web pages, including colors, layout, and fonts. CSS is independent of HTML. This is referred to as the separation of structure (or: content) from presentation.</p></blockquote>
<p>CSS rules (or &#8220;styles&#8221;) can be defined in one of three places:</p>
<ul>
<li>A separate file, such as the <i >main.css</i> that Matlab uses for uifigures (this file is found minified in <i>%matlabroot%\toolbox\matlab\uitools\uifigureappjs\release\gbtclient\css</i>)</li>
<li>An inline block inside the HTML&#8217;s <code>&lt;head&gt;</code> section</li>
<li>Directly within a DOM node</li>
</ul>
<p>Deciding which of the above to use, is largely a choice of the right tool for the job. <i>Usually</i>, the first two choices should be preferred, as they adhere to the &#8220;separation of structure and presentation&#8221; idea better. However, in the scope of this demonstration, we’ll be using mostly the 3rd option, because it allows us not to worry about possible CSS precedence issues (<a href="http://vanseodesign.com/css/css-specificity-inheritance-cascaade/" target="_blank" rel="nofollow">suggested read</a>).<br />
The syntax of CSS is generally: <code>selector { property: value }</code>, but it can have <a href="http://www.tutorialspoint.com/css/css_syntax.htm" target="_blank" rel="nofollow">other forms</a> as well.</p>
<h3 id="details">Getting down to business</h3>
<p>Let us consider a very basic uifigure that only contains a <a href="http://www.mathworks.com/help/matlab/ref/uitextarea.html" target="_blank" rel="nofollow"><code>uitextarea</code></a> and its label:<br />
<center><figure style="width: 282px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" alt="Simple demo uifigure with a TextArea and label" src="https://undocumentedmatlab.com/images/uifigure_css2.png" title="Simple demo uifigure with a TextArea and label" width="282" height="134" /><figcaption class="wp-caption-text">Simple demo uifigure with a TextArea and label</figcaption></figure></center><br />
The auto-generated code for it is:</p>
<div style="height: 300px; overflow: auto; margin-bottom: 10px;">
<pre lang="matlab">
classdef DOMdemo < matlab.apps.AppBase
    % Properties that correspond to app components
    properties (Access = public)
        UIFigure      matlab.ui.Figure           % UI Figure
        LabelTextArea matlab.ui.control.Label    % Text Area
        TextArea      matlab.ui.control.TextArea % This is some text.
    end
    methods (Access = private)
        % Code that executes after component creation
        function startupFcn(app)
        end
    end
    % App initialization and construction
    methods (Access = private)
        % Create UIFigure and components
        function createComponents(app)
            % Create UIFigure
            app.UIFigure = uifigure;
            app.UIFigure.Position = [100 100 280 102];
            app.UIFigure.Name = 'UI Figure';
            setAutoResize(app, app.UIFigure, true)
            % Create LabelTextArea
            app.LabelTextArea = uilabel(app.UIFigure);
            app.LabelTextArea.HorizontalAlignment = 'right';
            app.LabelTextArea.Position = [16 73 62 15];
            app.LabelTextArea.Text = 'Text Area';
            % Create TextArea
            app.TextArea = uitextarea(app.UIFigure);
            app.TextArea.Position = [116 14 151 60];
            app.TextArea.Value = {'This is some text.'};
        end
    end
    methods (Access = public)
        % Construct app
        function app = DOMdemo()
            % Create and configure components
            createComponents(app)
            % Register the app with App Designer
            registerApp(app, app.UIFigure)
            % Execute the startup function
            runStartupFcn(app, @startupFcn)
            if nargout == 0
                clear app
            end
        end
        % Code that executes before app deletion
        function delete(app)
            % Delete UIFigure when app is deleted
            delete(app.UIFigure)
        end
    end
end
</pre>
</div>
<p>Let's say we want to modify certain aspects of the <code>TextArea</code> widget, such as the text color, background, and/or horizontal alignment. The workflow for styling elements involves:</p>
<ol>
<li>Find the handle to the webfigure</li>
<li>Find the DOM node we want to modify</li>
<li>Find the property name that corresponds to the change we want</li>
<li>Find a way to manipulate the desired node from Matlab</li>
</ol>
<h4 id="webfigure">Step 1: Find the handle to the webfigure</h4>
<p>The first thing we need to do is to strategically place a bit of code that would allow us to get the URL of the figure so we can inspect it in our browser:</p>
<pre lang="matlab">
function startupFcn(app)
   % Customizations (aka "MAGIC GOES HERE"):
   warning off Matlab:HandleGraphics:ObsoletedProperty:JavaFrame
   warning off Matlab:structOnObject
   while true
      try
         win = struct(struct(struct(app).UIFigure).Controller).Container.CEF;
         disp(win.URL);
         break
      catch
         disp('Not ready yet!');
         pause(0.5); % Give the figure (webpage) some more time to load
      end
   end
end
</pre>
<p>This code waits until the page is <i>sufficiently</i> loaded, and then retrieve its local address (URL). The result will be something like this, which can be directly opened in any browser (outside Matlab):</p>
<pre lang="none">http://localhost:31415/toolbox/matlab/uitools/uifigureappjs/componentContainer.html?channel=/uicontainer/861ef484-534e-4a50-993e-6d00bdba73a5&snc=88E96E</pre>
<h4 id="DOM">Step 2: Find the DOM node that corresponds to the component that we want to modify</h4>
<p>Loading this URL in an external browser (e.g., Chrome, Firefox or IE/Edge) enables us to use web-development addins (e.g., FireBug) to inspect the page contents (source-code). </p>
<p>Note: in recent Matlab releases, the URL cannot be directly opened in a browser unless we first set Matlab to enable this (<a href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-uifigure-javascript-events#comment-454673" target="_blank">thanks to Perttu</a>). We can turn on such browser debugging by running:</p>
<pre lang="matlab">matlab.internal.webwindow(' ', 'DebugPort',4040) %note: the space is important!</pre>
<p>before any other App, or kill all MatlabWindow processes (from the operating system's task manager) before running the command. Then browse http://localhost:4040/ in your browser - this will display a list of links, one link for each uifigure, based on the uifigure's title (name); click the requested uifigure's link to see and debug the figure's HTML/CSS contents.</p>
<p>Opening the URL inside a browser and inspecting the page contents, we can see its DOM:<br />
<center><a href="/images/uifigure_css3.png" rel="nofollow" target="_blank"><img decoding="async" alt="Inspecting the DOM in Firefox (click to zoom-in)" src="https://undocumentedmatlab.com/images/uifigure_css3.png" title="Inspecting the DOM in Firefox (click to zoom-in)" width="60%" style="max-width:1197px;" /></a><br />
Inspecting the DOM in Firefox (click to zoom-in)<br />
</center><br />
Notice the three <code>data-tag</code> entries marked by red frames. Any idea why there are exactly three nonempty tags like that? This is because our App Designer object, <code>app</code>, contains 3 declared children, as defined in:</p>
<pre lang="matlab">
createComponents(app):
    app.UIFigure = uifigure;
    app.LabelTextArea = uilabel(app.UIFigure);
    app.TextArea = uitextarea(app.UIFigure);
</pre>
<p>... and each of them is assigned a random hexadecimal id whenever the app is opened.<br />
Finding the relevant node involved some trial-and-error, but after doing it several times I seem to have found a consistent pattern that can be used to our advantage. Apparently, the nodes with <code>data-tag</code> are always above the element we want to style, sometimes as a direct parent and sometimes farther away. So why do we even need to bother with choosing more accurate nodes than these "tagged" ones? Shouldn't styles applied to the tagged nodes <i>cascade</i> down to the element we care about? Sure, <i>sometimes</i> it works like that, but we want to do better than "sometimes". To that end, we would like to select as relevant a node as possible.<br />
Anyway, the next step in the program is to find the data-tag that corresponds to the selected component. Luckily, there is a direct (undocumented) way to get it:</p>
<pre lang="matlab">
% Determine the data-tag of the DOM component that we want to modify:
hComponent = app.TextArea;  % handle to the component that we want to modify
data_tag = char(struct(hComponent).Controller.ProxyView.PeerNode.getId);  % this part is generic: can be used with any web-based GUI component
</pre>
<p>Let's take a look at the elements marked with blue and green borders (in that order) in the DOM screenshot. We see that the <code>data-tag</code> property is exactly one level above these elements, in other words, the first child of the tagged node is an element that contains a <code>widgetid</code> property. This property is very important, as it contains the <code>id</code> of the node that we actually want to change. Think pointers. To summarize this part:<br />
<center><b>data-tag  &nbsp; => &nbsp; widgetid  &nbsp; => &nbsp; widget "handle"</b></center><br />
We shall use this transformation in Step 4 below.<br />
I wanted to start with the blue-outlined element as it demonstrates this structure using distinct elements. The green-outlined element is slightly strange, as it contains a <code>widgetid</code> that points back to itself. Since this obeys the same algorithm, it's not a problem.</p>
<h4 id="propname">Step 3: Find the CSS property name that corresponds to the change we want</h4>
<p>There is no trick here: it's just a matter of going through <a href="http://www.w3schools.com/cssref/default.asp" target="_blank" rel="nofollow">a list of CSS properties</a> and choosing one that "sounds about right" (there are often several ways to achieve the same visual result with CSS). After we choose the relevant properties, we need to convert them to camelCase as per documentation of <a href="https://dojotoolkit.org/reference-guide/1.7/dojo/style.html#tips" target="_blank" rel="nofollow">dojo.style()</a>:</p>
<blockquote><p>If the CSS style property is hyphenated, the JavaScript property is camelCased. For example: "font-size" becomes "fontSize", and so on.</p></blockquote>
<p>Note that Matlab R2016a comes bundled with Dojo v1.10.4, rev. <a href="https://github.com/dojo/dojo/commit/f4fef7077dde783156c1ddd3b06464d236e5537c" target="_blank" rel="nofollow">f4fef70</a> (January 11 2015). Other Matlab releases will probably come with other Dojo versions. They will never be the latest version of Dojo, but rather a version that is 1-2 years old. We should keep this in mind when searching the Dojo documentation. We can get the current Dojo version as follows:</p>
<pre lang="matlab">
>> f=uifigure; drawnow; dojoVersion = matlab.internal.webwindowmanager.instance.windowList(1).executeJS('dojo.version'), delete(f)
dojoVersion =
{"major":1,"minor":10,"patch":4,"flag":"","revision":"f4fef70"}
</pre>
<p>This tells us that Dojo 1.10.4.f4fef70 is the currently-used version. We can use this information to browse the relevant documentation branch, as well as possibly use different Dojo functions/features.</p>
<h4 id="manipulate">Step 4: Manipulate the desired element from Matlab</h4>
<p>In this demo, we'll use a combination of several commands:</p>
<ul>
<li>{matlab.internal.webwindow.}executeJS() – For sending JS commands to the uifigure.</li>
<li><a href="https://dojotoolkit.org/reference-guide/1.10/dojo/query.html" target="_blank" rel="nofollow">dojo.query()</a> – for finding nodes inside the DOM.</li>
<li><a href="https://dojotoolkit.org/reference-guide/1.7/dojo/style.html" target="_blank" rel="nofollow">dojo.style()</a> (deprecated since v1.8) – for applying styles to the required nodes of the DOM.<br />
Syntax: dojo.style(node, style, value); </li>
<li><a href="https://dojotoolkit.org/reference-guide/1.7/dojo/setAttr.html" target="_blank" rel="nofollow">dojo.setAttr</a> (deprecated since v1.8) – for setting some non-style attributes.<br />
Syntax: dojo.setAttr(node, name, value); </li>
</ul>
<p>Consider the following JS commands:</p>
<ul>
<li>search the DOM for nodes having a data-tag attribute having the specified value, take their first child of type <code>&lt;div&gt;</code>, and return the value of this child's <code>widgetid</code> attribute:
<pre lang="matlab">['dojo.getAttr(dojo.query("[data-tag^=''' data_tag '''] > div")[0],"widgetid")']</pre>
</li>
<li>search the DOM for nodes with id of <code>widgetid</code>, then take the first element of the result and set its text alignment:
<pre lang="matlab">['dojo.style(dojo.query("#' widgetId(2:end-1) '")[0],"textAlign","center")']</pre>
</li>
<li>append the CSS style defined by <code>{SOME CSS STYLE}</code> to the page (this style can later be used by nodes):
<pre lang="matlab">['document.head.innerHTML += ''<style>{SOME CSS STYLE}</style>''']);</pre>
</li>
</ul>
<h4 id="all">Putting it all together</h4>
<p>It should finally be possible to understand the code that appears in the animated screenshot at the top of this post:</p>
<pre lang="matlab">
%% 1. Get a handle to the webwindow:
win = struct(struct(struct(app).UIFigure).Controller).Container.CEF;
%% 2. Find which element of the DOM we want to edit (as before):
data_tag = char(struct(app.TextArea).Controller.ProxyView.PeerNode.getId);
%% 3. Manipulate the DOM via a JS command
% ^ always references a class="vc-widget" element.
widgetId = win.executeJS(['dojo.getAttr(dojo.query("[data-tag^=''' data_tag '''] > div")[0],"widgetid")']);
% Change font weight:
dojo_style_prefix = ['dojo.style(dojo.query("#' widgetId(2:end-1) '")[0],'];
win.executeJS([dojo_style_prefix '"fontWeight","900")']);
% Change font color:
win.executeJS([dojo_style_prefix '"color","yellow")']);
% Add an inline css to the HTML <head>:
win.executeJS(['document.head.innerHTML += ''<style>'...
    '@-webkit-keyframes mymove {50% {background-color: blue;}}'...
    '@keyframes mymove {50% {background-color: blue;}}</style>''']);
% Add animation to control:
win.executeJS([dojo_style_prefix '"-webkit-animation","mymove 5s infinite")']);
% Change Dojo theme:
win.executeJS('dojo.setAttr(document.body,''class'',''nihilo'')[0]');
% Center text:
win.executeJS([dojo_style_prefix '"textAlign","center")']);
</pre>
<p>A similar method for center-aligning the items in a <a href="http://www.mathworks.com/help/matlab/ref/uilistbox.html" rel="nofollow" target="_blank">uilistbox</a> is <a href="http://stackoverflow.com/questions/38933254/how-to-customize-app-designer-figures-in-more-ways-than-officially-documented" rel="nofollow" target="_blank">described here</a> (using a CSS <code>text-align</code> directive).<br />
The only thing we need to ensure before running code that manipulates the DOM, is that the page is fully loaded. The easiest way is to include a <i><b>pause</b>()</i> of several seconds right after the <code>createComponents(app)</code> function (this will not interfere with the creation of the uifigure, as it happens on a different thread). I have been experimenting with <a href="https://github.com/StackOverflowMATLABchat/mlapptools/issues/1#issuecomment-241252137" target="_blank" rel="nofollow">another method</a> involving <code>webwindow</code>'s <code>PageLoadFinishedCallback</code> callback, but haven’t found anything elegant yet.</p>
<h3 id="warning">A few words of caution</h3>
<p>In this demonstration, we invoked Dojo functions via the webwindow's JS interface. For something like this to be possible, there has to exist some form of “bridge” that translates Matlab commands to JS commands issued to the browser and control the DOM. We also know that this bridge has to be bi-directional, because binding Matlab callbacks to uifigure actions (e.g. <code>ButtonPushFcn</code> for uibuttons) is a documented feature.<br />
The extent to which the bridge might allow malicious code to control the Matlab process needs to be investigated. Until then, the ability of webwindows to execute arbitrary JS code should be considered a known vulnerability. For more information, see <a href="https://en.wikipedia.org/wiki/Cross-site_scripting" target="_blank" rel="nofollow">XSS</a> and <a href="https://en.wikipedia.org/wiki/Cross-site_scripting#Related_vulnerabilities" target="_blank" rel="nofollow">related</a> vulnerabilities.</p>
<h3 id="conclusion">Final remarks</h3>
<p>It should be clear now that there are actually lots of possibilities afforded by the new uifigures for user customizations. One would hope that future Matlab releases will expose easier and more robust hooks for CSS/JS customizations of uifigure contents. But until that time arrives (if ever), we can make do with the mechanism shown above.<br />
Readers are welcome to visit the <a href="https://github.com/StackOverflowMATLABchat/mlapptools" target="_blank" rel="nofollow">GitHub project</a> dedicated to manipulating uifigures using the methods discussed in this post. Feel free to comment, suggest improvements and ideas, and of course submit some pull requests 🙂<br />
p.s. – it turns out that uifigures can also display <a href="https://www.w3.org/Math/" rel="nofollow" target="_blank">MathML</a>. But this is a topic for another post...</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-2">Customizing uifigures part 2</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-3" rel="bookmark" title="Customizing uifigures part 3">Customizing uifigures part 3 </a> <small>As I have repeatedly posted in recent years, Matlab is advancing towards web-based GUI. The basic underlying technology is more-or-less stable: an HTML/Javascript webpage that is created-on-the-fly and rendered in a stripped-down browser window (based on Chromium-based jxBrowser in recent...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-uifigures-part-1" rel="bookmark" title="Customizing uifigures part 1">Customizing uifigures part 1 </a> <small>Matlab's new web-based uifigures can be customized in a variety of undocumented ways. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-web-gui-uipanel" rel="bookmark" title="Customizing web-GUI uipanel">Customizing web-GUI uipanel </a> <small>We can customize Matlab's new web-based GUI panels in many interesting ways. Here's how... ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-uifigure-javascript-events" rel="bookmark" title="Matlab callbacks for uifigure JavaScript events">Matlab callbacks for uifigure JavaScript events </a> <small>Matlab callback code can be attached to JavaScript events in web-based uifigures. ...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/customizing-uifigures-part-2/feed</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
	</channel>
</rss>
