Simulink: Keyboard shortcut for match block size

11 views (last 30 days)
Prior to 21b when Match Size / Width / Heigh were in the right click context menu (which why are they removed in the first place????) you could right click when selected on multiple blocks, then right click and A(rrange) -> S(ize) which was fast and easy way to match things up without having to go searching for things. Now it is in the ribbon, where I have to navigate to (which I usually avoid the ribbon at all costs) go to the correct tab, then click the button. This post discusses the topic, but with no useful workaround, other than use the ribbon. This is just way too many extra steps for something that just existed right in the canvas with a few click and small mouse movement, or no movement at all using the keyboard.
So how do I either setup a keyboard shortcut to do this (for size, width, and height) or add my own context menu to bring that command back? Is there a command similar to Simulink.BlockDiagram.arrangeSystem? Or do I have to do a whole
pos = get(gcbh,'Position')
% code to turn position to height and width
blocks = find_system(get(gcbh,'parent'),'FindAll','on','Selected','on')
% some voodoo to update all the sizes and not accidentally move them ...
% and make own context menu function to call the above. which used to be built in and is gone now because?

Accepted Answer

Scott Tatum
Scott Tatum on 9 Dec 2022
So, I semi answered my own question, but not with the answer that I really want. This is passable as a workaround, but not desireable. The reasons this still sucks are:
  1. cannot use "undo"
  2. have to set a separate menu to get keyboard shortcut to function, but that will be removed in future release, and it sticks that extra menu on your diagram toolstip
  3. extra menu, not under the "format" section where it should be
  4. cannot right click and hit single button or series of buttons because you can't apply a quick key letter to context menu items.
But, if you're like me and really don't want to use the toolstrip and like the context menu route, this works for now.
Create custom context menu with keyboard shortcuts by generating an sl_customization (see this help here for referece)
function sl_customization(cm)
% register custom menu functions
cm.addCustomMenuFcn('Simulink:ContextMenu',@getMyMenuItems)
cm.addCustomMenuFcn('Simulink:DiagramMenu',@getMyMenuItems) % This is here to make keyboard shortucts work
end
%% Define the custom menu function for sizes
function schemaFcns = getMyMenuItems(callbackInfo)
% Make it context dependant, and only show if multiple blocks selected
if length(find_system(gcs,'FindAll','on','SearchDepth',1,'Type','block','Selected','on')) > 2
schemaFcns = {@matchSizeMenu, ...
@matchHeightMenu, ...
@matchWidthMenu};
else
schemaFcns = {};
end
end
% Menu Schema for match size
function schema = matchSizeMenu(callbackInfo)
schema = sl_action_schema;
schema.label = 'Match Block Size';
schema.userdata = 'size';
schema.callback = @matchSize;
schema.accelerator = 'Ctrl+Alt+S'; % This works because the "DiagramMenu" above, but help says "to be removed"
end
% Menu Schema for match height
function schema = matchHeightMenu(callbackInfo)
schema = sl_action_schema;
schema.label = 'Match Block Height';
schema.userdata = 'height';
schema.callback = @matchSize;
schema.accelerator = 'Ctrl+Alt+H';
end
% Menu Schema for match width
function schema = matchWidthMenu(callbackInfo)
schema = sl_action_schema;
schema.label = 'Match Block Width';
schema.userdata = 'width';
schema.callback = @matchSize;
schema.accelerator = 'Ctrl+Alt+W';
end
% Function to match the size of the selected blocks based on the calling menu
function matchSize(callbackInfo)
% Get the selected block position
pos = get(gcbh,'Position');
sz = [pos(3)-pos(1), pos(4)-pos(2)]; % get the block size
% Find the rest of the selected blocks in this current subsystem
blks = find_system(gcs,'FindAll','on','SearchDepth',1,'Type','block','Selected','on');
blks(blks==get_param(gcs,'Handle')) = []; % Drop the parent block (not sure if always first, so find it)
% Check to see if multiple blocks selected
if length(blks) > 1
% Find the position of the selected blocks
pos = get(blks,'Position');
% Loop over the block positions updating to new ones
for n = 1:length(blks)
this = pos{n};
% adjust about the middle
md = [this(3)-this(1),this(4)-this(2)]./2 + [this(1), this(2)];
% Switch the callback type
switch callbackInfo.userdata
case 'size'
this(1) = md(1) - sz(1)/2;
this(3) = md(1) + sz(1)/2;
this(2) = md(2) - sz(2)/2;
this(4) = md(2) + sz(2)/2;
case 'height'
this(2) = md(2) - sz(2)/2;
this(4) = md(2) + sz(2)/2;
case 'width'
this(1) = md(1) - sz(1)/2;
this(3) = md(1) + sz(1)/2;
end
% Restore the updated position
pos{n} = this;
end
% Set the blocks to the new positions all at once
set(blks,{'Position'},pos);
end
end

More Answers (0)

Categories

Find more on Simulink Environment Customization in Help Center and File Exchange

Products


Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!