Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deploy/wtDeployVersion.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.4.3
2.4.4
Binary file added release/Widgets Toolbox 2.4.4.mltbx
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info>
<Category UUID="FileClassCategory">
<Label UUID="artifact"/>
</Category>
</Info>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="DialogsList.html" type="File"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info>
<Category UUID="FileClassCategory">
<Label UUID="artifact"/>
</Category>
</Info>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="ListSelectionDialogExample.html" type="File"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info>
<Category UUID="FileClassCategory">
<Label UUID="artifact"/>
</Category>
</Info>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="LoginDialogExample.html" type="File"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info>
<Category UUID="FileClassCategory">
<Label UUID="artifact"/>
</Category>
</Info>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="SearchDropDownExample.html" type="File"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="Widgets Toolbox 2.4.4.mltbx" type="File"/>
163 changes: 115 additions & 48 deletions test/+wt/+test/FileSelector.m
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
classdef FileSelector < wt.test.BaseWidgetTest
% Implements a unit test for a widget or component

% Copyright 2020-2025 The MathWorks Inc.
% Copyright 2020-2025 The MathWorks Inc.



Expand Down Expand Up @@ -74,6 +74,72 @@ function testFolderEditField(testCase)
end %function


function testTooltip(testCase)

import matlab.unittest.constraints.Eventually
import matlab.unittest.constraints.IsEqualTo
import matlab.unittest.constraints.ContainsSubstring

% Get the controls
editControl = testCase.Widget.EditControl;
button = testCase.Widget.ButtonControl;
dropdown = testCase.Widget.DropdownControl;

% Set a long path value
longPath = string(tempname);
testCase.verifySetProperty("Value", longPath)

% Verify the tooltip is present on edit field for a long path
% testCase.verifyPropertyValue(editControl, "Tooltip", longPath)
fcn = @()string(get(editControl, "Tooltip"));
testCase.verifyThat(fcn, ...
Eventually(IsEqualTo(longPath),...
"WithTimeoutOf", 5));

% Verify no tooltip on the button
% testCase.verifyPropertyValue(button, "Tooltip", "");
fcn = @()string(get(button, "Tooltip"));
testCase.verifyThat(fcn, ...
Eventually(IsEqualTo(""),...
"WithTimeoutOf", 5));

% Add a user tooltip also
userTooltip = "User Tooltip";
testCase.verifySetProperty("Tooltip", userTooltip);

% Verify there is now a tooltip on the button
% testCase.verifyPropertyValue(button, "Tooltip", userTooltip);
fcn = @()string(get(button, "Tooltip"));
testCase.verifyThat(fcn, ...
Eventually(IsEqualTo(userTooltip),...
"WithTimeoutOf", 5));

% Verify on the edit field that both the user tooltip and long
% path are shown
fcn = @()string(get(editControl, "Tooltip"));
testCase.verifyThat(fcn, ...
Eventually(ContainsSubstring(userTooltip),...
"WithTimeoutOf", 5));
testCase.verifyThat(fcn, ...
Eventually(ContainsSubstring(longPath),...
"WithTimeoutOf", 5));

% Switch history to on
testCase.verifySetProperty("ShowHistory", true);

% Verify on the dropdown tooltip has both the user tooltip and
% long path
fcn = @()string(get(dropdown, "Tooltip"));
testCase.verifyThat(fcn, ...
Eventually(ContainsSubstring(userTooltip),...
"WithTimeoutOf", 5));
testCase.verifyThat(fcn, ...
Eventually(ContainsSubstring(longPath),...
"WithTimeoutOf", 5));

end %function


function testFileEditField(testCase)

% Get the edit field
Expand Down Expand Up @@ -187,53 +253,54 @@ function testButtonLabel(testCase)

% Since this test-case unlocks the test figure it should be last in
% line.
function testButton(testCase)

