Skip to content

Commit

Permalink
LVD: Added undo/redo capability
Browse files Browse the repository at this point in the history
  • Loading branch information
Arrowstar committed Oct 8, 2018
1 parent 87dc0d4 commit 2065863
Show file tree
Hide file tree
Showing 5 changed files with 248 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
classdef LVD_UndoRedoState < matlab.mixin.SetGet
%LVD_UndoRedoState Summary of this class goes here
% Detailed explanation goes here

properties
serialLvdData uint8
actionName(1,:) char
end

methods
function obj = LVD_UndoRedoState(lvdData, actionName)
obj.serialLvdData = getByteStreamFromArray(lvdData);
obj.actionName = actionName;
end

function [lvdData, actionName] = getUndoData(obj)
lvdData = getArrayFromByteStream(obj.serialLvdData);
actionName = obj.actionName;
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
classdef LVD_UndoRedoStateSet < matlab.mixin.SetGet
%LVD_UndoRedoStateSet Summary of this class goes here
% Detailed explanation goes here

properties
undo_states(:,1) LVD_UndoRedoState
undo_pointer (1,1) double = 0
end

methods
function obj = LVD_UndoRedoStateSet()
obj.undo_states = LVD_UndoRedoState.empty(1,0);
end

function addState(obj, hLvdFig, lvdData, actionName)
if(obj.undo_pointer > length(obj.undo_states))
error('Undo/redo states and the pointer are out of sync.');
end

if(obj.undo_pointer == 0)
obj.undo_states = LVD_UndoRedoState.empty(1,0);
obj.undo_states(end+1) = LVD_UndoRedoState(lvdData, actionName);
obj.undo_pointer = 1;
else
t_undo_states = obj.undo_states(1:obj.undo_pointer,:);
t_undo_states(end+1) = LVD_UndoRedoState(lvdData, actionName);
obj.undo_states = t_undo_states;
obj.undo_pointer = obj.undo_pointer + 1;
end

maxUndos = 25;
if(obj.undo_pointer>maxUndos)
obj.undo_states = obj.undo_states(end-(maxUndos-1):end,:);
obj.undo_pointer = maxUndos;
end

curName = get(hLvdFig,'Name');
if(~strcmpi(curName(end),'*'))
set(hLvdFig,'Name',[curName,'*']);
end
end

function lvdData = undo(obj, curLvdData)
lvdData = LvdData.empty(0,1);
if(obj.undo_pointer < 1 || obj.undo_pointer > length(obj.undo_states))
return;
end

if(obj.undo_pointer == length(obj.undo_states))
obj.undo_states(end+1) = LVD_UndoRedoState(curLvdData, '');
end

lvdData = obj.undo_states(obj.undo_pointer).getUndoData();
obj.undo_pointer = obj.undo_pointer - 1;
end

function lvdData = redo(obj)
lvdData = LvdData.empty(0,1);
if(obj.undo_pointer + 1 < 1 || obj.undo_pointer + 2 > length(obj.undo_states))
return;
end

lvdData = obj.undo_states(obj.undo_pointer+2).getUndoData();
obj.undo_pointer = obj.undo_pointer + 1;
end

function [tf, undoActionName] = shouldUndoMenuBeEnabled(obj)
if(obj.undo_pointer > 0)
undoActionName = obj.undo_states(obj.undo_pointer).actionName;
tf = true;
else
undoActionName = '';
tf = false;
end
end

function [tf, redoActionName] = shouldRedoMenuBeEnabled(obj)
if(obj.undo_pointer + 1 > 0 && obj.undo_pointer + 1 < length(obj.undo_states))
redoActionName = obj.undo_states(obj.undo_pointer+1).actionName;
tf = true;
else
redoActionName = '';
tf = false;
end
end
end
end
Binary file modified kspTOT_MissionArchitect/LaunchVehicleDesigner/ma_LvdMainGUI.fig
Binary file not shown.
147 changes: 140 additions & 7 deletions kspTOT_MissionArchitect/LaunchVehicleDesigner/ma_LvdMainGUI.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

% Edit the above text to modify the response to help ma_LvdMainGUI

% Last Modified by GUIDE v2.5 08-Oct-2018 13:26:49
% Last Modified by GUIDE v2.5 08-Oct-2018 14:27:31

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
Expand Down Expand Up @@ -62,8 +62,7 @@ function ma_LvdMainGUI_OpeningFcn(hObject, eventdata, handles, varargin)

setappdata(hObject,'current_save_location','');
setappdata(hObject,'application_title','KSP TOT Launch Vehicle Designer');
% setappdata(hObject,'undo_states',{});
% setappdata(hObject,'undo_pointer',0);
setappdata(hObject,'undoRedo',LVD_UndoRedoStateSet());

