Skip to content

Commit 16eeeaa

Browse files
authored
Merge pull request #3 from Dev-iL/generic-modification
Adding a generic styling function (setStyle)
2 parents a534a88 + 92f4f2d commit 16eeeaa

File tree

2 files changed

+95
-36
lines changed

2 files changed

+95
-36
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ For additional information, see Iliya Romm's guest Undocumented Matlab article,
77
[`textAlign`](#textAlign) - Modify text alignment
88
[`fontWeight`](#fontWeight) - Modify font weight
99
[`fontColor`](#fontColor) - Modify font folor
10+
[`setStyle`](#setStyle) - Modify a specified style property
1011

1112
<a name="textAlign"></a>
1213
#### *mlapptools*.**textAlign**(*uielement*, *alignment*)
@@ -82,4 +83,21 @@ mlapptools.fontColor(myGUI.TextArea, 'aqua');
8283
```MATLAB
8384
myGUI = DOMdemoGUI;
8485
mlapptools.fontColor(myGUI.TextArea, 'rgb(255,165,0)');
86+
```
87+
88+
<a name="setStyle"></a>
89+
#### *mlapptools*.**setStyle**(*uielement*, *styleAttr*, *styleValue*)
90+
##### Description
91+
Set the style attribute `styleAttr` of the specified UI element, `'uielement'`, to the value `styleValue`. `styleAttr` should be any valid CSS attribute, and `styleValue` a valid setting thereof.
92+
93+
This method provides a general interface to change CSS style attributes, with minimal input testing and error reporting, so it is up to the user to provide valid inputs.
94+
95+
Valid style attributes and corresponding settings can be found [here](https://www.w3schools.com/cssref/).
96+
97+
##### Examples
98+
Using the demo GUI generated by `./Demo/DOMdemoGUI.m`
99+
```MATLAB
100+
myGUI = DOMdemoGUI;
101+
mlapptools.setStyle(myGUI.TextArea, 'background-image',...
102+
'url(https://upload.wikimedia.org/wikipedia/commons/8/80/Wikipedia-logo-v2.svg)');
85103
```

mlapptools.m

Lines changed: 77 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,27 @@
1-
classdef mlapptools
2-
% MLAPPTOOLS is a class definition
1+
classdef (Abstract) mlapptools
2+
% MLAPPTOOLS A collection of static methods for customizing various aspects
3+
% MATLAB App Designer UIFigures.
34
%
45
% MLAPPTOOLS methods:
6+
% textAlign - utility method for modifying text alignment.
7+
% fontWeight - utility method for modifying font weight (bold etc.).
8+
% fontColor - utility method for modifying font color.
9+
% setStyle - utility method for modifying styles that do not (yet) have a
10+
% dedicated mutator.
511

6-
properties (Constant)
7-
querytimeout = 5; % Dojo query timeout period, seconds
12+
properties (Access = private, Constant = true)
13+
QUERY_TIMEOUT = 5; % Dojo query timeout period, seconds
814
end
9-
10-
methods
11-
function obj = mlapptools
12-
% Dummy constructor so we don't return an empty class instance
13-
clear obj
14-
end
15-
end
16-
17-
18-
methods (Static)
15+
16+
methods (Access = public, Static = true)
1917
function textAlign(uielement, alignment)
2018
alignment = lower(alignment);
2119
mlapptools.validatealignmentstr(alignment)
2220

2321
[win, widgetID] = mlapptools.getWebElements(uielement);
2422

25-
alignsetstr = sprintf('dojo.style(dojo.query("#%s")[0], "textAlign", "%s")', widgetID, alignment);
26-
win.executeJS(alignsetstr);
23+
alignSetStr = sprintf('dojo.style(dojo.query("#%s")[0], "textAlign", "%s")', widgetID, alignment);
24+
win.executeJS(alignSetStr);
2725
end
2826

2927

@@ -32,8 +30,8 @@ function fontWeight(uielement, weight)
3230

3331
[win, widgetID] = mlapptools.getWebElements(uielement);
3432

35-
fontwtsetstr = sprintf('dojo.style(dojo.query("#%s")[0], "font-weight", "%s")', widgetID, weight);
36-
win.executeJS(fontwtsetstr);
33+
fontWeightSetStr = sprintf('dojo.style(dojo.query("#%s")[0], "font-weight", "%s")', widgetID, weight);
34+
win.executeJS(fontWeightSetStr);
3735
end
3836

3937

@@ -42,25 +40,54 @@ function fontColor(uielement, newcolor)
4240

4341
[win, widgetID] = mlapptools.getWebElements(uielement);
4442

45-
fontwtsetstr = sprintf('dojo.style(dojo.query("#%s")[0], "color", "%s")', widgetID, newcolor);
46-
win.executeJS(fontwtsetstr);
43+
fontColorSetStr = sprintf('dojo.style(dojo.query("#%s")[0], "color", "%s")', widgetID, newcolor);
44+
win.executeJS(fontColorSetStr);
4745
end
48-
end
49-
50-
51-
methods (Static, Access = private)
46+
47+
48+
function widgetID = setStyle(hControl, styleAttr, styleValue)
49+
% This method provides a simple interface for modifying style attributes
50+
% of uicontrols.
51+
%
52+
% WARNING: Due to the large amount of available style attributes and
53+
% corresponding settings, input checking is not performed. As this
54+
% might lead to unexpected results or errors - USE AT YOUR OWN RISK!
55+
[win, widgetID] = mlapptools.getWebElements(hControl);
56+
57+
styleSetStr = sprintf('dojo.style(dojo.query("#%s")[0], "%s", "%s")', widgetID, styleAttr, styleValue);
58+
% ^ this might result in junk if widgetId=='null'.
59+
try
60+
win.executeJS(styleSetStr);
61+
% ^ this might crash in case of invalid styleAttr/styleValue.
62+
catch ME
63+
% Test for "Invalid or unexpected token":
64+
ME = mlapptools.checkJavascriptSyntaxError(ME, styleSetStr);
65+
rethrow(ME);
66+
end
67+
end
68+
69+
end % Public static methods
70+
71+
methods (Static = true, Access = private)
5272
function [win] = getWebWindow(uifigurewindow)
53-
% TODO: Check that we've been passed an app designer figure window
5473
mlapptools.togglewarnings('off')
74+
% Test if uifigurewindow is a valid handle
75+
if ~isa(uifigurewindow,'matlab.ui.Figure') || ...
76+
isempty(struct(uifigurewindow).ControllerInfo)
77+
msgID = 'mlapptools:getWebWindow:NotUIFigure';
78+
error(msgID, 'The provided window handle is not of a UIFigure.');
79+
end
5580

5681
tic
57-
while true && (toc < mlapptools.querytimeout)
82+
while true && (toc < mlapptools.QUERY_TIMEOUT)
5883
try
59-
% Add check for container change in R2017a (version 9.2)
60-
if verLessThan('matlab', '9.2')
61-
win = struct(struct(uifigurewindow).Controller).Container.CEF;
62-
else
63-
win = struct(struct(struct(uifigurewindow).Controller).PlatformHost).CEF;
84+
hController = struct(struct(uifigurewindow).Controller);
85+
% Check for Controller version:
86+
switch subsref(ver('matlab'), substruct('.','Version'))
87+
case {'9.0','9.1'} % R2016a or R2016b
88+
win = hController.Container.CEF;
89+
otherwise % R2017a onward
90+
win = struct(hController.PlatformHost).CEF;
6491
end
6592
break
6693
catch err
@@ -74,11 +101,11 @@ function fontColor(uielement, newcolor)
74101
end
75102
mlapptools.togglewarnings('on')
76103

77-
if toc >= mlapptools.querytimeout
104+
if toc >= mlapptools.QUERY_TIMEOUT
78105
msgID = 'mlapptools:getWidgetID:QueryTimeout';
79106
error(msgID, ...
80107
'WidgetID query timed out after %u seconds, UI needs more time to load', ...
81-
mlapptools.querytimeout);
108+
mlapptools.QUERY_TIMEOUT);
82109
end
83110
end
84111

@@ -94,7 +121,7 @@ function fontColor(uielement, newcolor)
94121
widgetquerystr = sprintf('dojo.getAttr(dojo.query("[data-tag^=''%s''] > div")[0], "widgetid")', data_tag);
95122

96123
tic
97-
while true && (toc < mlapptools.querytimeout)
124+
while true && (toc < mlapptools.QUERY_TIMEOUT)
98125
try
99126
widgetID = win.executeJS(widgetquerystr);
100127
widgetID = widgetID(2:end-1);
@@ -111,11 +138,11 @@ function fontColor(uielement, newcolor)
111138
end
112139
mlapptools.togglewarnings('on')
113140

114-
if toc >= mlapptools.querytimeout
141+
if toc >= mlapptools.QUERY_TIMEOUT
115142
msgID = 'mlapptools:getWidgetID:QueryTimeout';
116143
error(msgID, ...
117144
'WidgetID query timed out after %u seconds, UI needs more time to load', ...
118-
mlapptools.querytimeout);
145+
mlapptools.QUERY_TIMEOUT);
119146
end
120147
end
121148

@@ -187,6 +214,20 @@ function validatealignmentstr(alignment)
187214

188215

189216
function [newcolor] = validateCSScolor(newcolor)
217+
% TODO
218+
end
219+
220+
221+
function ME = checkJavascriptSyntaxError(ME,styleSetStr)
222+
if (strcmp(ME.identifier,'cefclient:webwindow:jserror'))
223+
c = strfind(ME.message,'Uncaught SyntaxError:');
224+
if ~isempty(c)
225+
v = str2double(regexp(ME.message(c:end),'-?\d+\.?\d*|-?\d*\.?\d+','match'));
226+
msg = ['Syntax error: unexpected token in styleValue: ' styleSetStr(v(1),v(2))];
227+
causeException = MException('mlapptools:setStyle:invalidInputs',msg);
228+
ME = addCause(ME,causeException);
229+
end
230+
end
190231
end
191232
end
192233
end

0 commit comments

Comments
 (0)