classdef CrossGUI < matlab.apps.AppBase
properties (Access = public)
CrossDialog matlab.ui.Figure
FileMenu matlab.ui.container.Menu
OpenFile matlab.ui.container.Menu
SaveFile matlab.ui.container.Menu
Exit matlab.ui.container.Menu
AboutMenu matlab.ui.container.Menu
MomentPanel matlab.ui.container.Panel
ax_moment matlab.ui.control.UIAxes
DeformedPanel matlab.ui.container.Panel
ax_deformed matlab.ui.control.UIAxes
ModelPanel matlab.ui.container.Panel
ax_model matlab.ui.control.UIAxes
MessagePanel matlab.ui.container.Panel
MessageText matlab.ui.control.Label
ControlRuler matlab.ui.container.Panel
DeleteSup matlab.ui.control.StateButton
InsertSup matlab.ui.control.StateButton
Precision matlab.ui.control.DropDown
GoThru matlab.ui.control.Button
Step matlab.ui.control.Button
Restart matlab.ui.control.Button
SupEnd matlab.ui.control.Button
SupInit matlab.ui.control.Button
end
properties (Access = public)
control CrossControl
end
methods (Access = private)
function deleteCallback(app)
choice = questdlg('Are you sure you want to exit?',...
'Exit','Exit','Cancel','Cancel');
switch choice
case 'Cancel'
return
end
app.delete();
end
end
methods (Access = public)
function updateTextMessage(app)
if app.control.solver.moreStepsToGo()
app.MessageText.Text = 'Moments are not balanced yet.';
else
app.MessageText.Text = 'Cross iterative solution completed.';
end
end
function setTextMessage(app,msg)
app.MessageText.Text = msg;
end
function updateSupInit(app,supinit)
if supinit == 0
app.SupInit.Icon = 'images/supinitfix.gif';
app.SupInit.Tooltip = 'Change initial support to clamped';
else
app.SupInit.Icon = 'images/supinitrel.gif';
app.SupInit.Tooltip = 'Change initial support to released';
end
end
function updateSupEnd(app,supend)
if supend == 0
app.SupEnd.Icon = 'images/supendfix.gif';
app.SupEnd.Tooltip = 'Change end support to clamped';
else
app.SupEnd.Icon = 'images/supendrel.gif';
app.SupEnd.Tooltip = 'Change end support to released';
end
end
function resetInsertSup(app)
if app.InsertSup.Value
app.InsertSup.Value = false;
end
end
function resetDeleteSup(app)
if app.DeleteSup.Value
app.DeleteSup.Value = false;
end
end
end
methods (Access = private)
function startupFcn(app)
app.control = CrossControl(app);
app.control.startup(app.CrossDialog,app.ax_model,app.ax_deformed,app.ax_moment);
app.CrossDialog.CloseRequestFcn = app.createCallbackFcn(@deleteCallback, false);
app.ax_model.Toolbar.Visible = 'off';
app.ax_model.Interactions = [];
app.ax_deformed.Toolbar.Visible = 'off';
app.ax_deformed.Interactions = [];
app.ax_moment.Toolbar.Visible = 'off';
app.ax_moment.Interactions = [];
end
function SupInitButtonPushed(app, event)
app.resetInsertSup();
app.resetDeleteSup();
app.control.toggleSupInit();
app.updateSupInit(app.control.solver.supinit);
app.updateTextMessage();
end
function SupEndButtonPushed(app, event)
app.resetInsertSup();
app.resetDeleteSup();
app.control.toggleSupEnd();
app.updateSupEnd(app.control.solver.supend);
app.updateTextMessage();
end
function RestartButtonPushed(app, event)
app.resetInsertSup();
app.resetDeleteSup();
app.control.restart();
app.updateTextMessage();
end
function StepButtonPushed(app, event)
app.resetInsertSup();
app.resetDeleteSup();
app.control.autoStep();
app.updateTextMessage();
end
function GoThruButtonPushed(app, event)
app.resetInsertSup();
app.resetDeleteSup();
app.control.goThru();
app.updateTextMessage();
end
function InsertSupValueChanged(app, event)
app.resetDeleteSup();
value = app.InsertSup.Value;
app.MessageText.Text = 'Insert an internal support with mouse pointer.';
end
function DeleteSupValueChanged(app, event)
app.resetInsertSup();
value = app.DeleteSup.Value;
app.MessageText.Text = 'Select an internal support for deletion with mouse pointer.';
end
function PrecisionValueChanged(app, event)
app.resetInsertSup();
app.resetDeleteSup();
value = app.Precision.Value;
if strcmp(value,'1 kNm')
decplc = 0;
elseif strcmp(value,'0.1 kNm')
decplc = 1;
else
decplc = 2;
end
app.control.setPrecision(decplc);
app.updateTextMessage();
end
function ExitMenuSelected(app, event)
app.deleteCallback();
end
function OpenFileMenuSelected(app, event)
app.resetInsertSup();
app.resetDeleteSup();
filterspec = {'*.crs'};
[filename,pathname] = uigetfile(filterspec,'Cross Program - Input file');
if ~isequal(filename,0)
fullname = strcat(pathname,filename);
app.control.openFile(fullname);
end
app.updateTextMessage();
end
function SaveFileMenuSelected(app, event)
app.resetInsertSup();
app.resetDeleteSup();
filterspec = {'*.crs'};
[filename,pathname] = uiputfile(filterspec,'Cross Program - Output file');
if ~isequal(filename,0)
fullname = strcat(pathname,filename);
app.control.saveFile(fullname);
end
end
function AboutMenuSelected(app, event)
msgbox({ 'PUC-Rio - CIV2801 - Fundamentos de Computação Gráfica Aplicada - 2022.2'; ' '; ...
'Program to demonstrate the Cross process applied to a continuous beam.' }, 'About Cross program');
end
function ModelPanel_SizeChangedFcn(app, event)
position = app.ModelPanel.Position;
panel_width = position(3);
panel_height = position(4);
canvas_x = 1;
canvas_y = 1;
canvas_width = panel_width-1;
canvas_height = panel_height-21;
app.ax_model.Position = [canvas_x canvas_y canvas_width canvas_height];
app.control.resizeCanvas(app.ax_model);
end
function DeformedPanel_SizeChangedFcn(app, event)
position = app.DeformedPanel.Position;
panel_width = position(3);
panel_height = position(4);
canvas_x = 1;
canvas_y = 1;
canvas_width = panel_width-1;
canvas_height = panel_height-21;
app.ax_deformed.Position = [canvas_x canvas_y canvas_width canvas_height];
app.control.resizeCanvas(app.ax_deformed);
end
function MomentPanel_SizeChangedFcn(app, event)
position = app.MomentPanel.Position;
panel_width = position(3);
panel_height = position(4);
canvas_x = 1;
canvas_y = 1;
canvas_width = panel_width-1;
canvas_height = panel_height-21;
app.ax_moment.Position = [canvas_x canvas_y canvas_width canvas_height];
app.control.resizeCanvas(app.ax_moment);
end
end
methods (Access = private)
function createComponents(app)
app.CrossDialog = uifigure('Visible', 'off');
app.CrossDialog.Position = [100 100 900 590];
app.CrossDialog.Name = 'Cross process of continuous beam';
app.CrossDialog.Scrollable = 'on';
app.FileMenu = uimenu(app.CrossDialog);
app.FileMenu.Text = 'File';
app.OpenFile = uimenu(app.FileMenu);
app.OpenFile.MenuSelectedFcn = createCallbackFcn(app, @OpenFileMenuSelected, true);
app.OpenFile.Text = 'Open';
app.SaveFile = uimenu(app.FileMenu);
app.SaveFile.MenuSelectedFcn = createCallbackFcn(app, @SaveFileMenuSelected, true);
app.SaveFile.Text = 'Save as ...';
app.Exit = uimenu(app.FileMenu);
app.Exit.MenuSelectedFcn = createCallbackFcn(app, @ExitMenuSelected, true);
app.Exit.Text = 'Exit ...';
app.AboutMenu = uimenu(app.CrossDialog);
app.AboutMenu.MenuSelectedFcn = createCallbackFcn(app, @AboutMenuSelected, true);
app.AboutMenu.Text = 'About';
app.ControlRuler = uipanel(app.CrossDialog);
app.ControlRuler.Position = [2 561 898 30];
app.SupInit = uibutton(app.ControlRuler, 'push');
app.SupInit.ButtonPushedFcn = createCallbackFcn(app, @SupInitButtonPushed, true);
app.SupInit.Icon = 'supinitfix.gif';
app.SupInit.IconAlignment = 'center';
app.SupInit.Tooltip = {'Change initial support to clamped'};
app.SupInit.Position = [0 5 21 22];
app.SupInit.Text = '';
app.SupEnd = uibutton(app.ControlRuler, 'push');
app.SupEnd.ButtonPushedFcn = createCallbackFcn(app, @SupEndButtonPushed, true);
app.SupEnd.Icon = 'supendrel.gif';
app.SupEnd.IconAlignment = 'center';
app.SupEnd.Tooltip = {'Change initial support to released'};
app.SupEnd.Position = [61 5 21 22];
app.SupEnd.Text = '';
app.Restart = uibutton(app.ControlRuler, 'push');
app.Restart.ButtonPushedFcn = createCallbackFcn(app, @RestartButtonPushed, true);
app.Restart.Icon = 'restart.gif';
app.Restart.IconAlignment = 'center';
app.Restart.Tooltip = {'Initialize interative solution of Cross process'};
app.Restart.Position = [125 5 21 22];
app.Restart.Text = '';
app.Step = uibutton(app.ControlRuler, 'push');
app.Step.ButtonPushedFcn = createCallbackFcn(app, @StepButtonPushed, true);
app.Step.Icon = 'step.gif';
app.Step.IconAlignment = 'center';
app.Step.Tooltip = {'Process one step of iterative solution '};
app.Step.Position = [145 5 21 22];
app.Step.Text = '';
app.GoThru = uibutton(app.ControlRuler, 'push');
app.GoThru.ButtonPushedFcn = createCallbackFcn(app, @GoThruButtonPushed, true);
app.GoThru.Icon = 'gothru.gif';
app.GoThru.IconAlignment = 'center';
app.GoThru.Tooltip = {'Go through: process all steps of iterative solution'};
app.GoThru.Position = [165 5 21 22];
app.GoThru.Text = '';
app.Precision = uidropdown(app.ControlRuler);
app.Precision.Items = {'1 kNm', '0.1 kNm', '0.01 kNm'};
app.Precision.ValueChangedFcn = createCallbackFcn(app, @PrecisionValueChanged, true);
app.Precision.Tooltip = {'Set bending moment precision of iterative solution'};
app.Precision.Position = [185 5 84 22];
app.Precision.Value = '0.1 kNm';
app.InsertSup = uibutton(app.ControlRuler, 'state');
app.InsertSup.ValueChangedFcn = createCallbackFcn(app, @InsertSupValueChanged, true);
app.InsertSup.Tooltip = {'Insert internal support'};
app.InsertSup.Icon = 'supinsert.gif';
app.InsertSup.Text = '';
app.InsertSup.Position = [21 5 21 22];
app.DeleteSup = uibutton(app.ControlRuler, 'state');
app.DeleteSup.ValueChangedFcn = createCallbackFcn(app, @DeleteSupValueChanged, true);
app.DeleteSup.Tooltip = {'Delete internal support'};
app.DeleteSup.Icon = 'supdelete.gif';
app.DeleteSup.Text = '';
app.DeleteSup.Position = [41 5 21 22];
app.MessagePanel = uipanel(app.CrossDialog);
app.MessagePanel.Position = [2 530 898 30];
app.MessageText = uilabel(app.MessagePanel);
app.MessageText.Position = [4 4 893 22];
app.MessageText.Text = 'Moments are not balanced yet.';
app.ModelPanel = uipanel(app.CrossDialog);
app.ModelPanel.AutoResizeChildren = 'off';
app.ModelPanel.Title = 'Continuous beam model';
app.ModelPanel.SizeChangedFcn = createCallbackFcn(app, @ModelPanel_SizeChangedFcn, true);
app.ModelPanel.Position = [2 357 898 172];
app.ax_model = uiaxes(app.ModelPanel);
app.ax_model.XLim = [0 1];
app.ax_model.YLim = [0 1];
app.ax_model.ZLim = [0 1];
app.ax_model.XColor = 'none';
app.ax_model.XTick = [];
app.ax_model.YColor = 'none';
app.ax_model.YTick = [];
app.ax_model.ZColor = 'none';
app.ax_model.Position = [1 1 896 150];
app.DeformedPanel = uipanel(app.CrossDialog);
app.DeformedPanel.AutoResizeChildren = 'off';
app.DeformedPanel.Title = 'Deformed configuration (displacements scale exaggerated)';
app.DeformedPanel.SizeChangedFcn = createCallbackFcn(app, @DeformedPanel_SizeChangedFcn, true);
app.DeformedPanel.Position = [3 187 898 172];
app.ax_deformed = uiaxes(app.DeformedPanel);
app.ax_deformed.XLim = [0 1];
app.ax_deformed.YLim = [0 1];
app.ax_deformed.ZLim = [0 1];
app.ax_deformed.XColor = 'none';
app.ax_deformed.XTick = [];
app.ax_deformed.YColor = 'none';
app.ax_deformed.YTick = [];
app.ax_deformed.ZColor = 'none';
app.ax_deformed.Position = [1 0 896 150];
app.MomentPanel = uipanel(app.CrossDialog);
app.MomentPanel.AutoResizeChildren = 'off';
app.MomentPanel.Title = 'Bending moment diagram (kNm)';
app.MomentPanel.SizeChangedFcn = createCallbackFcn(app, @MomentPanel_SizeChangedFcn, true);
app.MomentPanel.Position = [3 16 898 172];
app.ax_moment = uiaxes(app.MomentPanel);
app.ax_moment.XLim = [0 1];
app.ax_moment.YLim = [0 1];
app.ax_moment.ZLim = [0 1];
app.ax_moment.XColor = 'none';
app.ax_moment.XTick = [];
app.ax_moment.YColor = 'none';
app.ax_moment.YTick = [];
app.ax_moment.ZColor = 'none';
app.ax_moment.Position = [1 0 896 150];
app.CrossDialog.Visible = 'on';
end
end
methods (Access = public)
function app = CrossGUI
createComponents(app)
registerApp(app, app.CrossDialog)
runStartupFcn(app, @startupFcn)
if nargout == 0
clear app
end
end
function delete(app)
delete(app.CrossDialog)
end
end
end