How to customize App Designer shapes more than officially documented?

A recently published article in UndocumentedMatlab mentions that App Designer are actually web pages using the Dojo Toolkit . This means that we could theoretically manipulate the HTML DOM directly to achieve certain user interface settings that are otherwise unavailable.

The following is an example of an App Designer shape definition, as shown in the .m file created by the application designer (on MATLAB R2016a):

 classdef domDemo < matlab.apps.AppBase % Properties that correspond to app components properties (Access = public) UIFigure matlab.ui.Figure % UI Figure LabelListBox matlab.ui.control.Label % List Box ListBox matlab.ui.control.ListBox % Item 1, Item 2, Item 3, It... 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 260 147]; app.UIFigure.Name = 'UI Figure'; setAutoResize(app, app.UIFigure, true) % Create LabelListBox app.LabelListBox = uilabel(app.UIFigure); app.LabelListBox.HorizontalAlignment = 'right'; app.LabelListBox.Position = [50 93 44 15]; app.LabelListBox.Text = 'List Box'; % Create ListBox app.ListBox = uilistbox(app.UIFigure); app.ListBox.Position = [109 36 100 74]; 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 

... which looks like this:

Example Figure App Designer

According to the uilistbox documentation (which redirects us to the checkbox Properties page for a complete list of properties), there is no way to manipulate, for example, aligning the text of list items. If yes, then

Question How can we manipulate the ListBox in the sample application so that its contents are centered, even if such a setting is not available to us?

+6
source share
1 answer

To succeed in this task, we need a few things:

  • Find where HTML / CSS is (so we can manipulate them). A.
  • Find which DOM element we want to change.
  • Find what we need to do.
  • Find a way to control an element using MATLAB.

Step by step:

1. Find where the HTML / CSS shape is stored / located

 win = struct(struct(struct(app).UIFigure).Controller).Container.CEF; URL = win.URL; % Needed only for testing in browser 

2. Find which DOM element we need to edit

 data_tag = char(struct(app.ListBox).Controller.ProxyView.PeerNode.getId); 

Check with a browser:

Checking a page in Firefox

3. Find what we need to do to do

Since we want to manipulate text alignment, we move on to the relevant keywords and find the CSS text-align property. Then we will try it manually to see if this really works:

enter image description here

4. Find a way to control an element using MATLAB

Using dojo.style and dojo.query :

 win.executeJS(['dojo.style(dojo.query("[data-tag^=''' data_tag ''']")[0],"textAlign","center")']); 

Before and after


Full code for this answer:

 classdef domDemo < matlab.apps.AppBase % Properties that correspond to app components properties (Access = public) UIFigure matlab.ui.Figure % UI Figure LabelListBox matlab.ui.control.Label % List Box ListBox matlab.ui.control.ListBox % Item 1, Item 2, Item 3, It... end methods (Access = private) % Code that executes after component creation function startupFcn(app) % Customizations (aka "MAGIC GOES HERE"): drawnow; rez = []; warning off MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame warning off MATLAB:structOnObject while ~strcmp(rez,'"center"') try % 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.ListBox).Controller.ProxyView.PeerNode.getId); % 3. Manipulate the DOM via a JS command rez = win.executeJS(['dojo.style(dojo.query("[data-tag^=''' ... data_tag ''']")[0],"textAlign","center")']); catch pause(1); % Give the figure (webpage) some more time to load end end 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 260 147]; app.UIFigure.Name = 'UI Figure'; setAutoResize(app, app.UIFigure, true) % Create LabelListBox app.LabelListBox = uilabel(app.UIFigure); app.LabelListBox.HorizontalAlignment = 'right'; app.LabelListBox.Position = [50 93 44 15]; app.LabelListBox.Text = 'List Box'; % Create ListBox app.ListBox = uilistbox(app.UIFigure); app.ListBox.Position = [109 36 100 74]; 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 
+11
source

All Articles