lvdData = LvdData.getDefaultLvdData(celBodyData);
setappdata(handles.ma_LvdMainGUI,'lvdData',lvdData);
Expand Down Expand Up @@ -133,6 +132,12 @@ function runScript(handles, lvdData)
% Get default command line output from handles structure
varargout{1} = handles.output;


function addUndoState(handles,actionName)
lvdData = getappdata(handles.ma_LvdMainGUI,'lvdData');
undoRedo = getappdata(handles.ma_LvdMainGUI,'undoRedo');

undoRedo.addState(handles.ma_LvdMainGUI, lvdData, actionName)

% --- Executes on selection change in scriptListbox.
function scriptListbox_Callback(hObject, eventdata, handles)
Expand All @@ -143,6 +148,8 @@ function scriptListbox_Callback(hObject, eventdata, handles)
% Hints: contents = cellstr(get(hObject,'String')) returns scriptListbox contents as cell array
% contents{get(hObject,'Value')} returns selected item from scriptListbox
if(strcmpi(get(handles.ma_LvdMainGUI,'SelectionType'),'open'))
addUndoState(handles,'Edit Event');

eventNum = get(hObject,'Value');
lvdData = getappdata(handles.ma_LvdMainGUI,'lvdData');

Expand Down Expand Up @@ -174,6 +181,8 @@ function insertEventButton_Callback(hObject, eventdata, handles)
% handles structure with handles and user data (see GUIDATA)
lvdData = getappdata(handles.ma_LvdMainGUI,'lvdData');

addUndoState(handles,'Insert Event');

selEvtNum = get(handles.scriptListbox,'Value');
event = LaunchVehicleEvent.getDefaultEvent(lvdData.script);
lvdData.script.addEventAtInd(event,selEvtNum);
Expand All @@ -191,6 +200,8 @@ function moveEventDown_Callback(hObject, eventdata, handles)
% handles structure with handles and user data (see GUIDATA)
lvdData = getappdata(handles.ma_LvdMainGUI,'lvdData');

addUndoState(handles,'Move Event Down');

eventNum = get(handles.scriptListbox,'Value');
lvdData.script.moveEvtAtIndexDown(eventNum);

Expand All @@ -208,6 +219,8 @@ function deleteEvent_Callback(hObject, eventdata, handles)
% handles structure with handles and user data (see GUIDATA)
lvdData = getappdata(handles.ma_LvdMainGUI,'lvdData');

addUndoState(handles,'Delete Event');

eventNum = get(handles.scriptListbox,'Value');
lvdData.script.removeEventFromIndex(eventNum);

Expand All @@ -230,6 +243,8 @@ function moveEventUp_Callback(hObject, eventdata, handles)
% handles structure with handles and user data (see GUIDATA)
lvdData = getappdata(handles.ma_LvdMainGUI,'lvdData');

addUndoState(handles,'Move Event Up');

eventNum = get(handles.scriptListbox,'Value');
lvdData.script.moveEvtAtIndexUp(eventNum);

Expand Down Expand Up @@ -323,6 +338,8 @@ function optimizeMissionMenu_Callback(hObject, eventdata, handles)
lvdData = getappdata(handles.ma_LvdMainGUI,'lvdData');
writeOutput = getappdata(handles.ma_LvdMainGUI,'write_to_output_func');

addUndoState(handles,'Optimize Mission');

lvdData.optimizer.optimize(writeOutput);

runScript(handles, lvdData);
Expand All @@ -342,6 +359,8 @@ function editLaunchVehicleMenu_Callback(hObject, eventdata, handles)
% handles structure with handles and user data (see GUIDATA)
lvdData = getappdata(handles.ma_LvdMainGUI,'lvdData');

addUndoState(handles,'Edit Launch Vehicle');

lvd_editLaunchVehicle(lvdData);

runScript(handles, lvdData);
Expand All @@ -362,6 +381,9 @@ function editConstraintsMenu_Callback(hObject, eventdata, handles)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
lvdData = getappdata(handles.ma_LvdMainGUI,'lvdData');

addUndoState(handles,'Edit Constraints');

lvd_EditConstraintsGUI(lvdData);

runScript(handles, lvdData);
Expand All @@ -375,6 +397,8 @@ function editInitialStateMenu_Callback(hObject, eventdata, handles)
lvdData = getappdata(handles.ma_LvdMainGUI,'lvdData');
hKsptotMainGUI = getappdata(handles.ma_LvdMainGUI,'ksptotMainGUI');

addUndoState(handles,'Edit Initial State');

lvd_EditInitialStateGUI(lvdData, hKsptotMainGUI);

runScript(handles, lvdData);
Expand Down Expand Up @@ -522,8 +546,7 @@ function newMissionPlanMenu_Callback(hObject, eventdata, handles, varargin)
return;
end