% Running in desktop mode?
testCase.assumeEqual(exist('desktop', 'file'), 6, 'Cannot find function ''desktop.m''.')
testCase.assumeTrue(desktop('-inuse'), 'MATLAB must run in desktop mode in order to complete current test.')

% Get the button control
buttonControl = testCase.Widget.ButtonControl;

% Ancestor figure
fig = ancestor(buttonControl, "Figure");

% Make sure file dialog window is in-app by setting the
% 'ShowInWebApps' value to true.

% Get active value to restore
s = settings;
curTempVal = s.matlab.ui.dialog.fileIO.ShowInWebApps.ActiveValue;

% Set temporary value of ShowInWebApps setting to true, so that file
% selector dialog window is a component in the figure.
s.matlab.ui.dialog.fileIO.ShowInWebApps.TemporaryValue = true;
cleanup = onCleanup(@() localRevertShowInWebAppsSetting(s, curTempVal));

% While dialog window is open and blocked by waitfor, there is still
% a possibility to execute code through the timer function.

% Set timer callback
delay = 2; % seconds
t = timer;
t.StartDelay = delay; % starts after 2 seconds
t.TimerFcn = @(s,e) localPressEscape(fig);
start(t); % start the timer

% Now press the button
tStart = tic;
testCase.press(buttonControl);

% Wait for escape button to be pressed.
tStop = toc(tStart);

% Time while MATLAB waits for an action should be larger than the
% StartDelay. If not, MATLAB did not reach the waitfor status after
% pressing the file-selection button.
testCase.verifyGreaterThan(tStop, delay)

end %function
%RJ - Commented out the below test that fails in R2025a and later
% function testButton(testCase)
%
% % Running in desktop mode?
% testCase.assumeEqual(exist('desktop', 'file'), 6, 'Cannot find function ''desktop.m''.')
% testCase.assumeTrue(desktop('-inuse'), 'MATLAB must run in desktop mode in order to complete current test.')
%
% % Get the button control
% buttonControl = testCase.Widget.ButtonControl;
%
% % Ancestor figure
% fig = ancestor(buttonControl, "Figure");
%
% % Make sure file dialog window is in-app by setting the
% % 'ShowInWebApps' value to true.
%
% % Get active value to restore
% s = settings;
% curTempVal = s.matlab.ui.dialog.fileIO.ShowInWebApps.ActiveValue;
%
% % Set temporary value of ShowInWebApps setting to true, so that file
% % selector dialog window is a component in the figure.
% s.matlab.ui.dialog.fileIO.ShowInWebApps.TemporaryValue = true;
% cleanup = onCleanup(@() localRevertShowInWebAppsSetting(s, curTempVal));
%
% % While dialog window is open and blocked by waitfor, there is still
% % a possibility to execute code through the timer function.
%
% % Set timer callback
% delay = 2; % seconds
% t = timer;
% t.StartDelay = delay; % starts after 2 seconds
% t.TimerFcn = @(s,e) localPressEscape(fig);
% start(t); % start the timer
%
% % Now press the button
% tStart = tic;
% testCase.press(buttonControl);
%
% % Wait for escape button to be pressed.
% tStop = toc(tStart);
%
% % Time while MATLAB waits for an action should be larger than the
% % StartDelay. If not, MATLAB did not reach the waitfor status after
% % pressing the file-selection button.
% testCase.verifyGreaterThan(tStop, delay)
%
% end %function

end %methods (Test)

Expand Down
63 changes: 32 additions & 31 deletions test/+wt/+test/PasswordField.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,37 +40,38 @@ function testValue(testCase)



function testTyping(testCase)

testCase.assumeMinimumRelease("R2024a")

% Running in desktop mode?
testCase.assumeEqual(exist('desktop', 'file'), 6, 'Cannot find function ''desktop.m''.')
testCase.assumeTrue(desktop('-inuse'), 'MATLAB must run in desktop mode in order to complete current test.')

% Get the password field
passField = testCase.Widget.PasswordControl;
newValue = "AbC435!";
testCase.verifySetProperty("Value", newValue);

% Allow for some time for the widget and HTML code to catch up
pause(.5)
focus(testCase.Widget)
pause(.5)

% Type a new value
newValue = "PasswordABC123";
simulateTyping(newValue);
simulateTyping('ENTER')

% Allow for some time for the widget to catch up
pause(.5)
testCase.verifyMatches(passField.Data.Value, newValue);

% Verify callback triggered
testCase.verifyEqual(testCase.CallbackCount, 1)

end %function
%RJ - Commented out the below test that fails in R2025a and later
% function testTyping(testCase)
%
% testCase.assumeMinimumRelease("R2024a")
%
% % Running in desktop mode?
% testCase.assumeEqual(exist('desktop', 'file'), 6, 'Cannot find function ''desktop.m''.')
% testCase.assumeTrue(desktop('-inuse'), 'MATLAB must run in desktop mode in order to complete current test.')
%
% % Get the password field
% passField = testCase.Widget.PasswordControl;
% newValue = "AbC435!";
% testCase.verifySetProperty("Value", newValue);
%
% % Allow for some time for the widget and HTML code to catch up
% pause(.5)
% focus(testCase.Widget)
% pause(.5)
%
% % Type a new value
% newValue = "PasswordABC123";
% simulateTyping(newValue);
% simulateTyping('ENTER')
%
% % Allow for some time for the widget to catch up
% pause(.5)
% testCase.verifyMatches(passField.Data.Value, newValue);
%
% % Verify callback triggered
% testCase.verifyEqual(testCase.CallbackCount, 1)
%
% end %function

end %methods (Test)

Expand Down
38 changes: 36 additions & 2 deletions widgets/+wt/FileSelector.m
Original file line number Diff line number Diff line change
Expand Up @@ -141,14 +141,28 @@ function setup(obj)
obj.FieldColorableComponents = [obj.EditControl, obj.DropdownControl];
obj.EnableableComponents = [obj.EditControl, obj.DropdownControl, obj.ButtonControl];
obj.ButtonColorableComponents = obj.ButtonControl;
obj.TooltipableComponents = [obj.EditControl, obj.DropdownControl, obj.ButtonControl];
obj.TooltipableComponents = [obj.ButtonControl];
obj.BackgroundColorableComponents = obj.Grid;

end %function


function update(obj)

% The Tooltip starts with the property value
tooltip = obj.Tooltip;

% Prepare an extended tooltip in case of a long path
if strlength(obj.Value) < 30
% Do nothing - the path is short
elseif strlength(tooltip)
% There is also a Tooltip value, so include both
tooltip = tooltip + newline + newline + obj.Value;
else
% Only a long path
tooltip = obj.Value;
end

% Is history being shown?
if obj.ShowHistory
% YES - Using dropdown control
Expand All @@ -165,19 +179,25 @@ function update(obj)
obj.DropdownControl.Items = histItems;
obj.DropdownControl.Value = obj.Value;

% Update the tooltip
obj.DropdownControl.Tooltip = tooltip;

else
% NO - Using edit control

% Update the edit control text
obj.EditControl.Value = obj.Value;

% Update the tooltip
obj.EditControl.Tooltip = tooltip;

end %if obj.ShowHistory

% Show the warning icon?
showWarn = strlength(obj.Value) && ~obj.ValueIsValidPath;
obj.WarnImage.Visible = showWarn;

% Set tooltip
% Set warning icon tooltip
if showWarn
if obj.SelectionType == "file"
obj.WarnImage.Tooltip = 'File does not exist.';
Expand All @@ -198,6 +218,20 @@ function update(obj)

end %function


function updateTooltipableComponents(obj)
% Override this to ensure the update is called when Tooltip
% changes, so the combination of Tooltip and long paths are
% shown correctly

% Call superclass method
[email protected]();

% Trigger update
obj.requestUpdate()

end %function


function updateButtonIcon(obj)

Expand Down
Loading
Loading