% setappdata(handles.ma_MainGUI,'undo_states',{});
% setappdata(handles.ma_MainGUI,'undo_pointer',0);
setappdata(handles.ma_LvdMainGUI,'undoRedo',LVD_UndoRedoStateSet());

celBodyData = getappdata(handles.ma_LvdMainGUI,'celBodyData');
write_to_output_func = getappdata(handles.ma_LvdMainGUI,'write_to_output_func');
Expand Down Expand Up @@ -584,8 +607,7 @@ function openMissionPlanMenu_Callback(hObject, eventdata, handles)

load(filePath);
if(exist('lvdData','var'))
% setappdata(handles.ma_MainGUI,'undo_states',{});
% setappdata(handles.ma_MainGUI,'undo_pointer',0);
setappdata(handles.ma_LvdMainGUI,'undoRedo',LVD_UndoRedoStateSet());

if(isfield(lvdData,'celBodyData') && ...
length(fields(celBodyData.sun)) == length(fields(lvdData.celBodyData.sun))) %#ok<NODEF>
Expand Down Expand Up @@ -731,3 +753,114 @@ function saveMissionPlanToolbar_ClickedCallback(hObject, eventdata, handles)
set(handles.newMissionPlanToolbar,'Enable','on');
set(handles.openMissionPlanToolbar,'Enable','on');
set(handles.saveMissionPlanToolbar,'Enable','on');


% --------------------------------------------------------------------
function editMenu_Callback(hObject, eventdata, handles)
% hObject handle to editMenu (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
undoRedo = getappdata(handles.ma_LvdMainGUI,'undoRedo');
[undoTf, undoActionName] = undoRedo.shouldUndoMenuBeEnabled();
[redoTf, redoActionName] = undoRedo.shouldRedoMenuBeEnabled();

if(undoTf)
set(handles.undoMenu,'Enable','on');
else
set(handles.undoMenu,'Enable','off');
end
set(handles.undoMenu,'Label',['Undo ',undoActionName]);

if(redoTf)
set(handles.redoMenu,'Enable','on');
else
set(handles.redoMenu,'Enable','off');
end
set(handles.redoMenu,'Label',['Redo ',redoActionName]);

% --------------------------------------------------------------------
function undoMenu_Callback(hObject, eventdata, handles)
% hObject handle to undoMenu (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
lvdData = getappdata(handles.ma_LvdMainGUI,'lvdData');
undoRedo = getappdata(handles.ma_LvdMainGUI,'undoRedo');
lvdData = undoRedo.undo(lvdData);

setappdata(handles.ma_LvdMainGUI,'lvdData',lvdData);

runScript(handles, lvdData);
lvd_processData(handles);

curName = get(handles.ma_LvdMainGUI,'Name');
if(~strcmpi(curName(end),'*'))
set(handles.ma_MainGUI,'Name',[curName,'*']);
end

editMenu_Callback([], [], handles);

% --------------------------------------------------------------------
function redoMenu_Callback(hObject, eventdata, handles)
% hObject handle to redoMenu (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
undoRedo = getappdata(handles.ma_LvdMainGUI,'undoRedo');
lvdData = undoRedo.redo();

if(not(isempty(lvdData)))
setappdata(handles.ma_LvdMainGUI,'lvdData',lvdData);

runScript(handles, lvdData);
lvd_processData(handles);
end

curName = get(handles.ma_LvdMainGUI,'Name');
if(~strcmpi(curName(end),'*'))
set(handles.ma_MainGUI,'Name',[curName,'*']);
end

editMenu_Callback([], [], handles);


% --- Executes when user attempts to close ma_LvdMainGUI.
function ma_LvdMainGUI_CloseRequestFcn(hObject, eventdata, handles)
% hObject handle to ma_LvdMainGUI (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)

% Hint: delete(hObject) closes the figure
if(strcmpi(handles.scriptWorkingLbl.Visible,'on') || ...
strcmpi(handles.plotWorkingLbl.Visible,'on'))
askToQuit = true;
else
askToQuit = false;
end

yesStr = 'Yes';
if(askToQuit)
response = questdlg(['KSPTOT is still processing. Any in-work data will be lost upon closing. Continue?'],'Close Mission Architect?',yesStr,'No','No');
else
response = yesStr;
end

if(~strcmpi(response,yesStr))
return;
else
if(isMissionPlanSaved(handles))
askToClear = false;
else
askToClear = true;
end

if(askToClear)
response = questdlg(['All unsaved work will be lost. Continue?'],'Close Launch Vehicle Designer?',yesStr,'No','No');
else
response = yesStr;
end

if(~strcmpi(response,yesStr))
return;
end

delete(hObject);
end
Binary file modified kspTOT_MissionArchitect/ma_MainGUI.fig
Binary file not shown.

0 comments on commit 2065863

Please sign in to comment.