NaN'];
+ end
+ end
+ end
+ end
+
+ EStudio_gui_erp_totl.ERP_M_T_Viewer_table = uitable(EStudio_gui_erp_totl.ERP_M_T_Viewer,'Data',Data_display_tra,'Units','Normalize');
+ if Bin_chans == 0
+ EStudio_gui_erp_totl.ERP_M_T_Viewer_table.RowName = RowName;
+ EStudio_gui_erp_totl.ERP_M_T_Viewer_table.ColumnName = ColumnName;
+ else
+ EStudio_gui_erp_totl.ERP_M_T_Viewer_table.RowName = ColumnName;
+ EStudio_gui_erp_totl.ERP_M_T_Viewer_table.ColumnName = RowName;
+ end
+ EStudio_gui_erp_totl.ERP_M_T_Viewer_table.BackgroundColor = line_colors_ldg;
+
+
+ if size(Data_display_tra,2)<12
+ ColumnWidth = {};
+ for Numofchan =1:size(Data_display_tra,2)
+ ColumnWidth{Numofchan} = EStudio_gui_erp_totl.ERP_M_T_Viewer.Position(3)/size(Data_display_tra,2);
+ end
+ EStudio_gui_erp_totl.ERP_M_T_Viewer_table.ColumnWidth = ColumnWidth;
+ elseif size(Data_display_tra,2) ==1
+ EStudio_gui_erp_totl.ERP_M_T_Viewer_table.ColumnWidth = {EStudio_gui_erp_totl.ERP_M_T_Viewer.Position(3)};
+ end
+
+ catch
+ for Numofbin = 1:observe_ERPDAT.ERP.nbin
+ Data_display{Numofbin,1} = '';
+ end
+
+ RowName = {};
+ for Numofbin = 1:observe_ERPDAT.ERP.nbin
+ RowName{Numofbin} = strcat('Bin',num2str((Numofbin)));
+ end
+ EStudio_gui_erp_totl.ERP_M_T_Viewer_table = uitable(EStudio_gui_erp_totl.ERP_M_T_Viewer,'Data',Data_display);
+ EStudio_gui_erp_totl.ERP_M_T_Viewer_table.RowName = RowName;
+ EStudio_gui_erp_totl.ERP_M_T_Viewer_table.ColumnName = {'No data are avalible'};
+ EStudio_gui_erp_totl.ERP_M_T_Viewer_table.ColumnWidth = {EStudio_gui_erp_totl.ERP_M_T_Viewer.Position(3)};
+ EStudio_gui_erp_totl.ERP_M_T_Viewer_table.BackgroundColor = line_colors_ldg;
+ EStudio_gui_erp_totl.ERP_M_T_Viewer_table.ForegroundColor = [1 1 1];
+ end
+
+ EStudio_gui_erp_totl.ERP_M_T_Viewer_table.FontSize = 12;
+else
+ set(EStudio_gui_erp_totl.plot_wav_legend,'Sizes',[80 -10]);
+ EStudio_gui_erp_totl.plotgrid.Heights(1) = 30; % set the first element (pageinfo) to 30px high
+ EStudio_gui_erp_totl.plotgrid.Heights(3) = 30; % set the second element (x axis) to 30px high
+ EStudio_gui_erp_totl.plotgrid.Heights(4) = 30;
+
+end
+end % redrawDemo
+
+
+function colors = get_colors(ncolors)
+% Each color gets 1 point divided into up to 2 of 3 groups (RGB).
+degree_step = 6/ncolors;
+angles = (0:ncolors-1)*degree_step;
+colors = nan(numel(angles),3);
+for i = 1:numel(angles)
+ if angles(i) < 1
+ colors(i,:) = [1 (angles(i)-floor(angles(i))) 0]*0.75;
+ elseif angles(i) < 2
+ colors(i,:) = [(1-(angles(i)-floor(angles(i)))) 1 0]*0.75;
+ elseif angles(i) < 3
+ colors(i,:) = [0 1 (angles(i)-floor(angles(i)))]*0.75;
+ elseif angles(i) < 4
+ colors(i,:) = [0 (1-(angles(i)-floor(angles(i)))) 1]*0.75;
+ elseif angles(i) < 5
+ colors(i,:) = [(angles(i)-floor(angles(i))) 0 1]*0.75;
+ else
+ colors(i,:) = [1 0 (1-(angles(i)-floor(angles(i))))]*0.75;
+ end
+end
+end
+
+
+%------------------Display the waveform for proir ERPset--------------------
+function page_minus(~,~,EStudio_gui_erp_totl)
+global observe_ERPDAT;
+S_ws_geterpset= estudioworkingmemory('selectederpstudio');
+if isempty(S_ws_geterpset)
+ S_ws_geterpset = observe_ERPDAT.CURRENTERP;
+
+ if isempty(S_ws_geterpset)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+end
+S_ws_getbinchan = estudioworkingmemory('geterpbinchan');
+S_ws_getbinchan.Select_index = S_ws_getbinchan.Select_index-1;
+Current_erp_Index = S_ws_geterpset(S_ws_getbinchan.Select_index);
+if Current_erp_Index > length(observe_ERPDAT.ALLERP)
+ beep;
+ disp('Waiting for modifing');
+ return;
+end
+observe_ERPDAT.CURRENTERP = Current_erp_Index;
+observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_erp_Index);
+estudioworkingmemory('geterpbinchan',S_ws_getbinchan);
+if length(S_ws_geterpset) ==1
+ Enable_minus = 'off';
+ Enable_plus = 'off';
+ Enable_plus_BackgroundColor = [0 0 0];
+ Enable_minus_BackgroundColor = [0 0 0];
+else
+
+ if S_ws_getbinchan.Select_index ==1
+ Enable_minus = 'off';
+ Enable_plus = 'on';
+
+ Enable_plus_BackgroundColor = [0 1 0];
+ Enable_minus_BackgroundColor = [0 0 0];
+ elseif S_ws_getbinchan.Select_index == length(S_ws_geterpset)
+ Enable_minus = 'on';
+ Enable_plus = 'off';
+ Enable_plus_BackgroundColor = [0 0 0];
+ Enable_minus_BackgroundColor = [0 1 0];
+ else
+ Enable_minus = 'on';
+ Enable_plus = 'on';
+ Enable_plus_BackgroundColor = [0 1 0];
+ Enable_minus_BackgroundColor = [0 1 0];
+ end
+end
+EStudio_gui_erp_totl.pageinfo_minus.Enable = Enable_minus;
+EStudio_gui_erp_totl.pageinfo_plus.Enable = Enable_plus;
+f_redrawERP_mt_viewer();
+EStudio_gui_erp_totl.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor;
+EStudio_gui_erp_totl.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor;
+
+MessageViewer= char(strcat('Plot prior page (<)'));
+erpworkingmemory('f_ERP_proces_messg',MessageViewer);
+observe_ERPDAT.Process_messg =1;
+try
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Process_messg =2;
+catch
+ observe_ERPDAT.Process_messg =3;
+end
+observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+end
+
+
+
+%%Edit the index of ERPsets
+function page_edit(Str,~,EStudio_gui_erp_totl)
+CurrentERPindex = str2num(Str.String);
+global observe_ERPDAT;
+S_ws_geterpset= estudioworkingmemory('selectederpstudio');
+if isempty(S_ws_geterpset)
+ S_ws_geterpset = observe_ERPDAT.CURRENTERP;
+ if isempty(S_ws_geterpset)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+end
+S_ws_getbinchan = estudioworkingmemory('geterpbinchan');
+if ~isempty(CurrentERPindex) && numel(CurrentERPindex)==1 && (CurrentERPindex<= numel(S_ws_geterpset))
+ S_ws_getbinchan.Select_index = CurrentERPindex;
+ Current_erp_Index = S_ws_geterpset(S_ws_getbinchan.Select_index);
+ % EStudio_gui_erp_totl.pageinfo_edit.String = num2str(S_ws_getbinchan.Select_index);
+ if Current_erp_Index > length(observe_ERPDAT.ALLERP)
+ beep;
+ disp('Waiting for modifing');
+ return;
+ end
+ observe_ERPDAT.CURRENTERP = Current_erp_Index;
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_erp_Index);
+ estudioworkingmemory('geterpbinchan',S_ws_getbinchan);
+ if length(S_ws_geterpset) ==1
+ Enable_minus = 'off';
+ Enable_plus = 'off';
+ Enable_plus_BackgroundColor = [0 0 0];
+ Enable_minus_BackgroundColor = [0 0 0];
+ else
+ if CurrentERPindex ==1
+ Enable_minus = 'off';
+ Enable_plus = 'on';
+ Enable_plus_BackgroundColor = [0 1 0];
+ Enable_minus_BackgroundColor = [1 1 1];
+ elseif CurrentERPindex == length(S_ws_geterpset)
+ Enable_minus = 'on';
+ Enable_plus = 'off';
+ Enable_plus_BackgroundColor = [0 0 0];
+ Enable_minus_BackgroundColor = [0 1 0];
+ else
+ Enable_minus = 'on';
+ Enable_plus = 'on';
+ Enable_plus_BackgroundColor = [0 1 0];
+ Enable_minus_BackgroundColor = [0 1 0];
+ end
+ end
+ EStudio_gui_erp_totl.pageinfo_minus.Enable = Enable_minus;
+ EStudio_gui_erp_totl.pageinfo_plus.Enable = Enable_plus;
+ EStudio_gui_erp_totl.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor;
+ EStudio_gui_erp_totl.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor;
+
+ MessageViewer= char(strcat('Page Editor'));
+ erpworkingmemory('f_ERP_proces_messg',MessageViewer);
+ observe_ERPDAT.Process_messg =1;
+ try
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Process_messg =2;
+ catch
+ observe_ERPDAT.Process_messg =3;
+ end
+end
+observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+end
+
+
+%------------------Display the waveform for next ERPset--------------------
+function page_plus(~,~,EStudio_gui_erp_totl)
+global observe_ERPDAT;
+S_ws_geterpset= estudioworkingmemory('selectederpstudio');
+if isempty(S_ws_geterpset)
+ S_ws_geterpset = observe_ERPDAT.CURRENTERP;
+ if isempty(S_ws_geterpset)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+end
+S_ws_getbinchan = estudioworkingmemory('geterpbinchan');
+S_ws_getbinchan.Select_index = S_ws_getbinchan.Select_index+1;
+Current_erp_Index = S_ws_geterpset(S_ws_getbinchan.Select_index);
+if Current_erp_Index > length(observe_ERPDAT.ALLERP)
+ beep;
+ disp('Waiting for modifing');
+ return;
+end
+observe_ERPDAT.CURRENTERP = Current_erp_Index;
+observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_erp_Index);
+estudioworkingmemory('geterpbinchan',S_ws_getbinchan);
+if length(S_ws_geterpset) ==1
+ Enable_minus = 'off';
+ Enable_plus = 'off';
+ Enable_plus_BackgroundColor = [0 0 0];
+ Enable_minus_BackgroundColor = [0 0 0];
+else
+
+ if S_ws_getbinchan.Select_index ==1
+ Enable_minus = 'off';
+ Enable_plus = 'on';
+ Enable_plus_BackgroundColor = [0 1 0];
+ Enable_minus_BackgroundColor = [1 1 1];
+ elseif S_ws_getbinchan.Select_index == length(S_ws_geterpset)
+ Enable_minus = 'on';
+ Enable_plus = 'off';
+ Enable_plus_BackgroundColor = [0 0 0];
+ Enable_minus_BackgroundColor = [0 1 0];
+
+
+ else
+ Enable_minus = 'on';
+ Enable_plus = 'on';
+ Enable_plus_BackgroundColor = [0 1 0];
+ Enable_minus_BackgroundColor = [0 1 0];
+ end
+end
+EStudio_gui_erp_totl.pageinfo_minus.Enable = Enable_minus;
+EStudio_gui_erp_totl.pageinfo_plus.Enable = Enable_plus;
+EStudio_gui_erp_totl.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor;
+EStudio_gui_erp_totl.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor;
+
+MessageViewer= char(strcat('Plot next page (>)'));
+erpworkingmemory('f_ERP_proces_messg',MessageViewer);
+observe_ERPDAT.Process_messg =1;
+try
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Process_messg =2;
+catch
+ observe_ERPDAT.Process_messg =3;
+end
+observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+end
+
+
+%%Mark the area or latency/amplitude of interest within defined latecies%%%
+function ERP_mark_area_latency(r_ax,timex,moption,plot_erp_data,latency,line_colors,offset,Plority_plot)
+try
+ cwm_backgb = erpworkingmemory('MWColor');
+catch
+ cwm_backgb=[0.7 0.7 0.7];
+end
+if isempty(cwm_backgb)
+ cwm_backgb=[0.7 0.7 0.7];
+end
+
+try
+ cwm = erpworkingmemory('MTLineColor');
+catch
+ cwm =[0 0 0];
+end
+if isempty(cwm)
+ cwm=[0 0 0];
+end
+
+global observe_ERPDAT;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Plot area within the defined time-window%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%Set area within the defined time-window for 1.Fractional area latency, 2. Numerical integration/Area between two fixed latencies
+mearea = { 'areat', 'areap', 'arean','areazt','areazp','areazn', 'ninteg','nintegz'};
+
+[~,Num_data,Num_plot] = size(plot_erp_data);
+
+if ismember_bc2(moption, mearea) || ismember_bc2(moption, {'fareatlat', 'fareaplat','fninteglat','fareanlat'})
+ if numel(latency) ==2
+ latx = latency;
+ [xxx, latsamp] = closest(timex, latx);
+ datax = plot_erp_data(latsamp(1):latsamp(2),:,:);
+ end
+ Time_res = timex(2)-timex(1);
+
+ if ismember_bc2(moption, {'areap', 'fareaplat'}) % positive area
+
+ for Numofstione = 1:size(datax,3)
+ for Numofstitwo = 1:size(datax,2)
+ timexx = timex(latsamp(1):latsamp(2));
+ dataxx = squeeze(datax(:,Numofstitwo,Numofstione));
+ data_check = dataxx-offset(Numofstione);
+ if Plority_plot==1
+ dataxx(data_check<0) = [];
+ timexx(data_check<0) = [];
+ elseif Plority_plot ==-1
+ dataxx(data_check>0) = [];
+ timexx(data_check>0) = [];
+ else
+ dataxx(data_check<0) = [];
+ timexx(data_check<0) = [];
+ end
+
+ if ~isempty(dataxx) && numel(dataxx)>=2
+ %%Check isolated point
+ Check_outlier =[];
+ count = 0;
+
+ if (timexx(2)-timexx(1)>Time_res)
+ count= count +1;
+ Check_outlier(count) = 1;
+ end
+ if numel(dataxx)>=3
+ for Numofsample = 2:length(timexx)-1
+ if (timexx(Numofsample+1)-timexx(Numofsample)>Time_res) && (timexx(Numofsample)-timexx(Numofsample-1)< Time_res)
+ count = count+1;
+ Check_outlier(count) = Numofsample;
+ end
+ end
+ end
+ dataxx(Check_outlier) = [];
+ timexx(Check_outlier) = [];
+
+ Check_isolated =[];
+ count = 0;
+ for Numofsample = 1:length(timexx)-1
+ if timexx(Numofsample+1)-timexx(Numofsample)>Time_res
+ count = count+1;
+ Check_isolated(count) = Numofsample;
+ end
+ end
+ if numel(Check_isolated) ==1
+ inBetweenRegionX1 = [timexx(1:Check_isolated(1)),fliplr(timexx(1:Check_isolated(1)))];
+ inBetweenRegionY1 = [squeeze(dataxx(1:Check_isolated(1)))',fliplr(offset(Numofstione)*ones(1,numel(timexx(1:Check_isolated(1)))))];
+ fill(r_ax,inBetweenRegionX1, inBetweenRegionY1,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+
+ inBetweenRegionX2 = [timexx(Check_isolated(1)+1:end),fliplr(timexx(Check_isolated(1)+1:end))];
+ inBetweenRegionY2 = [squeeze(dataxx(Check_isolated(1)+1:end))',fliplr(offset(Numofstione)*ones(1,numel(timexx(Check_isolated(1)+1:end))))];
+ fill(r_ax,inBetweenRegionX2, inBetweenRegionY2,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+ elseif numel(Check_isolated) >1
+ for Numofrange = 1:numel(Check_isolated)-1
+
+ inBetweenRegionX = [timexx(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)),fliplr(timexx(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))];
+ inBetweenRegionY = [squeeze(dataxx(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))',fliplr(offset(Numofstione)*ones(1,numel(timexx(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))))];
+ fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+
+ end
+ inBetweenRegionX1 = [timexx(1:Check_isolated(1)),fliplr(timexx(1:Check_isolated(1)))];
+ inBetweenRegionY1 = [squeeze(dataxx(1:Check_isolated(1)))',fliplr(offset(Numofstione)*ones(1,numel(timexx(1:Check_isolated(1)))))];
+ fill(r_ax,inBetweenRegionX1, inBetweenRegionY1,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+
+ inBetweenRegionX2 = [timexx(Check_isolated(Numofrange+1)+1:end),fliplr(timexx(Check_isolated(Numofrange+1)+1:end))];
+ inBetweenRegionY2 = [squeeze(dataxx(Check_isolated(Numofrange+1)+1:end))',fliplr(offset(Numofstione)*ones(1,numel(timexx(Check_isolated(Numofrange+1)+1:end))))];
+ fill(r_ax,inBetweenRegionX2, inBetweenRegionY2,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+
+ else
+ inBetweenRegionX = [timexx,fliplr(timexx)];
+ inBetweenRegionY = [squeeze(dataxx)',fliplr(offset(Numofstione)*ones(1,numel(timexx)))];
+ fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+ end
+ end
+
+ end
+
+ end
+ elseif ismember_bc2(moption, {'arean', 'fareanlat'}) % negative area
+ for Numofstione = 1:size(datax,3)
+ for Numofstitwo = 1:size(datax,2)
+ timexx = timex(latsamp(1):latsamp(2));
+ dataxx = squeeze(datax(:,Numofstitwo,Numofstione));
+ data_check = dataxx-offset(Numofstione);
+ if Plority_plot==1
+ dataxx(data_check>0) = [];
+ timexx(data_check>0) = [];
+ elseif Plority_plot ==-1
+ dataxx(data_check<0) = [];
+ timexx(data_check<0) = [];
+ else
+ dataxx(data_check>0) = [];
+ timexx(data_check>0) = [];
+ end
+
+ %%Check isolated point
+ if ~isempty(dataxx) && numel(dataxx)>=2
+ Check_outlier =[];
+ count = 0;
+
+ if (timexx(2)-timexx(1)>Time_res)
+ count= count +1;
+ Check_outlier(count) = 1;
+ end
+ if numel(dataxx)>=3
+ for Numofsample = 2:length(timexx)-1
+ if (timexx(Numofsample+1)-timexx(Numofsample)>Time_res) && (timexx(Numofsample)-timexx(Numofsample-1)< Time_res)
+ count = count+1;
+ Check_outlier(count) = Numofsample;
+ end
+ end
+ end
+ dataxx(Check_outlier) = [];
+ timexx(Check_outlier) = [];
+
+ Check_isolated =[];
+ count = 0;
+ for Numofsample = 1:length(timexx)-1
+ if timexx(Numofsample+1)-timexx(Numofsample)>Time_res
+ count = count+1;
+ Check_isolated(count) = Numofsample;
+ end
+ end
+ if numel(Check_isolated) ==1
+ inBetweenRegionX1 = [timexx(1:Check_isolated(1)),fliplr(timexx(1:Check_isolated(1)))];
+ inBetweenRegionY1 = [squeeze(dataxx(1:Check_isolated(1)))',fliplr(offset(Numofstione)*ones(1,numel(timexx(1:Check_isolated(1)))))];
+ fill(r_ax,inBetweenRegionX1, inBetweenRegionY1,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+
+ inBetweenRegionX2 = [timexx(Check_isolated(1)+1:end),fliplr(timexx(Check_isolated(1)+1:end))];
+ inBetweenRegionY2 = [squeeze(dataxx(Check_isolated(1)+1:end))',fliplr(offset(Numofstione)*ones(1,numel(timexx(Check_isolated(1)+1:end))))];
+ fill(r_ax,inBetweenRegionX2, inBetweenRegionY2,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+ elseif numel(Check_isolated) >1
+ for Numofrange = 1:numel(Check_isolated)-1
+
+ inBetweenRegionX = [timexx(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)),fliplr(timexx(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))];
+ inBetweenRegionY = [squeeze(dataxx(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))',fliplr(offset(Numofstione)*ones(1,numel(timexx(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))))];
+ fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+
+ end
+ inBetweenRegionX1 = [timexx(1:Check_isolated(1)),fliplr(timexx(1:Check_isolated(1)))];
+ inBetweenRegionY1 = [squeeze(dataxx(1:Check_isolated(1)))',fliplr(offset(Numofstione)*ones(1,numel(timexx(1:Check_isolated(1)))))];
+ fill(r_ax,inBetweenRegionX1, inBetweenRegionY1,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+
+ inBetweenRegionX2 = [timexx(Check_isolated(Numofrange+1)+1:end),fliplr(timexx(Check_isolated(Numofrange+1)+1:end))];
+ inBetweenRegionY2 = [squeeze(dataxx(Check_isolated(Numofrange+1)+1:end))',fliplr(offset(Numofstione)*ones(1,numel(timexx(Check_isolated(Numofrange+1)+1:end))))];
+ fill(r_ax,inBetweenRegionX2, inBetweenRegionY2,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+
+ else
+ inBetweenRegionX = [timexx,fliplr(timexx)];
+ inBetweenRegionY = [squeeze(dataxx)',fliplr(offset(Numofstione)*ones(1,numel(timexx)))];
+ fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+ end
+ end
+ end
+ end
+
+
+ elseif ismember_bc2(moption, {'ninteg', 'fninteglat'}) % integration(area for negative substracted from area for positive)
+ for Numofstione = 1:size(datax,3)
+ for Numofstitwo = 1:size(datax,2)
+ timexxp = timex(latsamp(1):latsamp(2));
+ dataxxp = squeeze(datax(:,Numofstitwo,Numofstione));
+ timexxn = timex(latsamp(1):latsamp(2));
+ dataxxn = squeeze(datax(:,Numofstitwo,Numofstione));
+ data_check = dataxxn-offset(Numofstione);
+ if Plority_plot==1
+ dataxxp(data_check<0) = [];
+ timexxp(data_check<0) = [];
+ dataxxn(data_check>0) = [];
+ timexxn(data_check>0) = [];
+
+ elseif Plority_plot ==-1
+ dataxxp(data_check>0) = [];
+ timexxp(data_check>0) = [];
+ dataxxn(data_check<0) = [];
+ timexxn(data_check<0) = [];
+ else
+ dataxxp(data_check<0) = [];
+ timexxp(data_check<0) = [];
+ dataxxn(data_check>0) = [];
+ timexxn(data_check>0) = [];
+ end
+
+
+ if ~isempty(dataxxp) && numel(dataxxp)>=2
+ %%Check isolated point
+ Check_outlierp =[];
+ count = 0;
+
+ if (timexxp(2)-timexxp(1)>Time_res)
+ count= count +1;
+ Check_outlierp(count) = 1;
+ end
+ if numel(dataxxp)>=3
+ for Numofsample = 2:length(timexxp)-1
+ if (timexxp(Numofsample+1)-timexxp(Numofsample)>Time_res) && (timexxp(Numofsample)-timexxp(Numofsample-1)< Time_res)
+ count = count+1;
+ Check_outlierp(count) = Numofsample;
+ end
+ end
+ end
+ dataxxp(Check_outlierp) = [];
+ timexxp(Check_outlierp) = [];
+
+ Check_isolated =[];
+ count = 0;
+ for Numofsample = 1:length(timexxp)-1
+ if timexxp(Numofsample+1)-timexxp(Numofsample)>Time_res
+ count = count+1;
+ Check_isolated(count) = Numofsample;
+ end
+ end
+ if numel(Check_isolated) ==1
+ inBetweenRegionXp1 = [timexxp(1:Check_isolated(1)),fliplr(timexxp(1:Check_isolated(1)))];
+ inBetweenRegionYp1 = [squeeze(dataxxp(1:Check_isolated(1)))',fliplr(offset(Numofstione)*ones(1,numel(timexxp(1:Check_isolated(1)))))];
+ fill(r_ax,inBetweenRegionXp1, inBetweenRegionYp1,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+
+ inBetweenRegionXp2 = [timexxp(Check_isolated(1)+1:end),fliplr(timexxp(Check_isolated(1)+1:end))];
+ inBetweenRegionYp2 = [squeeze(dataxxp(Check_isolated(1)+1:end))',fliplr(offset(Numofstione)*ones(1,numel(timexxp(Check_isolated(1)+1:end))))];
+ fill(r_ax,inBetweenRegionXp2, inBetweenRegionYp2,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+ elseif numel(Check_isolated) >1
+ for Numofrange = 1:numel(Check_isolated)-1
+
+ inBetweenRegionX = [timexxp(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)),fliplr(timexxp(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))];
+ inBetweenRegionY = [squeeze(dataxxp(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))',fliplr(offset(Numofstione)*ones(1,numel(timexxp(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))))];
+ fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+
+ end
+ inBetweenRegionX1 = [timexxp(1:Check_isolated(1)),fliplr(timexxp(1:Check_isolated(1)))];
+ inBetweenRegionY1 = [squeeze(dataxxp(1:Check_isolated(1)))',fliplr(offset(Numofstione)*ones(1,numel(timexxp(1:Check_isolated(1)))))];
+ fill(r_ax,inBetweenRegionX1, inBetweenRegionY1,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+
+ inBetweenRegionX2 = [timexxp(Check_isolated(Numofrange+1)+1:end),fliplr(timexxp(Check_isolated(Numofrange+1)+1:end))];
+ inBetweenRegionY2 = [squeeze(dataxxp(Check_isolated(Numofrange+1)+1:end))',fliplr(offset(Numofstione)*ones(1,numel(timexxp(Check_isolated(Numofrange+1)+1:end))))];
+ fill(r_ax,inBetweenRegionX2, inBetweenRegionY2,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+
+ else
+ inBetweenRegionX = [timexxp,fliplr(timexxp)];
+ inBetweenRegionY = [squeeze(dataxxp)',fliplr(offset(Numofstione)*ones(1,numel(timexxp)))];
+ fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+ end
+ end%Positive part end
+
+ if ~isempty(dataxxn) && numel(dataxxn)>=2
+ %%Check isolated point
+ Check_outliern =[];
+ count = 0;
+
+ if (timexxn(2)-timexxn(1)>Time_res)
+ count= count +1;
+ Check_outliern(count) = 1;
+ end
+ if numel(dataxxn)>=3
+ for Numofsample = 2:length(timexxn)-1
+ if (timexxn(Numofsample+1)-timexxn(Numofsample)>Time_res) && (timexxn(Numofsample)-timexxn(Numofsample-1)< Time_res)
+ count = count+1;
+ Check_outliern(count) = Numofsample;
+ end
+ end
+ end
+ dataxxn(Check_outliern) = [];
+ timexxn(Check_outliern) = [];
+
+ Check_isolated =[];
+ count = 0;
+ for Numofsample = 1:length(timexxn)-1
+ if timexxn(Numofsample+1)-timexxn(Numofsample)>Time_res
+ count = count+1;
+ Check_isolated(count) = Numofsample;
+ end
+ end
+ if numel(Check_isolated) ==1
+ inBetweenRegionXp1 = [timexxn(1:Check_isolated(1)),fliplr(timexxn(1:Check_isolated(1)))];
+ inBetweenRegionYp1 = [squeeze(dataxxn(1:Check_isolated(1)))',fliplr(offset(Numofstione)*ones(1,numel(timexxn(1:Check_isolated(1)))))];
+ fill(r_ax,inBetweenRegionXp1, inBetweenRegionYp1,line_colors(Numofstitwo,:,:).*0.3,'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+
+ inBetweenRegionXp2 = [timexxn(Check_isolated(1)+1:end),fliplr(timexxn(Check_isolated(1)+1:end))];
+ inBetweenRegionYp2 = [squeeze(dataxxn(Check_isolated(1)+1:end))',fliplr(offset(Numofstione)*ones(1,numel(timexxn(Check_isolated(1)+1:end))))];
+ fill(r_ax,inBetweenRegionXp2, inBetweenRegionYp2,line_colors(Numofstitwo,:,:).*0.3,'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+ elseif numel(Check_isolated) >1
+ for Numofrange = 1:numel(Check_isolated)-1
+
+ inBetweenRegionX = [timexxn(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)),fliplr(timexxn(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))];
+ inBetweenRegionY = [squeeze(dataxxn(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))',fliplr(offset(Numofstione)*ones(1,numel(timexxn(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))))];
+ fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:).*0.3,'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+
+ end
+ inBetweenRegionX1 = [timexxn(1:Check_isolated(1)),fliplr(timexxn(1:Check_isolated(1)))];
+ inBetweenRegionY1 = [squeeze(dataxxn(1:Check_isolated(1)))',fliplr(offset(Numofstione)*ones(1,numel(timexxn(1:Check_isolated(1)))))];
+ fill(r_ax,inBetweenRegionX1, inBetweenRegionY1,line_colors(Numofstitwo,:,:).*0.3,'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+
+ inBetweenRegionX2 = [timexxn(Check_isolated(Numofrange+1)+1:end),fliplr(timexxn(Check_isolated(Numofrange+1)+1:end))];
+ inBetweenRegionY2 = [squeeze(dataxxn(Check_isolated(Numofrange+1)+1:end))',fliplr(offset(Numofstione)*ones(1,numel(timexxn(Check_isolated(Numofrange+1)+1:end))))];
+ fill(r_ax,inBetweenRegionX2, inBetweenRegionY2,line_colors(Numofstitwo,:,:).*0.3,'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+
+ else
+ inBetweenRegionX = [timexxn,fliplr(timexxn)];
+ inBetweenRegionY = [squeeze(dataxxn)',fliplr(offset(Numofstione)*ones(1,numel(timexxn)))];
+ fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:).*0.3,'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+ end
+ end%%Negative part end
+ end
+ end
+
+ elseif ismember_bc2(moption, {'areat', 'fareatlat'})% negative values become positive
+
+ for Numofstione = 1:size(datax,3)
+ for Numofstitwo = 1:size(datax,2)
+ timexx = timex(latsamp(1):latsamp(2));
+ dataxx = squeeze(datax(:,Numofstitwo,Numofstione));
+ inBetweenRegionX = [timexx,fliplr(timexx)];
+ inBetweenRegionY = [squeeze(dataxx)',fliplr(offset(Numofstione)*ones(1,numel(timexx)))];
+ fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+ end
+ end
+
+ elseif ismember_bc2(moption, {'areazt','areazp','areazn', 'nintegz'})
+ [new_erp_data, Amp_out,Lat]= f_ERP_plot_wav(observe_ERPDAT.ERP);
+ if strcmp(moption,'areazt')%% all area were included
+
+ for Numofstione = 1:size(plot_erp_data,3)
+ for Numofstitwo = 1:size(plot_erp_data,2)
+ latx = Lat{Numofstitwo,Numofstione};
+ [xxx, latsamp] = closest(timex, latx);
+ datax = plot_erp_data(latsamp(1):latsamp(2),:,:);
+ timexx = timex(latsamp(1):latsamp(2));
+ dataxx = squeeze(datax(:,Numofstitwo,Numofstione));
+ inBetweenRegionX = [timexx,fliplr(timexx)];
+ inBetweenRegionY = [squeeze(dataxx)',fliplr(offset(Numofstione)*ones(1,numel(timexx)))];
+ fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+ end
+ end
+
+ elseif strcmp(moption,'areazp')%% Only positive area was included
+
+ for Numofstione = 1:size(plot_erp_data,3)
+ for Numofstitwo = 1:size(plot_erp_data,2)
+ latx = Lat{Numofstitwo,Numofstione};
+ [xxx, latsamp] = closest(timex, latx);
+ datax = plot_erp_data(latsamp(1):latsamp(2),:,:);
+ timexx = timex(latsamp(1):latsamp(2));
+ timexx_unsl = timex(latsamp(1):latsamp(2));
+ dataxx = squeeze(datax(:,Numofstitwo,Numofstione));
+ data_check_unsl = squeeze(datax(:,Numofstitwo,Numofstione));
+ data_check = dataxx -offset(Numofstione);
+ if Plority_plot==1
+ dataxx(data_check<0) = [];
+ timexx(data_check<0) = [];
+ data_check_unsl(data_check>0) =[];
+ timexx_unsl(data_check>0) = [];
+ elseif Plority_plot ==-1
+ dataxx(data_check>0) = [];
+ timexx(data_check>0) = [];
+ data_check_unsl(data_check<0) =[];
+ timexx_unsl(data_check<0) = [];
+ else
+ dataxx(data_check<0) = [];
+ timexx(data_check<0) = [];
+ data_check_unsl(data_check>0) =[];
+ timexx_unsl(data_check>0) = [];
+ end
+ inBetweenRegionX = [timexx,fliplr(timexx)];
+ inBetweenRegionY = [squeeze(dataxx)',fliplr(offset(Numofstione)*ones(1,numel(timexx)))];
+ fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+ inBetweenRegionX_unsl = [timexx_unsl,fliplr(timexx_unsl)];
+ inBetweenRegionY_unsl = [squeeze(data_check_unsl)',fliplr(offset(Numofstione)*ones(1,numel(timexx_unsl)))];
+ fill(r_ax,inBetweenRegionX_unsl, inBetweenRegionY_unsl,[1 1 1],'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+
+ end
+ end
+
+
+ elseif strcmp(moption,'areazn')%% Only positive area was included
+
+ for Numofstione = 1:size(plot_erp_data,3)
+ for Numofstitwo = 1:size(plot_erp_data,2)
+ latx = Lat{Numofstitwo,Numofstione};
+ [xxx, latsamp] = closest(timex, latx);
+ datax = plot_erp_data(latsamp(1):latsamp(2),:,:);
+ timexx = timex(latsamp(1):latsamp(2));
+ timexx_unsl = timex(latsamp(1):latsamp(2));
+ dataxx = squeeze(datax(:,Numofstitwo,Numofstione));
+ data_check_unsl = squeeze(datax(:,Numofstitwo,Numofstione));
+ data_check = dataxx -offset(Numofstione);
+ if Plority_plot==1
+ dataxx(data_check>0) = [];
+ timexx(data_check>0) = [];
+ data_check_unsl(data_check<0) =[];
+ timexx_unsl(data_check<0) = [];
+ elseif Plority_plot ==-1
+ dataxx(data_check<0) = [];
+ timexx(data_check<0) = [];
+ data_check_unsl(data_check>0) =[];
+ timexx_unsl(data_check>0) = [];
+ else
+ dataxx(data_check>0) = [];
+ timexx(data_check>0) = [];
+ data_check_unsl(data_check<0) =[];
+ timexx_unsl(data_check<0) = [];
+ end
+ inBetweenRegionX = [timexx,fliplr(timexx)];
+ inBetweenRegionY = [squeeze(dataxx)',fliplr(offset(Numofstione)*ones(1,numel(timexx)))];
+ fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+ inBetweenRegionX_unsl = [timexx_unsl,fliplr(timexx_unsl)];
+ inBetweenRegionY_unsl = [squeeze(data_check_unsl)',fliplr(offset(Numofstione)*ones(1,numel(timexx_unsl)))];
+ fill(r_ax,inBetweenRegionX_unsl, inBetweenRegionY_unsl,[1 1 1],'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+ end
+ end
+
+ elseif strcmp(moption,'nintegz')%% Only positive area was included
+
+ for Numofstione = 1:size(plot_erp_data,3)
+ for Numofstitwo = 1:size(plot_erp_data,2)
+ latx = Lat{Numofstitwo,Numofstione};
+ [xxx, latsamp] = closest(timex, latx);
+ datax = plot_erp_data(latsamp(1):latsamp(2),:,:);
+ timexx = timex(latsamp(1):latsamp(2));
+ timexx_unsl = timex(latsamp(1):latsamp(2));
+ dataxx = squeeze(datax(:,Numofstitwo,Numofstione));
+ data_check_unsl = squeeze(datax(:,Numofstitwo,Numofstione));
+ data_check = dataxx -offset(Numofstione);
+ if Plority_plot==1
+ dataxx(data_check<0) = [];
+ timexx(data_check<0) = [];
+ data_check_unsl(data_check>0) =[];
+ timexx_unsl(data_check>0) = [];
+ elseif Plority_plot ==-1
+ dataxx(data_check>0) = [];
+ timexx(data_check>0) = [];
+ data_check_unsl(data_check<0) =[];
+ timexx_unsl(data_check<0) = [];
+ else
+ dataxx(data_check<0) = [];
+ timexx(data_check<0) = [];
+ data_check_unsl(data_check>0) =[];
+ timexx_unsl(data_check>0) = [];
+ end
+ inBetweenRegionX = [timexx,fliplr(timexx)];
+ inBetweenRegionY = [squeeze(dataxx)',fliplr(offset(Numofstione)*ones(1,numel(timexx)))];
+ fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+ inBetweenRegionX_unsl = [timexx_unsl,fliplr(timexx_unsl)];%
+ inBetweenRegionY_unsl = [squeeze(data_check_unsl)',fliplr(offset(Numofstione)*ones(1,numel(timexx_unsl)))];
+ fill(r_ax,inBetweenRegionX_unsl, inBetweenRegionY_unsl,line_colors(Numofstitwo,:,:)*0.5,'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:));
+
+ end
+ end
+
+
+ end
+ end
+end
+
+
+if length(latency)==1
+ if ismember_bc2(moption, {'areazt','areazp','areazn', 'nintegz'})%% Four options for Numerical integration/Area between two (automatically detected)zero-crossing latencies
+ xline(r_ax,latency, 'Color', cwm,'LineWidth' ,1);
+
+ else
+ xline(r_ax,latency, 'Color', cwm,'LineWidth' ,1);
+ end
+ if ismember_bc2(moption, 'instabl')
+ [new_erp_data, Amp_out,Lat]= f_ERP_plot_wav(observe_ERPDAT.ERP);
+
+ for Numofstione = 1:Num_plot
+ for Numofstitwo = 1:Num_data
+ plot(r_ax,latency,squeeze(Amp_out(Numofstitwo,Numofstione)),'Color',line_colors(Numofstitwo,:,:),'Marker','x');
+ end
+ end
+
+ end
+elseif length(latency)==2
+ Max_values = max(abs(plot_erp_data(:)));
+ plot_area_up = area(r_ax,[latency latency(2) latency(1)],[-2*Max_values-500,Max_values*2 -2*Max_values-500,Max_values*2]);
+ plot_area_low = area(r_ax,[latency latency(2) latency(1)],[0,-Max_values*2 0,-Max_values*2]);
+
+ set(plot_area_up,'FaceAlpha',0.2, 'EdgeAlpha', 0.1, 'EdgeColor', cwm,'FaceColor',cwm_backgb);
+ set(plot_area_low,'FaceAlpha',0.2, 'EdgeAlpha', 0.1, 'EdgeColor', cwm,'FaceColor',cwm_backgb);
+
+ if ismember_bc2(moption, {'peakampbl'})%Local Peak amplitude
+
+ [new_erp_data, Amp_out,Lat]= f_ERP_plot_wav(observe_ERPDAT.ERP);
+ for Numofstione = 1:Num_plot
+ for Numofstitwo = 1:Num_data
+ line(r_ax, [Lat{Numofstitwo,Numofstione} Lat{Numofstitwo,Numofstione}],[offset(Numofstione),squeeze(Amp_out(Numofstitwo,Numofstione))],'Color',line_colors(Numofstitwo,:,:),'LineWidth',3,'LineStyle','--','Marker','x');
+ end
+ end
+
+ elseif ismember_bc2(moption, { 'fareatlat', 'fareaplat','fninteglat','fareanlat'})%fractional area latency
+
+
+ [new_erp_data, Amp_out,Lat]= f_ERP_plot_wav(observe_ERPDAT.ERP);
+ for Numofstione = 1:Num_plot
+ for Numofstitwo = 1:Num_data
+ Amp_all = squeeze(plot_erp_data(:,Numofstitwo,Numofstione));
+ if ~isnan(Amp_out(Numofstitwo,Numofstione))
+ [xxx, latsamp, latdiffms] = closest(timex, Amp_out(Numofstitwo,Numofstione));
+ line(r_ax, [Amp_out(Numofstitwo,Numofstione) Amp_out(Numofstitwo,Numofstione)],[offset(Numofstione),Amp_all(latsamp)],'Color',line_colors(Numofstitwo,:,:),'LineWidth',3,'LineStyle','--','Marker','x');
+ end
+ end
+ end
+
+ elseif ismember_bc2(moption, {'peaklatbl','fpeaklat'}) % fractional peak latency && Local peak latency
+
+ [new_erp_data, Amp_out,Lat]= f_ERP_plot_wav(observe_ERPDAT.ERP);
+ for Numofstione = 1:Num_plot
+ for Numofstitwo = 1:Num_data
+ Amp_all = squeeze(plot_erp_data(:,Numofstitwo,Numofstione));
+ if ~isnan(Amp_out(Numofstitwo,Numofstione))
+ [xxx, latsamp, latdiffms] = closest(timex, Amp_out(Numofstitwo,Numofstione));
+ line(r_ax, [Amp_out(Numofstitwo,Numofstione) Amp_out(Numofstitwo,Numofstione)],[offset(Numofstione),Amp_all(latsamp)],'Color',line_colors(Numofstitwo,:,:),'LineWidth',3,'LineStyle','--','Marker','x');
+ end
+ end
+ end
+
+ end
+end
+
+end
diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_redrawERP_try.m b/studio_functions/Functions/EStudio/ERP Tab/f_redrawERP_try.m
new file mode 100755
index 00000000..87e813f0
--- /dev/null
+++ b/studio_functions/Functions/EStudio/ERP Tab/f_redrawERP_try.m
@@ -0,0 +1,942 @@
+%This function is to plot ERP wave with single or multiple columns on one page.
+
+
+
+% Author: Guanghui Zhang & Steve J. Luck & Andrew Stewart
+% Center for Mind and Brain
+% University of California, Davis,
+% Davis, CA
+% 2022
+
+
+
+function f_redrawERP_try()
+% Draw a demo ERP into the axes provided
+global gui_erp;
+global observe_ERPDAT;
+
+
+S_ws_geterpset= estudioworkingmemory('selectederpstudio');
+if isempty(S_ws_geterpset)
+ S_ws_geterpset = observe_ERPDAT.CURRENTERP;
+
+ if isempty(S_ws_geterpset)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+end
+
+S_ws_getbinchan = estudioworkingmemory('geterpbinchan');
+
+S_ws_geterpplot = estudioworkingmemory('geterpplot');
+
+
+%%Parameter from bin and channel panel
+Elecs_shown = S_ws_getbinchan.elecs_shown{S_ws_getbinchan.Select_index};
+Bins = S_ws_getbinchan.bins{S_ws_getbinchan.Select_index};
+Bin_chans = S_ws_getbinchan.bins_chans(S_ws_getbinchan.Select_index);
+Elec_list = S_ws_getbinchan.elec_list{S_ws_getbinchan.Select_index};
+Matlab_ver = S_ws_getbinchan.matlab_ver;
+
+
+
+%%Parameter from plotting panel
+try
+ Min_vspacing = S_ws_geterpplot.min_vspacing(S_ws_getbinchan.Select_index);
+ Min_time = S_ws_geterpplot.min(S_ws_getbinchan.Select_index);
+ Max_time = S_ws_geterpplot.max(S_ws_getbinchan.Select_index);
+ Yscale = S_ws_geterpplot.yscale(S_ws_getbinchan.Select_index);
+ Timet_low =S_ws_geterpplot.timet_low(S_ws_getbinchan.Select_index);
+ Timet_high =S_ws_geterpplot.timet_high(S_ws_getbinchan.Select_index);
+ Timet_step=S_ws_geterpplot.timet_step(S_ws_getbinchan.Select_index);
+ Fill = S_ws_geterpplot.fill(S_ws_getbinchan.Select_index);
+ Plority_plot = S_ws_geterpplot.Positive_up(S_ws_getbinchan.Select_index);
+ ColumnNum = S_ws_geterpplot.Plot_column;
+catch
+ return;
+end
+
+Column_label = ColumnNum(S_ws_getbinchan.Select_index);
+
+if Bin_chans == 0
+ elec_n = S_ws_getbinchan.elec_n(S_ws_getbinchan.Select_index);
+ max_elec_n = observe_ERPDAT.ALLERP(S_ws_geterpset(S_ws_getbinchan.Select_index)).nchan;
+else
+ elec_n = S_ws_getbinchan.bin_n(S_ws_getbinchan.Select_index);
+ max_elec_n = observe_ERPDAT.ALLERP(S_ws_geterpset(S_ws_getbinchan.Select_index)).nbin;
+end
+
+% We first clear the existing axes ready to build a new one
+if ishandle( gui_erp.ViewAxes )
+ delete( gui_erp.ViewAxes );
+end
+
+
+% Get chan labels
+S_chan.chan_label = cell(1,max_elec_n);
+S_chan.chan_label_place = zeros(1,max_elec_n);
+
+
+if Bin_chans == 0
+ for i = 1:elec_n
+ S_chan.chan_label{i} = observe_ERPDAT.ERP.chanlocs(Elecs_shown(i)).labels;
+ end
+else
+ for i = 1:elec_n
+ S_chan.chan_label{i} = observe_ERPDAT.ERP.bindescr(Bins(i));
+ end
+end
+
+
+%Sets the units of your root object (screen) to pixels
+set(0,'units','pixels')
+%Obtains this pixel information
+Pix_SS = get(0,'screensize');
+%Sets the units of your root object (screen) to inches
+set(0,'units','inches')
+%Obtains this inch information
+Inch_SS = get(0,'screensize');
+%Calculates the resolution (pixels per inch)
+Res = Pix_SS./Inch_SS;
+
+
+pb_height = Min_vspacing*Res(4); %px
+
+
+% Plot data in the main viewer fig
+splot_n = elec_n;
+tsize = 13;
+
+
+clear pb r_ax plotgrid;
+try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;%%Get background color
+catch
+ ColorB_def = [0.95 0.95 0.95];
+end
+if isempty(ColorB_def)
+ ColorB_def = [0.95 0.95 0.95];
+end
+gui_erp.plotgrid = uix.VBox('Parent',gui_erp.ViewContainer,'Padding',0,'Spacing',0,'BackgroundColor',ColorB_def);
+
+pageinfo_box = uiextras.HBox( 'Parent', gui_erp.plotgrid,'BackgroundColor',ColorB_def);
+
+gui_erp.plot_wav_legend = uiextras.HBox( 'Parent', gui_erp.plotgrid,'BackgroundColor',[1 1 1]);
+gui_erp.ViewAxes_legend = uix.ScrollingPanel( 'Parent', gui_erp.plot_wav_legend,'BackgroundColor',ColorB_def);
+
+gui_erp.ViewAxes = uix.ScrollingPanel( 'Parent', gui_erp.plot_wav_legend,'BackgroundColor',[1 1 1]);
+
+
+%%Changed by Guanghui Zhang 2 August 2022-------panel for display the processing procedure for some functions, e.g., filtering
+xaxis_panel = uiextras.HBox( 'Parent', gui_erp.plotgrid,'BackgroundColor',ColorB_def);%%%Message
+gui_erp.Process_messg = uicontrol('Parent',xaxis_panel,'Style','text','String','','FontSize',20,'FontWeight','bold','BackgroundColor',ColorB_def);
+
+
+%%Setting title
+gui_erp.pageinfo_minus = uicontrol('Parent',pageinfo_box,'Style', 'pushbutton', 'String', '<','Callback',@page_minus,'FontSize',30,'BackgroundColor',[1 1 1]);
+if S_ws_getbinchan.Select_index ==1
+ gui_erp.pageinfo_minus.Enable = 'off';
+end
+
+gui_erp.pageinfo_plus = uicontrol('Parent',pageinfo_box,'Style', 'pushbutton', 'String', '>','Callback',@page_plus,'FontSize',30,'BackgroundColor',[1 1 1]);
+if S_ws_getbinchan.Select_index == numel(S_ws_geterpset)
+ gui_erp.pageinfo_plus.Enable = 'off';
+end
+
+pageinfo_str = ['Page',32,num2str(S_ws_getbinchan.Select_index),'/',num2str(numel(S_ws_geterpset)),':',32,observe_ERPDAT.ERP.erpname];
+
+pageinfo_text = uicontrol('Parent',pageinfo_box,'Style','text','String',pageinfo_str,'FontSize',14,'FontWeight','bold');
+
+if length(S_ws_geterpset) ==1
+ Enable_minus = 'off';
+ Enable_plus = 'off';
+ Enable_plus_BackgroundColor = [1 1 1];
+ Enable_minus_BackgroundColor = [0 0 0];
+else
+
+ if S_ws_getbinchan.Select_index ==1
+ Enable_minus = 'off';
+ Enable_plus = 'on';
+
+ Enable_plus_BackgroundColor = [0 1 0];
+ Enable_minus_BackgroundColor = [0 0 0];
+ elseif S_ws_getbinchan.Select_index == length(S_ws_geterpset)
+ Enable_minus = 'on';
+ Enable_plus = 'off';
+ Enable_plus_BackgroundColor = [0 0 0];
+ Enable_minus_BackgroundColor = [0 1 0];
+ else
+ Enable_minus = 'on';
+ Enable_plus = 'on';
+ Enable_plus_BackgroundColor = [0 1 0];
+ Enable_minus_BackgroundColor = [0 1 0];
+ end
+end
+gui_erp.pageinfo_minus.Enable = Enable_minus;
+gui_erp.pageinfo_plus.Enable = Enable_plus;
+gui_erp.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor;
+gui_erp.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor;
+
+set(pageinfo_box, 'Sizes', [50 50 -1] );
+set(pageinfo_box,'BackgroundColor',ColorB_def);
+set(pageinfo_text,'BackgroundColor',ColorB_def);
+%Setting title. END,'BackgroundColor',ColorB_def
+
+%for i=1:splot_n
+
+%
+%%------------Setting the number of data and plotting---------------------
+ndata = 0;
+nplot = 0;
+if Bin_chans == 0 %if channels with bin overlay
+ ndata = Bins;
+ nplot = Elecs_shown;
+else %if bins with channel overlay
+ ndata = Elecs_shown;
+ nplot = Bins;
+end
+
+%
+timeor = observe_ERPDAT.ERP.times; % original time vector
+timex = timeor;
+[xxx, latsamp, latdiffms] = closest(timex, [Min_time Max_time]);
+tmin = latsamp(1);
+tmax = latsamp(2);
+
+if tmin < 1
+ tmin = 1;
+end
+
+if tmax > numel(observe_ERPDAT.ERP.times)
+ tmax = numel(observe_ERPDAT.ERP.times);
+end
+
+plot_erp_data = nan(tmax-tmin+1,numel(ndata));
+for i = 1:splot_n
+ if Bin_chans == 0
+ for i_bin = 1:numel(ndata)
+ plot_erp_data(:,i_bin,i) = observe_ERPDAT.ERP.bindata(Elecs_shown(i),tmin:tmax,Bins(i_bin))'*Plority_plot; %
+ end
+ else
+ for i_bin = 1:numel(ndata)
+ plot_erp_data(:,i_bin,i) = observe_ERPDAT.ERP.bindata(Elecs_shown(i_bin),tmin:tmax,Bins(i))'*Plority_plot; %
+ end
+ end
+end
+
+perc_lim = Yscale;
+percentile = perc_lim*3/2;
+
+[~,~,b] = size(plot_erp_data);
+
+
+%
+%%%------------Setting xticklabels for each row of each wave--------------
+xstep_label = estudioworkingmemory('erp_xtickstep');
+if isempty(xstep_label)
+ xstep_label =0;
+end
+if ~xstep_label
+ [def Timet_step]= default_time_ticks_studio(observe_ERPDAT.ERP, [Min_time,Max_time]);
+ if ~isempty(def{1,1})
+ xticks_clomn = str2num(def{1,1});
+ while xticks_clomn(end)<=Max_time
+ xticks_clomn(numel(xticks_clomn)+1) = xticks_clomn(end)+Timet_step;
+ if xticks_clomn(end)>Max_time
+ xticks_clomn = xticks_clomn(1:end-1);
+ break;
+ end
+ end
+ else
+ xticks_clomn = (Min_time:Timet_step:Max_time);
+ end
+else
+
+
+ xticks_clomn = (Min_time:Timet_step:Max_time);
+end
+Timet_step_p = ceil(Timet_step/(1000/observe_ERPDAT.ERP.srate));%% Time points of the gap between columns
+
+%
+%%----------------------Modify the data into multiple-columns---------------------------------------
+rowNum = ceil(b/Column_label);
+plot_erp_data_new = NaN(size(plot_erp_data,1),size(plot_erp_data,2),rowNum*Column_label);
+
+plot_erp_data_new(:,:,1:size(plot_erp_data,3)) = plot_erp_data;
+plot_erp_data_new_trans = [];
+
+
+if Column_label==1
+ for Numofrow = 1:rowNum
+ plot_erp_data_new_trans(:,:,:,Numofrow) = plot_erp_data_new(:,:,(Numofrow-1)*Column_label+1:Numofrow*Column_label);
+ end
+
+ clear plot_erp_data;
+ plot_erp_data_new_trans = permute(plot_erp_data_new_trans,[1,3,2,4]) ;
+ plot_erp_data = reshape(plot_erp_data_new_trans,size(plot_erp_data_new_trans,1)*size(plot_erp_data_new_trans,2),size(plot_erp_data_new_trans,3),size(plot_erp_data_new_trans,4));
+
+elseif Column_label>1
+
+ plot_erp_data_trans_clumns = NaN(size(plot_erp_data_new,1)*Column_label+(Column_label-1)*Timet_step_p,size(plot_erp_data_new,2),rowNum);
+ for Numofrow = 1:rowNum
+ Data_column = plot_erp_data_new(:,:,(Numofrow-1)*Column_label+1:Numofrow*Column_label);
+ for Numofcolumn = 1:Column_label
+ low_interval = size(plot_erp_data_new,1)*(Numofcolumn-1)+1+(Numofcolumn-1)*Timet_step_p;
+ high_interval = size(plot_erp_data_new,1)*(Numofcolumn-1)+(Numofcolumn-1)*Timet_step_p+size(plot_erp_data_new,1);
+ plot_erp_data_trans_clumns(low_interval:high_interval,:,Numofrow) = squeeze(Data_column(:,:,Numofcolumn));
+ end
+ end
+ plot_erp_data = plot_erp_data_trans_clumns;
+end
+
+ind_plot_height = percentile*2; % Height of each individual subplot
+
+offset = [];
+if Bin_chans == 0
+ offset = (size(plot_erp_data,3)-1:-1:0)*ind_plot_height;
+else
+ offset = (size(plot_erp_data,3)-1:-1:0)*ind_plot_height;
+end
+[~,~,b] = size(plot_erp_data);
+for i = 1:b
+ plot_erp_data(:,:,i) = plot_erp_data(:,:,i) + ones(size(plot_erp_data(:,:,i)))*offset(i);
+end
+
+
+
+r_ax = axes('Parent', gui_erp.ViewAxes,'Color','none','Box','on','FontWeight','bold');
+hold(r_ax,'on');
+set(gui_erp.plot_wav_legend,'Sizes',[80 -10]);
+r_ax_legend = axes('Parent', gui_erp.ViewAxes_legend,'Color','none','Box','off');
+hold(r_ax_legend,'on');
+
+
+try
+ f_bin = 1000/observe_ERPDAT.ERP.srate;
+catch
+ f_bin = 1;
+end
+
+ts = observe_ERPDAT.ERP.times(tmin:tmax);
+ts_colmn = ts;
+
+%
+%%------------------Adjust the data into multiple/single columns------------
+if Column_label>1 % Plotting waveforms with munltiple-columns
+ xticks_org = xticks_clomn;
+
+ for Numofcolumn = 1:Column_label-1
+ xticks_clomn_add = [1:numel(ts)+Timet_step_p].*f_bin+(ts_colmn(end).*ones(1,numel(ts)+Timet_step_p));
+ ts_colmn = [ts_colmn,xticks_clomn_add];
+ end
+
+ X_zero_line(1) =ts(1);
+ for Numofcolumn = 1:Column_label-1
+ if Numofcolumn ==1
+ X_zero_line(Numofcolumn+1) = X_zero_line(Numofcolumn)+ ts(end)-ts(1)+f_bin + (Timet_step_p/2)*f_bin;
+ else
+ X_zero_line(Numofcolumn+1) = X_zero_line(Numofcolumn)+ ts(end)-ts(1)+f_bin + (Timet_step_p)*f_bin;
+ end
+ end
+
+ [xticks,xticks_labels] = f_geterpxticklabel(observe_ERPDAT.ERP,xticks_clomn,Column_label,[Min_time Max_time],Timet_step);
+ ts = ts_colmn;
+ Min_time = ts(1);
+ Max_time = ts(end);
+
+else%% Plotting waveforms with single-column
+ %%%------------getting xticklabels for each row of each wave--------------
+ xticks =xticks_clomn;
+ X_zero_line(1) =ts(1);
+ for Numofxlabel = 1:numel(xticks)
+ xticks_labels{Numofxlabel} = num2str(xticks(Numofxlabel));
+ end
+end
+
+
+splot_n = size(plot_erp_data,3);%%Adjust the columns
+
+set(r_ax,'XLim',[Min_time Max_time]);
+
+[a,c,b] = size(plot_erp_data);
+new_erp_data = zeros(a,b*c);
+for i = 1:b
+ new_erp_data(:,((c*(i-1))+1):(c*i)) = plot_erp_data(:,:,i);
+end
+
+
+line_colors = erpworkingmemory('PWColor');
+if size(line_colors,1)~= numel(ndata)
+ if numel(ndata)> size(line_colors,1)
+ line_colors = get_colors(numel(ndata));
+ else
+ line_colors = line_colors(1:numel(ndata),:,:);
+ end
+end
+
+if isempty(line_colors)
+ line_colors = get_colors(numel(ndata));
+end
+
+line_colors = repmat(line_colors,[splot_n 1]); %repeat the colors once for every plot
+
+
+%
+%%------------Setting xticklabels for each row --------------
+x_axs = ones(size(new_erp_data,1),1);
+for jj = 1:numel(offset)-1
+ plot(r_ax,ts,x_axs.*offset(end),'color',[1 1 1],'LineWidth',1);
+ set(r_ax,'XTick',xticks, ...
+ 'box','off', 'Color','none','xticklabels',xticks_labels,'FontWeight','bold');
+ myX_Crossing = offset(jj);
+ props = get(r_ax);
+
+ tick_bottom = -props.TickLength(1)*diff(props.YLim);
+ if abs(tick_bottom) > abs(Yscale)/5
+ try
+ tick_bottom = - abs(Yscale)/5;
+ catch
+ tick_bottom = tick_bottom;
+ end
+ elseif abs(tick_bottom)1
+ if numel(offset)==jj
+ kkkk = 1;
+ else
+ kkkk = 2;
+ end
+ for iCount = kkkk:nTicks
+ xtick_label = (props.XTickLabel(iCount, :));
+ text(r_ax,props.XTick(iCount), tick_bottom + myX_Crossing, ...
+ xtick_label, ...
+ 'HorizontalAlignment', 'Center', ...
+ 'VerticalAlignment', 'Top', ...
+ 'FontSize', 12, ...
+ 'FontName', props.FontName, ...
+ 'FontAngle', props.FontAngle, ...
+ 'FontUnits', props.FontUnits, ...
+ 'FontWeight', 'bold');
+ end
+ end
+
+end
+
+%
+%%----------------Start:Remove xticks for the columns without waves in the last row-------------------------
+Element_left = numel(nplot) - (ceil(numel(nplot)/Column_label)-1)*Column_label;
+x_axset = plot(r_ax,ts,x_axs.*offset(end),'color', [1 1 1],'LineWidth',1);
+set(r_ax,'XTick',xticks, ...
+ 'box','off', 'Color','none','xticklabels',xticks_labels,'FontWeight','bold');
+myX_Crossing = offset(end);
+props = get(r_ax);
+
+tick_bottom = -props.TickLength(1)*diff(props.YLim);
+if abs(tick_bottom) > abs(Yscale)/5
+ try
+ tick_bottom = - abs(Yscale)/5;
+ catch
+ tick_bottom = tick_bottom;
+ end
+elseif abs(tick_bottom)1
+ for iCount = 1:ceil(nTicks/Column_label*Element_left)
+ xtick_label = (props.XTickLabel(iCount, :));
+ text(r_ax,props.XTick(iCount), tick_bottom + myX_Crossing, ...
+ xtick_label, ...
+ 'HorizontalAlignment', 'Center', ...
+ 'VerticalAlignment', 'Top', ...
+ 'FontSize', 12, ...
+ 'FontName', props.FontName, ...
+ 'FontAngle', props.FontAngle, ...
+ 'FontUnits', props.FontUnits, ...
+ 'FontWeight', 'bold');
+ end
+end
+%%--------------------------End:Remove xticks for the columns without waves in the last row-------------------------
+
+%
+%%-----------------Get zeroline for each row-----------------------------
+row_baseline = NaN(numel(ts),splot_n);
+count = 0;
+for Numofsplot = 0:splot_n-1
+ for Numofcolumn = 1:Column_label
+ count = count +1;
+ if count> numel(nplot)
+
+ break;
+
+ end
+ low_interval = size(plot_erp_data_new,1)*(Numofcolumn-1)+1+(Numofcolumn-1)*Timet_step_p;
+ high_interval = size(plot_erp_data_new,1)*(Numofcolumn-1)+(Numofcolumn-1)*Timet_step_p+size(plot_erp_data_new,1);
+ row_baseline(low_interval:high_interval,Numofsplot+1) = ones(numel(low_interval:high_interval),1).*offset(Numofsplot+1);
+ end
+end
+
+
+%
+%%-------------------------Plotting ERP waves-----------------------------
+pb_here = plot(r_ax,ts, [new_erp_data],'LineWidth',1.5);
+
+set(r_ax, 'XTick', [], 'XTickLabel', []);
+
+%
+%%----------------Marking 0 point (event-locked)--------------------------
+[xxx, latsamp_0, latdiffms_0] = closest(xticks, [0]);
+if numel(offset)>1
+ if latdiffms_0 ==0
+ for Numofcolumn = 1:Column_label
+ xline(r_ax,xticks((Numofcolumn-1)*numel(xticks_clomn)+latsamp_0),'k-.','LineWidth',1);%%'Color',Marking start time point for each column
+ end
+ end
+elseif numel(offset)==1
+
+ for Numofcolumn = 1:numel(nplot)
+ xline(r_ax,xticks((Numofcolumn-1)*numel(xticks_clomn)+latsamp_0),'k-.','LineWidth',1);%%'Color',Marking start time point for each column
+ end
+end
+%
+yticks = -perc_lim:perc_lim:((2*percentile*b)-(2*perc_lim));
+ylabs = repmat([-perc_lim 0 perc_lim],[1,b]);
+oldlim = [-percentile yticks(end)-perc_lim+percentile];
+top_vspace = max( max( new_erp_data))-oldlim(2);
+bot_vspace = min( min( new_erp_data))-oldlim(1);
+if top_vspace < 0
+ top_vspace = 0;
+end
+
+if bot_vspace > 0
+ bot_vspace = 0;
+end
+newlim = oldlim + [bot_vspace top_vspace];
+set(r_ax,'XLim',[Min_time Max_time],'Ylim',newlim);
+
+
+%
+%%--------------Setting color for each wave--------------------------
+% if Column_label>1
+% for i = 0:splot_n-1
+% r_ax.Children(end-i).Color = [1 1 1];
+% end
+% end
+
+% for i = splot_n+1:numel(pb_here)
+% pb_here(i).Color = line_colors((i-splot_n),:);
+% end
+for i = 1:numel(pb_here)
+ pb_here(i).Color = line_colors(i,:);
+end
+%
+% for i = 1:splot_n-1
+% pb_here(i).Color = [0 0 0];
+% pb_here(i).LineWidth=.01;
+% end
+
+
+
+
+%%------------Marking start time point for each column---------------------
+if Column_label>1
+ for ii = 2:numel(X_zero_line)
+ xline(r_ax,X_zero_line(ii), 'y--','LineWidth',2);
+ end
+end
+
+for Numofplot = 1:size(row_baseline,2)
+ plot(r_ax,ts,row_baseline(:,Numofplot),'color',[0 0 0],'LineWidth',1.5);
+end
+ylabs = [fliplr(-perc_lim:-perc_lim:newlim(1)) ylabs(2:end-1) (yticks(end):perc_lim:newlim(2))-yticks(end)+perc_lim];
+yticks = [fliplr(-perc_lim:-perc_lim:newlim(1)) yticks(2:end-1) yticks(end):perc_lim:newlim(2)];
+
+
+
+%
+%%-------------Name of bin/channel for each subplot--------------------------
+if Column_label==1
+ if numel(offset)>1
+ count = 0;
+ for i = 0:numel(offset)-1
+ leg_str = '';
+
+ count = count+1;
+ try
+ if Bin_chans == 0
+ leg_str = sprintf('%s',Elec_list{Elecs_shown(count)});
+ else
+ leg_str = sprintf('%s',observe_ERPDAT.ERP.bindescr{Bins(count)});
+ end
+ catch
+ leg_str = '';
+ end
+ text(r_ax,ts(1),offset(i+1)+offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14);
+ end
+ end
+
+ try
+ if Bin_chans == 0
+ leg_str = sprintf('%s',Elec_list{Elecs_shown(end)});
+ else
+ leg_str = sprintf('%s',observe_ERPDAT.ERP.bindescr{Bins(end)});
+ end
+ catch%%
+ leg_str = '';
+ end
+
+ try
+ text(r_ax,ts(1),offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14);
+ catch
+ text(r_ax,ts(1),Yscale/2,leg_str,'FontWeight','bold','FontSize', 14);
+ end
+else%% Getting y ticks and legends for multiple-columns
+ if numel(offset)>1
+ count = 0;
+ for i = 0:numel(offset)-1
+ leg_str = '';
+ for Numofcolumn = 1: Column_label
+ count = count+1;
+ try
+ if Bin_chans == 0
+ leg_str = sprintf('%s',Elec_list{Elecs_shown(count)});
+ else
+ leg_str = sprintf('%s',observe_ERPDAT.ERP.bindescr{Bins(count)});
+ end
+ catch
+ leg_str = '';
+ end
+ if Numofcolumn ==1
+ text(r_ax,X_zero_line(Numofcolumn),offset(i+1)+offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14);
+ else
+ text(r_ax,X_zero_line(Numofcolumn)+Timet_step/2,offset(i+1)+offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14);
+ end
+ end
+ end
+ end
+
+
+ count = (numel(offset)-1)*Column_label;
+ leg_str = '';
+ for Numofcolumn = 1:Column_label
+ count = count+1;
+ try
+ if Bin_chans == 0
+ leg_str = sprintf('%s',Elec_list{Elecs_shown(count)});
+ else
+ leg_str = sprintf('%s',observe_ERPDAT.ERP.bindescr{Bins(count)});
+ end
+ catch%%
+ leg_str = '';
+ end
+ try
+
+ if Numofcolumn ==1
+ text(r_ax,X_zero_line(Numofcolumn),offset(i+1)+offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14);
+ else
+ text(r_ax,X_zero_line(Numofcolumn)+Timet_step/2,offset(i+1)+offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14);
+ end
+ catch
+
+ if Numofcolumn ==1
+ text(r_ax,X_zero_line(Numofcolumn),Yscale/2,leg_str,'FontWeight','bold','FontSize', 14);
+ else
+ text(r_ax,X_zero_line(Numofcolumn)+Timet_step/2,Yscale/2,leg_str,'FontWeight','bold','FontSize', 14);
+ end
+ % text(r_ax,X_zero_line(Numofcolumn),Yscale/2,leg_str,'FontWeight','bold','FontSize', 14);
+ end
+ end
+
+end
+%
+
+
+%
+%%-------------Setting x/yticks and ticklabels--------------------------------
+Ylabels_new = ylabs.*Plority_plot;
+[~,Y_label] = find(Ylabels_new == -0);
+Ylabels_new(Y_label) = 0;
+% xticks = (Min_time:Timet_step:Max_time);
+% some options currently only work post Matlab R2016a ,'XLim',[Min_time Max_time],'XLim',[Min_time Max_time]
+if Matlab_ver >= 2016
+ set(r_ax,'FontSize',tsize,'FontWeight','bold','XAxisLocation','origin',...
+ 'XGrid','on','YGrid','on','YTick',yticks,'YTickLabel',Ylabels_new, ...
+ 'YLim',newlim,'XTick',xticks, ...
+ 'box','off', 'Color','none','xticklabels',xticks_labels);
+else
+ set(r_ax,'FontSize',tsize,'FontWeight','bold','XAxisLocation','bottom',...
+ 'XGrid','on','YGrid','on','YTick',yticks,'YTickLabel',Ylabels_new, ...
+ 'YLim',newlim, 'XTick',xticks, ...
+ 'box','off', 'Color','none','xticklabels',xticks_labels);
+ hline(0,'k'); % backup xaxis
+end
+if Column_label>1
+ set(r_ax,'XGrid','on','YGrid','on');%,'XDir','reverse'
+end
+set(r_ax, 'XTick', [], 'XTickLabel', [],'FontWeight', 'bold');
+r_ax.YAxis.LineWidth = 1.5;
+
+hold(r_ax,'off');
+%
+
+
+
+%
+%%--------------------------Setting legend---------------------------------
+line_colors_ldg = erpworkingmemory('PWColor');
+if isempty(line_colors_ldg)
+ line_colors_ldg = get_colors(numel(ndata));
+end
+
+if size(line_colors_ldg,1)~= numel(ndata)
+ if numel(ndata)> size(line_colors_ldg,1)
+ line_colors_ldg = get_colors(numel(ndata));
+ else
+ line_colors_ldg = line_colors_ldg(1:numel(ndata),:,:);
+ end
+end
+
+for Numofplot = 1:size(plot_erp_data,2)
+ plot(r_ax_legend,[0 0],'Color',line_colors_ldg(Numofplot,:,:),'LineWidth',3)
+end
+
+if Bin_chans == 0
+
+ Leg_Name = {};
+
+ for Numofbin = 1:numel(Bins)
+ Leg_Name{Numofbin} = strcat('Bin',num2str(Bins(Numofbin)));
+ end
+else
+ for Numofchan = 1:numel(Elecs_shown)
+ Leg_Name{Numofchan} = Elec_list{Numofchan};
+ end
+end
+legend(r_ax_legend,Leg_Name,'FontSize',14,'TextColor','blue');
+legend(r_ax_legend,'boxoff');
+%
+
+%-------fix scaling shrinkage--------------
+pos_fix = r_ax.Position;
+pos_fix(2) = 1; % Start at the bottom
+pos_fix(4) = pb_height - 1; % fill the height;
+
+gui_erp.plotgrid.Heights(1) = 30; % set the first element (pageinfo) to 30px high
+gui_erp.plotgrid.Heights(3) = 30; % set the second element (x axis) to 30px high
+gui_erp.plotgrid.Units = 'pixels';
+if splot_n*pb_height<(gui_erp.plotgrid.Position(4)-gui_erp.plotgrid.Heights(1))&&Fill
+ pb_height = (gui_erp.plotgrid.Position(4)-gui_erp.plotgrid.Heights(1)-gui_erp.plotgrid.Heights(2))/splot_n;
+end
+
+gui_erp.ViewAxes.Heights = splot_n*pb_height;
+gui_erp.plotgrid.Units = 'normalized';
+
+end % redrawDemo
+
+
+function colors = get_colors(ncolors)
+% Each color gets 1 point divided into up to 2 of 3 groups (RGB).
+degree_step = 6/ncolors;
+angles = (0:ncolors-1)*degree_step;
+colors = nan(numel(angles),3);
+for i = 1:numel(angles)
+ if angles(i) < 1
+ colors(i,:) = [1 (angles(i)-floor(angles(i))) 0]*0.75;
+ elseif angles(i) < 2
+ colors(i,:) = [(1-(angles(i)-floor(angles(i)))) 1 0]*0.75;
+ elseif angles(i) < 3
+ colors(i,:) = [0 1 (angles(i)-floor(angles(i)))]*0.75;
+ elseif angles(i) < 4
+ colors(i,:) = [0 (1-(angles(i)-floor(angles(i)))) 1]*0.75;
+ elseif angles(i) < 5
+ colors(i,:) = [(angles(i)-floor(angles(i))) 0 1]*0.75;
+ else
+ colors(i,:) = [1 0 (1-(angles(i)-floor(angles(i))))]*0.75;
+ end
+end
+end
+
+
+
+%------------------Display the waveform for proir ERPset--------------------
+function page_minus(~,~)
+global observe_ERPDAT;
+global gui_erp;
+
+
+S_ws_geterpset= estudioworkingmemory('selectederpstudio');
+if isempty(S_ws_geterpset)
+ S_ws_geterpset = observe_ERPDAT.CURRENTERP;
+
+ if isempty(S_ws_geterpset)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+end
+
+S_ws_getbinchan = estudioworkingmemory('geterpbinchan');
+
+
+S_ws_getbinchan.Select_index = S_ws_getbinchan.Select_index-1;
+Current_erp_Index = S_ws_geterpset(S_ws_getbinchan.Select_index);
+if Current_erp_Index > length(observe_ERPDAT.ALLERP)
+ beep;
+ disp('Waiting for modifing');
+ return;
+end
+
+observe_ERPDAT.CURRENTERP = Current_erp_Index;
+observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_erp_Index);
+
+
+estudioworkingmemory('geterpbinchan',S_ws_getbinchan);
+
+
+observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+
+
+if length(S_ws_geterpset) ==1
+ Enable_minus = 'off';
+ Enable_plus = 'off';
+ Enable_plus_BackgroundColor = [0 0 0];
+ Enable_minus_BackgroundColor = [0 0 0];
+else
+
+ if S_ws_getbinchan.Select_index ==1
+ Enable_minus = 'off';
+ Enable_plus = 'on';
+
+ Enable_plus_BackgroundColor = [0 1 0];
+ Enable_minus_BackgroundColor = [0 0 0];
+ elseif S_ws_getbinchan.Select_index == length(S_ws_geterpset)
+ Enable_minus = 'on';
+ Enable_plus = 'off';
+ Enable_plus_BackgroundColor = [0 0 0];
+ Enable_minus_BackgroundColor = [0 1 0];
+ else
+ Enable_minus = 'on';
+ Enable_plus = 'on';
+ Enable_plus_BackgroundColor = [0 1 0];
+ Enable_minus_BackgroundColor = [0 1 0];
+ end
+end
+gui_erp.pageinfo_minus.Enable = Enable_minus;
+gui_erp.pageinfo_plus.Enable = Enable_plus;
+% f_redrawERP_mt_viewer();
+gui_erp.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor;
+gui_erp.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor;
+end
+
+
+
+
+
+%------------------Display the waveform for next ERPset--------------------
+function page_plus(~,~)
+global observe_ERPDAT;
+global gui_erp;
+
+
+S_ws_geterpset= estudioworkingmemory('selectederpstudio');
+if isempty(S_ws_geterpset)
+ S_ws_geterpset = observe_ERPDAT.CURRENTERP;
+
+ if isempty(S_ws_geterpset)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+end
+
+S_ws_getbinchan = estudioworkingmemory('geterpbinchan');
+
+
+
+
+S_ws_getbinchan.Select_index = S_ws_getbinchan.Select_index+1;
+Current_erp_Index = S_ws_geterpset(S_ws_getbinchan.Select_index);
+if Current_erp_Index > length(observe_ERPDAT.ALLERP)
+ beep;
+ disp('Waiting for modifing');
+ return;
+end
+
+observe_ERPDAT.CURRENTERP = Current_erp_Index;
+observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_erp_Index);
+
+estudioworkingmemory('geterpbinchan',S_ws_getbinchan);
+
+observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+
+
+if length(S_ws_geterpset) ==1
+ Enable_minus = 'off';
+ Enable_plus = 'off';
+ Enable_plus_BackgroundColor = [0 0 0];
+ Enable_minus_BackgroundColor = [0 0 0];
+else
+
+ if S_ws_getbinchan.Select_index ==1
+ Enable_minus = 'off';
+ Enable_plus = 'on';
+ Enable_plus_BackgroundColor = [0 1 0];
+ Enable_minus_BackgroundColor = [1 1 1];
+ elseif S_ws_getbinchan.Select_index == length(S_ws_geterpset)
+ Enable_minus = 'on';
+ Enable_plus = 'off';
+ Enable_plus_BackgroundColor = [0 0 0];
+ Enable_minus_BackgroundColor = [0 1 0];
+
+
+ else
+ Enable_minus = 'on';
+ Enable_plus = 'on';
+ Enable_plus_BackgroundColor = [0 1 0];
+ Enable_minus_BackgroundColor = [0 1 0];
+ end
+end
+gui_erp.pageinfo_minus.Enable = Enable_minus;
+gui_erp.pageinfo_plus.Enable = Enable_plus;
+gui_erp.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor;
+gui_erp.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor;
+end
+
+
diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_spectral_analysis_advance.fig b/studio_functions/Functions/EStudio/ERP Tab/f_spectral_analysis_advance.fig
new file mode 100755
index 00000000..b1502ebb
Binary files /dev/null and b/studio_functions/Functions/EStudio/ERP Tab/f_spectral_analysis_advance.fig differ
diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_spectral_analysis_advance.m b/studio_functions/Functions/EStudio/ERP Tab/f_spectral_analysis_advance.m
new file mode 100755
index 00000000..c11257e0
--- /dev/null
+++ b/studio_functions/Functions/EStudio/ERP Tab/f_spectral_analysis_advance.m
@@ -0,0 +1,814 @@
+%
+% Author: Guanghui Zhang & Steven Luck
+% Center for Mind and Brain
+% University of California, Davis,
+% Davis, CA
+% 2022
+
+%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b
+%
+% Copyright (C) 2022 Guanghui ZHANG & Steven Luck,
+% Center for Mind and Brain, University of California, Davis,
+% ghzhang@ucdavis.edu, sjluck@ucdavis.edu
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see .
+
+function varargout = f_spectral_analysis_advance(varargin)
+
+% Begin initialization code - DO NOT EDIT
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @f_spectral_analysis_advance_OpeningFcn, ...
+ 'gui_OutputFcn', @f_spectral_analysis_advance_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+% End initialization code - DO NOT EDIT
+
+%--------------------------------------------------------------------------
+function f_spectral_analysis_advance_OpeningFcn(hObject, eventdata, handles, varargin)
+
+% Choose default command line output for f_spectral_analysis_advance
+handles.output = [];
+try
+ ERP = varargin{1};
+catch
+ ERP = [];
+ ERP = buildERPstruct([]);
+ ERP.xmin = 0;
+ ERP.xmax = 0;
+ ERP.nbin = 1;
+ ERP.nchan = 1;
+
+end
+handles.ERP = ERP;
+
+try
+ def = varargin{2};
+catch
+ def = {1,[], [], [1 16], 1, 1,1,0};
+end
+
+bin_chan_label = def{1};
+BinArray = def{2};
+ChanArray = def{3};
+freqRange = def{4};
+Auto_freq = def{5};
+RowNum = def{6};
+ColumnNum = def{7};
+
+listb = {''};
+nbin = ERP.nbin; % Total number of bins
+try
+ for b=1:nbin
+ listb{b}= ['BIN' num2str(b) ' = ' ERP.bindescr{b} ];
+ end
+catch
+ listb = {};
+end
+
+
+%%%set(handles.popupmenu_bins,'String', listb)
+handles.listb = listb;
+handles.indxlistb = BinArray;
+
+
+nchan = ERP.nchan; % Total number of channels
+if ~isfield(ERP.chanlocs,'labels')
+ for e=1:nchan
+ ERP.chanlocs(e).labels = ['Ch' num2str(e)];
+ end
+end
+listch = {''};
+for ch =1:nchan
+ listch{ch} = [num2str(ch) ' = ' ERP.chanlocs(ch).labels ];
+end
+handles.listch = listch;
+handles.indxlistch = ChanArray;
+
+for Numofrow = 1:256
+ FramString{Numofrow}= num2str(Numofrow);
+end
+
+set(handles.popupmenu_row_num,'String',FramString);
+set(handles.popupmenu_column_num,'String',FramString);
+
+set(handles.popupmenu_row_num,'Value',nchan);
+
+if bin_chan_label ==1
+ set(handles.radiobutton_all_bin_chan,'Value',1);
+ set(handles.radiobutton_selected_bin_chan,'Value',0);
+ set(handles.radiobutton_Custom_bin_chan,'Value',0);
+ set(handles.pushbutton_browse_bin,'Enable','off');
+ set(handles.pushbutton_browse_chan,'Enable','off');
+ set(handles.edit_bin_custom,'String',num2str(vect2colon([1:ERP.nbin],'Sort', 'on')));
+ set(handles.edit_channel_custom,'String',num2str(vect2colon([1:ERP.nchan],'Sort', 'on')));
+elseif bin_chan_label ==2
+ set(handles.radiobutton_all_bin_chan,'Value',0);
+ set(handles.radiobutton_selected_bin_chan,'Value',1);
+ set(handles.radiobutton_Custom_bin_chan,'Value',0);
+ set(handles.pushbutton_browse_bin,'Enable','off');
+ set(handles.pushbutton_browse_chan,'Enable','off');
+ [chk, msgboxText] = chckbinandchan(ERP, BinArray, ChanArray);
+ if chk(1)
+ BinString = [1:ERP.nbin];
+ else
+ BinString = BinArray;
+ end
+ if chk(2)
+ ChanString = [1:ERP.nchan];
+ else
+ ChanString = ChanArray;
+ end
+
+ set(handles.edit_bin_custom,'String',num2str(vect2colon(BinString,'Sort', 'on')));
+ set(handles.edit_channel_custom,'String',num2str(vect2colon(ChanString,'Sort', 'on')));
+
+elseif bin_chan_label ==3
+ set(handles.radiobutton_all_bin_chan,'Value',0);
+ set(handles.radiobutton_selected_bin_chan,'Value',0);
+ set(handles.radiobutton_Custom_bin_chan,'Value',1);
+ set(handles.pushbutton_browse_bin,'Enable','on');
+ set(handles.pushbutton_browse_chan,'Enable','on');
+else
+ set(handles.radiobutton_all_bin_chan,'Value',1);
+ set(handles.radiobutton_selected_bin_chan,'Value',0);
+ set(handles.radiobutton_Custom_bin_chan,'Value',0);
+ set(handles.pushbutton_browse_bin,'Enable','off');
+ set(handles.pushbutton_browse_chan,'Enable','off');
+ set(handles.edit_bin_custom,'String',num2str(vect2colon([1:ERP.nbin],'Sort', 'on')));
+ set(handles.edit_channel_custom,'String',num2str(vect2colon([1:ERP.nchan],'Sort', 'on')));
+end
+set(handles.checkbox_freq_ticks_auto,'Value',1);
+set(handles.edit_freq_tick_auto,'Enable','off');
+
+set(handles.edit_freq_range,'String',num2str(freqRange));
+
+
+
+erplab_studio_default_values;
+version = erplabstudiover;
+set(handles.gui_chassis,'Name', ['EStudio',version,' - Plot and save spectrum for the selected ERP GUI '])
+handles = painterplabstudio(handles);
+handles = setfonterplabestudio(handles);
+
+% helpbutton
+
+%
+% Color GUI
+%
+% handles = painterplab(handles);
+
+%
+% Set font size
+%
+% handles = setfonterplab(handles);
+
+% Update handles structure
+guidata(hObject, handles);
+
+% help
+% helpbutton
+
+% UIWAIT makes f_spectral_analysis_advance wait for user response (see UIRESUME)
+uiwait(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+function varargout = f_spectral_analysis_advance_OutputFcn(hObject, eventdata, handles)
+
+% Get default command line output from handles structure
+varargout{1} = handles.output;
+
+% The figure can be deleted now
+delete(handles.gui_chassis);
+
+% --- Executes on button press in radiobutton_all_bin_chan.
+function radiobutton_all_bin_chan_Callback(hObject, eventdata, handles)
+set(handles.radiobutton_Custom_bin_chan,'Value',0);
+set(handles.radiobutton_selected_bin_chan,'Value',0);
+set(handles.radiobutton_all_bin_chan,'Value',1);
+set(handles.pushbutton_browse_bin,'Enable','off');
+set(handles.pushbutton_browse_chan,'Enable','off');
+BinString = handles.ERP.nbin;
+ChanString = handles.ERP.nchan;
+
+set(handles.edit_bin_custom,'String',num2str(vect2colon(1:BinString,'Sort', 'on')));
+set(handles.edit_channel_custom,'String',num2str(vect2colon(1:ChanString,'Sort', 'on')));
+
+% --- Executes on button press in radiobutton_selected_bin_chan.
+function radiobutton_selected_bin_chan_Callback(hObject, eventdata, handles)
+set(handles.radiobutton_Custom_bin_chan,'Value',0);
+set(handles.radiobutton_selected_bin_chan,'Value',1);
+set(handles.radiobutton_all_bin_chan,'Value',0);
+set(handles.pushbutton_browse_bin,'Enable','off');
+set(handles.pushbutton_browse_chan,'Enable','off');
+
+ERP = handles.ERP;
+
+BinString = handles.indxlistb;
+ChanString = handles.indxlistch;
+if isempty(BinString)
+ BinString =[1:ERP.nbin];
+end
+if isempty(ChanString)
+ ChanString =[1:ERP.nchan];
+end
+[chk, msgboxText] = chckbinandchan(ERP, BinString, ChanString);
+if chk(1)
+ BinString = 1:ERP.nbin;
+end
+if chk(2)
+ ChanString = 1:ERP.nchan;
+end
+set(handles.edit_bin_custom,'String',num2str(vect2colon(BinString,'Sort', 'on')));
+set(handles.edit_channel_custom,'String',num2str(vect2colon(ChanString,'Sort', 'on')));
+
+
+% --- Executes on button press in radiobutton_Custom_bin_chan.
+function radiobutton_Custom_bin_chan_Callback(hObject, eventdata, handles)
+set(handles.radiobutton_Custom_bin_chan,'Value',1);
+set(handles.radiobutton_selected_bin_chan,'Value',0);
+set(handles.radiobutton_all_bin_chan,'Value',0);
+set(handles.pushbutton_browse_bin,'Enable','on');
+set(handles.pushbutton_browse_chan,'Enable','on');
+
+
+function edit_bin_custom_Callback(hObject, eventdata, handles)
+BinString = str2num(handles.edit_bin_custom.String);
+ERP = handles.ERP;
+% [chk, msgboxText] = chckbinandchan(ERP, BinString, []);
+[chk, msgboxText] = f_ERP_chckbinandchan(ERP, BinString, [],1);
+
+if chk(1)
+ title = 'EStudio: Spectral analysis GUI input';
+ errorfound(msgboxText, title);
+ return;
+end
+
+
+
+% --- Executes during object creation, after setting all properties.
+function edit_bin_custom_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+
+function edit_channel_custom_Callback(hObject, eventdata, handles)
+ChanString = str2num(handles.edit_channel_custom.String);
+ERP = handles.ERP;
+[chk, msgboxText] = chckbinandchan(ERP, [], ChanString);
+
+
+if chk(2)
+ title = 'EStudio: Spectral analysis GUI input';
+ errorfound(msgboxText, title);
+ return;
+end
+
+chanArray = ChanString;
+ColumnNum = get(handles.popupmenu_column_num, 'Value');
+RowNum = ceil((numel(chanArray))/ColumnNum);
+ColumnNum = ceil((numel(chanArray))/RowNum);
+if RowNum<=0
+ RowNum=1;
+end
+set(handles.popupmenu_row_num, 'Value', RowNum);
+set(handles.popupmenu_column_num, 'Value', ColumnNum);
+
+% --- Executes during object creation, after setting all properties.
+function edit_channel_custom_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function pushbutton_browse_bin_Callback(hObject, eventdata, handles)
+listb = handles.listb;
+indxlistb = handles.indxlistb;
+indxlistb = indxlistb(indxlistb<=length(listb));
+titlename = 'Select Bin(s)';
+
+if get(hObject, 'Value')
+ %set(handles.pushbutton_browsechan, 'Enable', 'off')
+ if ~isempty(listb)
+ bin = browsechanbinGUI(listb, indxlistb, titlename);
+ if ~isempty(bin)
+ set(handles.edit_bin_custom, 'String', vect2colon(bin, 'Delimiter', 'off'));
+ handles.indxlistb = bin;
+ % Update handles structure
+ guidata(hObject, handles);
+ else
+ disp('User selected Cancel')
+ return
+ end
+ else
+ msgboxText = 'No bin information was found';
+ title = 'EStudio: Spectral analysis GUI input';
+ errorfound(msgboxText, title);
+ return
+ end
+
+end
+
+
+
+% --- Executes on button press in pushbutton_browse_chan.
+function pushbutton_browse_chan_Callback(hObject, eventdata, handles)
+listch = handles.listch;
+indxlistch = handles.indxlistch;
+indxlistch = indxlistch(indxlistch<=length(listch));
+titlename = 'Select Channel(s)';
+
+if get(hObject, 'Value')
+ if ~isempty(listch)
+ ch = browsechanbinGUI(listch, indxlistch, titlename);
+ if ~isempty(ch)
+ set(handles.edit_channel_custom, 'String', vect2colon(ch, 'Delimiter', 'off'));
+ handles.indxlistch = ch;
+
+ chanArray = ch;
+ ColumnNum = get(handles.popupmenu_column_num, 'Value');
+ RowNum = ceil((numel(chanArray))/ColumnNum);
+ if RowNum<=0
+ RowNum=1;
+ end
+ set(handles.popupmenu_row_num, 'Value', RowNum);
+
+ % Update handles structure
+ guidata(hObject, handles);
+ else
+ disp('User selected Cancel')
+ return
+ end
+ else
+ msgboxText = 'No channel information was found';
+ title = 'EStudio: Spectral analysis GUI input';
+ errorfound(msgboxText, title);
+ return
+ end
+end
+
+%Freq. range [min max] in Hz
+function edit_freq_range_Callback(hObject, eventdata, handles)
+freqx = str2num(get(handles.edit_freq_range, 'String'));
+if isempty(freqx)
+ msgboxText = 'Invalid input for frequency range of interest';
+ title = 'EStudio: f_spectral_analysis_advance().';
+ errorfound(msgboxText, title);
+ return
+end
+if length(freqx)~=2
+ msgboxText = 'Please, enter two values';
+ title = 'EStudio: f_spectral_analysis_advance().';
+ errorfound(msgboxText, title);
+ return
+end
+
+
+if freqx(1)>= freqx(2)
+ msgboxText = 'The first value must be smaller than the second one!';
+ title = 'EStudio: f_spectral_analysis_advance().';
+ errorfound(msgboxText, title);
+ return
+end
+ERP = handles.ERP;
+try
+ freq_half = ERP.srate/2;
+catch
+ freq_half =freqx(2);
+end
+
+if freqx(2)> freq_half
+ msgboxText = ['Second value must be smaller than',32,num2str(ERP.srate/2)];
+ title = 'ERPLAB Studio: f_ERP_spectral_advance_GUI() error';
+ errorfound(msgboxText, title);
+ return
+end
+
+Auto_tick = get(handles.checkbox_freq_ticks_auto,'Value');
+
+if ~Auto_tick
+ def_ticks = default_time_ticks(handles.ERP, freqx);
+ set(handles.edit_freq_tick_auto,'String',num2str(def_ticks{1}));
+end
+
+
+% --- Executes during object creation, after setting all properties.
+function edit_freq_range_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+
+% --- Executes on button press in checkbox_freq_ticks_auto.
+function checkbox_freq_ticks_auto_Callback(hObject, eventdata, handles)
+if get(hObject, 'Value')
+ set(handles.edit_freq_tick_auto,'Enable','off');
+ set(handles.edit_freq_tick_auto,'String','');
+else
+ set(handles.edit_freq_tick_auto,'Enable','on');
+
+ freqx = str2num(get(handles.edit_freq_range, 'String')); % XL
+ if isempty(freqx)
+ msgboxText = 'Invalid input for frequency range of interest on "Freq. range [min max] in Hz"';
+ title = 'EStudio: f_spectral_analysis_advance().';
+ errorfound(msgboxText, title);
+ return
+ end
+ if length(freqx)~=2
+ msgboxText = 'Please, enter two values on "Freq. range [min max] in Hz"';
+ title = 'EStudio: f_spectral_analysis_advance().';
+ errorfound(msgboxText, title);
+ return
+ end
+
+
+ if freqx(1)>= freqx(2)
+ msgboxText = 'The first value must be smaller than the second one on "Freq. range [min max] in Hz"';
+ title = 'EStudio: f_spectral_analysis_advance().';
+ errorfound(msgboxText, title);
+ return
+ end
+ if freqx(1)<0
+ msgboxText = 'The first value must be larger than 0Hz on "Freq. range [min max] in Hz"';
+ title = 'EStudio: f_spectral_analysis_advance().';
+ errorfound(msgboxText, title);
+ return
+ end
+
+ ERP = handles.ERP;
+ if freqx(2)> ERP.srate/2
+ msgboxText = ['Second value must be smaller than',32,num2str(observe_ERPDAT.ERP.srate/2),'Hz',32,'on "Freq. range [min max] in Hz"'];
+ title = 'ERPLAB Studio: f_ERP_spectral_advance_GUI() error';
+ errorfound(msgboxText, title);
+ return
+ end
+
+
+ def_ticks = default_time_ticks(handles.ERP, freqx);
+ if ~isempty(def_ticks)
+ set(handles.edit_freq_tick_auto,'String',num2str(def_ticks{1}));
+ end
+end
+
+
+
+
+
+function edit_freq_tick_auto_Callback(hObject, eventdata, handles)
+answer = get(handles.edit_freq_tick_auto,'String');
+nanswer = str2num(strtrim(char(answer)));
+if isempty(nanswer)
+ msgboxText = 'Invalid range of values on freq. ticks!\n';
+ title = 'ERPLAB Studio: f_ERP_spectral_advance_GUI() error';
+ errorfound(sprintf(msgboxText), title);
+ return
+end
+
+
+
+
+
+
+% --- Executes during object creation, after setting all properties.
+function edit_freq_tick_auto_CreateFcn(hObject, eventdata, handles)
+% hObject handle to edit_freq_tick_auto (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+% Hint: edit controls usually have a white background on Windows.
+% See ISPC and COMPUTER.
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+% --- Executes on selection change in popupmenu_row_num.
+function popupmenu_row_num_Callback(hObject, eventdata, handles)
+chanArraystr = get(handles.edit_channel_custom, 'String');
+chanArray = str2num(chanArraystr);
+if isempty(chanArray)
+ chanArray = [1:handles.ERP.nchan];
+end
+RowNum= get(handles.popupmenu_row_num, 'Value');
+ColumnNum = ceil((numel(chanArray))/RowNum);
+if ColumnNum<=0
+ ColumnNum=1;
+end
+set(handles.popupmenu_column_num, 'Value', ColumnNum);
+
+
+% --- Executes during object creation, after setting all properties.
+function popupmenu_row_num_CreateFcn(hObject, eventdata, handles)
+% hObject handle to popupmenu_row_num (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+% Hint: popupmenu controls usually have a white background on Windows.
+% See ISPC and COMPUTER.
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+% --- Executes on selection change in popupmenu_column_num.
+function popupmenu_column_num_Callback(hObject, eventdata, handles)
+
+chanArraystr = get(handles.edit_channel_custom, 'String');
+chanArray = str2num(chanArraystr);
+
+if isempty(chanArray)
+ chanArray = [1:handles.ERP.nchan];
+end
+ColumnNum = get(handles.popupmenu_column_num, 'Value');
+RowNum = ceil((numel(chanArray))/ColumnNum);
+if RowNum<=0
+ RowNum=1;
+end
+set(handles.popupmenu_row_num, 'Value', RowNum);
+
+
+% --- Executes during object creation, after setting all properties.
+function popupmenu_column_num_CreateFcn(hObject, eventdata, handles)
+% hObject handle to popupmenu_column_num (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+% Hint: popupmenu controls usually have a white background on Windows.
+% See ISPC and COMPUTER.
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+
+
+
+%--------------------------------------------------------------------------
+function pushbutton_cancel_Callback(hObject, eventdata, handles)
+
+handles.output = [];
+disp('User selected Cancel');
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+% %--------------------------------------------------------------------------
+% function pushbutton_help_Callback(hObject, eventdata, handles)
+% % doc pop_export2text
+% web 'https://github.com/lucklab/erplab/wiki/Exporting,-Editing,-and-Importing-EVENTLISTS' -browser
+%--------------------------------------------------------------------------
+function pushbutton_apply_Callback(hObject, eventdata, handles)
+
+BinArray = str2num(handles.edit_bin_custom.String);
+ChanArray = str2num(handles.edit_channel_custom.String);
+ERP = handles.ERP;
+[chk, msgboxText] = chckbinandchan(ERP, BinArray, ChanArray);
+if chk(1)
+ title = 'ERPLAB Studio: f_ERP_spectral_advance_GUI() error';
+ errorfound(sprintf(msgboxText), title);
+ return;
+end
+if chk(2)
+ title = 'ERPLAB Studio: f_ERP_spectral_advance_GUI() error';
+ errorfound(sprintf(msgboxText), title);
+ return;
+end
+
+
+
+freqRange = str2num(get(handles.edit_freq_range, 'String')); % XL
+if isempty(freqRange)
+ msgboxText = 'Invalid input for frequency range of interest on "Freq. range [min max] in Hz"';
+ title = 'EStudio: f_spectral_analysis_advance().';
+ errorfound(msgboxText, title);
+ return
+end
+if length(freqRange)~=2
+ msgboxText = 'Please, enter two values on "Freq. range [min max] in Hz"';
+ title = 'EStudio: f_spectral_analysis_advance().';
+ errorfound(msgboxText, title);
+ return
+end
+
+
+if freqRange(1)>= freqRange(2)
+ msgboxText = 'The first value must be smaller than the second one on "Freq. range [min max] in Hz"';
+ title = 'EStudio: f_spectral_analysis_advance().';
+ errorfound(msgboxText, title);
+ return
+end
+if freqRange(1)<0
+ msgboxText = 'The first value must be larger than 0Hz on "Freq. range [min max] in Hz"';
+ title = 'EStudio: f_spectral_analysis_advance().';
+ errorfound(msgboxText, title);
+ return
+end
+
+
+if freqRange(2)> ERP.srate/2
+ msgboxText = ['Second value must be smaller than',32,num2str(observe_ERPDAT.ERP.srate/2),'Hz',32,'on "Freq. range [min max] in Hz"'];
+ title = 'ERPLAB Studio: f_ERP_spectral_advance_GUI() error';
+ errorfound(msgboxText, title);
+ return
+end
+
+
+
+
+if handles.checkbox_freq_ticks_auto.Value
+ Auto_freq = [];
+else
+ Auto_freq_String = handles.edit_freq_tick_auto.String;
+ Auto_freq = str2num(Auto_freq_String);
+end
+
+RowNum = handles.popupmenu_row_num.Value;
+ColumnNum = handles.popupmenu_column_num.Value;
+
+if handles.radiobutton_all_bin_chan.Value
+ bin_chan_label = 1;
+elseif handles.radiobutton_selected_bin_chan.Value
+ bin_chan_label = 2;
+elseif handles.radiobutton_Custom_bin_chan.Value
+ bin_chan_label = 3;
+end
+
+
+Save_label = handles.pushbutton_save.Value;
+
+answer = {bin_chan_label,BinArray, ChanArray,freqRange,Auto_freq,RowNum,ColumnNum,Save_label};
+handles.output = answer;
+
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+
+% --- Executes on button press in pushbutton_save.
+function pushbutton_save_Callback(hObject, eventdata, handles)
+BinArray = str2num(handles.edit_bin_custom.String);
+ChanArray = str2num(handles.edit_channel_custom.String);
+ERP = handles.ERP;
+[chk, msgboxText] = chckbinandchan(ERP, BinArray, ChanArray);
+if chk(1)
+ title = 'ERPLAB Studio: f_ERP_spectral_advance_GUI() error';
+ errorfound(sprintf(msgboxText), title);
+ return;
+end
+if chk(2)
+ title = 'ERPLAB Studio: f_ERP_spectral_advance_GUI() error';
+ errorfound(sprintf(msgboxText), title);
+ return;
+end
+
+freqRange = str2num(get(handles.edit_freq_range, 'String')); % XL
+if isempty(freqRange)
+ msgboxText = 'Invalid input for frequency range of interest on "Freq. range [min max] in Hz"';
+ title = 'EStudio: f_spectral_analysis_advance().';
+ errorfound(msgboxText, title);
+ return
+end
+if length(freqRange)~=2
+ msgboxText = 'Please, enter two values on "Freq. range [min max] in Hz"';
+ title = 'EStudio: f_spectral_analysis_advance().';
+ errorfound(msgboxText, title);
+ return
+end
+
+
+if freqRange(1)>= freqRange(2)
+ msgboxText = 'The first value must be smaller than the second one on "Freq. range [min max] in Hz"';
+ title = 'EStudio: f_spectral_analysis_advance().';
+ errorfound(msgboxText, title);
+ return
+end
+if freqRange(1)<0
+ msgboxText = 'The first value must be larger than 0Hz on "Freq. range [min max] in Hz"';
+ title = 'EStudio: f_spectral_analysis_advance().';
+ errorfound(msgboxText, title);
+ return
+end
+
+
+if freqRange(2)> ERP.srate/2
+ msgboxText = ['Second value must be smaller than',32,num2str(observe_ERPDAT.ERP.srate/2),'Hz',32,'on "Freq. range [min max] in Hz"'];
+ title = 'ERPLAB Studio: f_ERP_spectral_advance_GUI() error';
+ errorfound(msgboxText, title);
+ return
+end
+
+
+
+
+if handles.checkbox_freq_ticks_auto.Value
+ Auto_freq = [];
+else
+ Auto_freq_String = handles.edit_freq_tick_auto.String;
+ Auto_freq = str2num(Auto_freq_String);
+end
+
+RowNum = handles.popupmenu_row_num.Value;
+ColumnNum = handles.popupmenu_column_num.Value;
+
+if handles.radiobutton_all_bin_chan.Value
+ bin_chan_label = 1;
+elseif handles.radiobutton_selected_bin_chan.Value
+ bin_chan_label = 2;
+elseif handles.radiobutton_Custom_bin_chan.Value
+ bin_chan_label = 3;
+end
+
+
+Save_label = handles.pushbutton_save.Value;
+
+answer = {bin_chan_label,BinArray, ChanArray,freqRange,Auto_freq,RowNum,ColumnNum,Save_label};
+handles.output = answer;
+
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+
+
+%--------------------------------------------------------------------------
+function gui_chassis_CloseRequestFcn(hObject, eventdata, handles)
+if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting')
+ handles.output = [];
+ %Update handles structure
+ guidata(hObject, handles);
+ uiresume(handles.gui_chassis);
+else
+ % The GUI is no longer waiting, just close it
+ delete(handles.gui_chassis);
+end
+
+
+
+
+
+function [chk, msgboxText] = chckbinandchan(ERP, binArray, chanArray)
+chk=[0 0];
+msgboxText = '';
+if isempty(binArray)
+ msgboxText = 'You have not specified any bin';
+ chk(1) = 1;
+ % return
+end
+if any(binArray<=0)
+ msgboxText = sprintf('Invalid bin index.\nPlease specify only positive integer values.');
+ chk(1) = 1;
+ return
+end
+if any(binArray>ERP.nbin)
+ msgboxText = sprintf('Bin index out of range!\nYou only have %g bins in this ERPset',ERP.nbin);
+ chk(1) = 1;
+ return
+end
+if length(binArray)~=length(unique_bc2(binArray))
+ msgboxText = 'You have specified repeated bins for plotting.';
+ chk(1) = 1;
+ return
+end
+if isempty(chanArray)
+ msgboxText = 'You have not specified any channel';
+ chk(2) = 1;
+ return
+end
+if any(chanArray<=0)
+ msgboxText = sprintf('Invalid channel index.\nPlease specify only positive integer values.');
+ chk(2) = 1;
+ return
+end
+if any(chanArray>ERP.nchan)
+ msgboxText = sprintf('Channel index out of range!\nYou only have %g channels in this ERPset', ERP.nchan);
+ chk(2) = 1;
+ return
+end
+if length(chanArray)~=length(unique_bc2(chanArray))
+ msgboxText = 'You have specified repeated channels for plotting.';
+ chk(2) = 1;
+ return
+end
diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_testsyntaxtype.m b/studio_functions/Functions/EStudio/ERP Tab/f_testsyntaxtype.m
new file mode 100755
index 00000000..23c45a08
--- /dev/null
+++ b/studio_functions/Functions/EStudio/ERP Tab/f_testsyntaxtype.m
@@ -0,0 +1,94 @@
+%--------------------------------------------------------------------------
+function [val, formulaArray]= f_testsyntaxtype(FormulaArrayIn, whocall)
+val = 1;
+formulaArray = FormulaArrayIn;
+
+if isempty(formulaArray)
+ return
+else
+ formulaArray = strtrim(cellstr(formulaArray));
+end
+nformulas = length(formulaArray);
+[expspliter parts] = regexp(formulaArray, '=','match','split');
+ask4fix = 1;
+wantfix = 0;
+newnumbin = 1;
+
+for t=1:nformulas
+ fcomm = formulaArray{t};
+ tokcommentb = regexpi(fcomm, '^#', 'match'); % comment symbol (June 3, 2013)
+
+ if isempty(tokcommentb) % skip comment symbol
+ pleft = regexpi(parts{t}{1}, '(\s*nb[in]*\d+)', 'tokens');
+ plcom = regexpi(parts{t}{1}, '(\s*b[in]*\d+)', 'tokens');
+
+ if isempty(pleft) && ~isempty(plcom) && strcmpi(whocall,'norecu')
+ if ask4fix
+ BackERPLABcolor = [1 0.9 0.3]; % yellow
+ question = ['For non recursive mode, left side of equation\nmust be define as a new bin.\n'...
+ 'For instance, nbin1 = ...\n\n'...
+ 'Do you want that EStudio corrects the syntax for you?'];
+ title = 'WARNING: Syntax is not proper for non recursive mode';
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor)
+ button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes');
+ set(0,'DefaultUicontrolBackgroundColor',oldcolor)
+
+ if strcmpi(button,'Yes')
+ ask4fix = 0;
+ wantfix = 1;
+ elseif strcmpi(button,'Cancel')
+ val = 0; % cancel
+ break
+ else
+ ask4fix = 0;
+ wantfix = 0;
+ end
+ %else
+ % wantfix =1;
+ end
+ elseif ~isempty(pleft) && strcmpi(whocall,'recu')
+ if ask4fix
+ BackERPLABcolor = [1 0.9 0.3]; % yellow
+ question = ['For recursive mode, left side of equation cannot\nbe define as a new bin.\n'...
+ 'For instance, you must write bin1 = ...\n\n'...
+ 'Do you want that EStudio corrects the syntax for you?'];
+ title = 'WARNING: Syntax is not proper for recursive mode';
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor)
+ button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes');
+ set(0,'DefaultUicontrolBackgroundColor',oldcolor)
+
+ if strcmpi(button,'Yes')
+ ask4fix = 0;
+ wantfix =1;
+ elseif strcmpi(button,'Cancel')
+ val = 0; % cancel
+ break
+ else
+ ask4fix = 0;
+ wantfix = 0;
+ end
+ %else
+ % wantfix =1;
+ end
+ %else
+ % wantfix = 0;
+
+ end
+ if wantfix && (~isempty(pleft) || ~isempty(plcom))% fixed (June 3, 2013): JLC
+ fprintf('WARNING: equation %s ', formulaArray{t})
+ if strcmpi(whocall,'recu') % for recursive mode delete the n in nch
+ formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*','','ignorecase')), strtrim(parts{t}{2}));
+ else
+ formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*b(\D*)(\d*)',['nb$1' num2str(newnumbin)],'ignorecase')), strtrim(parts{t}{2}));
+ newnumbin = newnumbin+1;
+ end
+ fprintf('was changed to equation %s \n', formulaArray{t})
+ end
+ end
+end
+% if val==1
+% set(handles.editor,'String', char(formulaArray));
+% end
+
diff --git a/studio_functions/Functions/EStudio/ERP Tab/geterplabstudiodef.m b/studio_functions/Functions/EStudio/ERP Tab/geterplabstudiodef.m
new file mode 100755
index 00000000..670920f5
--- /dev/null
+++ b/studio_functions/Functions/EStudio/ERP Tab/geterplabstudiodef.m
@@ -0,0 +1,21 @@
+% PURPOSE: gets current ERPLAB's version
+%
+% FORMAT:
+%
+% version = geterplabversion;
+%
+% or
+%
+%
+% [version reldate] = geterplabversion; % reldate=release date
+
+
+function [version reldate,ColorB_def,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef
+
+erplab_studio_default_values;
+version = erplabstudiover;
+reldate = erplabstudiorel;
+ColorB_def =ColorB;
+ColorF_def=ColorF;
+errorColorF_def = errorColorF;
+ColorBviewer_def = ColorBviewer;
\ No newline at end of file
diff --git a/studio_functions/Functions/EStudio/ERP Tab/mini_viewer.m b/studio_functions/Functions/EStudio/ERP Tab/mini_viewer.m
new file mode 100755
index 00000000..f94ce9db
--- /dev/null
+++ b/studio_functions/Functions/EStudio/ERP Tab/mini_viewer.m
@@ -0,0 +1,434 @@
+%
+% We need a very fancy data structure system. We've got an array of our
+% 'pages'. Each page is a structure. Each page has a property 'data'. In order to graph effectively it's 2
+% dimensional. It's a series of X by Y matrices compounded horizontally.
+% Each column represents one line of data. Each 'chunk' (Length Y)
+% represents one of three things: A bin, a channel, or an ERPset. If we
+% were to look at one bin as a chunk, each column could either represent a
+% channel or an ERPset.
+%
+% We can change to this system fairly easily. Replace 'nchan' with
+% 'nlines', 'nbin' with 'nplots', etc. Then create a func to turn ERP
+% structure into local data structure based on the 3 way intersection of
+% channels, bins, and ERPsets.
+%
+
+% [ 1 2 3 1 2 3
+% 1 2 3 1 2 3
+% 1 2 3 1 2 3 ]
+
+function varargout = mini_viewer(varargin)
+ parent = uiextras.Empty();
+ boxpan = uiextras.Empty();
+ inpd = [];
+ data = [];
+ olddata = [];
+ child_vs = {};
+ floating = 0<1;
+ havedat = 0<1;
+
+ % Lines, Plots, Pages
+ % 1 = Chans, 2 = Bins, 3 = ERPsets
+ ord = [2 1 3];
+
+ if nargin == 0
+ havedat = 0>1;
+ elseif nargin == 1
+ fig = figure( 'Name', 'ERP Explorer', ...
+ 'NumberTitle', 'off', ...
+ 'MenuBar', 'none', ...
+ 'Toolbar', 'none', ...
+ 'HandleVisibility', 'off');
+ parent = fig;
+ data = cell2mat(varargin(1));
+ else
+ data = cell2mat(varargin(1));
+ parent = [varargin{2}];
+ floating = 1<0;
+ end
+ erp_tabs = uiextras.TabPanel('Parent', parent, 'Padding', 5);
+
+ olddata = data;
+
+ data = erp2loc(data);
+
+ data = data{:};
+
+ drawUI()
+ ret_v = struct('tabs', erp_tabs, 'data', olddata);
+ varargout{1} = ret_v;
+
+ function drawUI()
+
+ havedat = numel(data)>0;
+
+ delete(erp_tabs.Children);
+ if havedat
+ tabnames = cell(size(data));
+ tabs = zeros(size(data));
+ [~,a] = size(data);
+ for i = 1:a
+ tabs(i) = uix.HBoxFlex( 'Parent', erp_tabs, 'Spacing', 10 );
+ dat = data(i);
+ tabnames(i) = {dat.name};
+ end
+
+ erp_tabs.TabNames = tabnames;
+ erp_tabs.SelectedChild = 1;
+ erp_tabs.TabSize = 120;
+ for tabn = 1:numel(tabs)
+ TAB = tabs(tabn);
+ cdat = data(tabn);
+ hbox = uiextras.HBox('Parent', TAB);
+ boxpan = uiextras.BoxPanel('Parent', hbox);
+ [d1,d2,d3] = size(cdat.data);
+ plot_erp_data = cdat.data;
+% for i = 1:cdat.nlin
+% ndata = 1:cdat.nplot;
+% for i_bin = 1:numel(ndata)
+% el_shown = 1:cdat.nlin;
+%
+% plot_erp_data(:,(i_bin+((i-1)*numel(ndata)))) = cdat.data(el_shown(i),1:d2,d3)'; % + (i+1)*S.display_offset;
+% end
+% end
+ offset = (repmat(kron(1:cdat.nplot,ones(1,cdat.nlin)),[500 1])-1)*30;
+ plot_erp_data = plot_erp_data + offset;
+ drawERP(plot_erp_data,boxpan,cdat)
+ vpanels = uiextras.VBox('Parent', hbox);
+ dat_sel = uiextras.BoxPanel('Parent', vpanels,'Title','Data Selector');
+ pl_ops = uiextras.BoxPanel('Parent', vpanels,'Title','Plotting Options');
+
+ % Data Selector
+ ds_vb = uiextras.VBox('Parent',dat_sel);
+ ds_grid = uiextras.Grid('Parent',ds_vb);
+
+ uicontrol('Style','text','String','Chans','Parent',ds_grid);
+ cs = {cdat.channames};
+ chan_sel = uicontrol('Style','listbox','Parent',ds_grid,'String',[{'ALL'}, cs{:}],'callback',@temp,'Max',2,'Min',0);
+
+ uicontrol('Style','text','String','Bins','Parent',ds_grid);
+ bs = cdat.binnames;
+ bin_sel = uicontrol('Style','listbox','Parent',ds_grid,'String',[{'ALL'}, bs{:}],'callback',@temp,'Max',2,'Min',0);
+
+ set( ds_grid, 'ColumnSizes', [-1 -1], 'RowSizes', [25, -1] );
+
+ b_c = uicontrol('Style','popupmenu','Parent',ds_vb,'String',{'Channels by Bins','Bins by Channels'},'callback',@temp);
+
+ set( ds_vb, 'Sizes', [-1, 20] );
+
+ % Plotting Options
+ pl_grid = uiextras.Grid('Parent',pl_ops);
+
+ tr_pn = uipanel('Parent',pl_grid);
+ uicontrol('Parent', tr_pn, 'Style','text','String','Range','Position',[0 0 65 25]);
+ uicontrol('Parent',pl_grid,'Style','text','String','Min');
+ uicontrol('Parent',pl_grid,'Style','edit','String','0');
+ uicontrol('Parent',pl_grid,'Style','text','String','Max');
+ uicontrol('Parent',pl_grid,'Style','edit','String','1000');
+ uiextras.Empty('Parent', pl_grid);
+ uiextras.Empty('Parent', pl_grid);
+
+ tt_pn = uipanel('Parent',pl_grid);
+ uicontrol('Parent', tt_pn, 'Style','text','String','X Scale','Position',[0 0 65 25]);
+ uicontrol('Parent',pl_grid,'Style','text','String','Min');
+ uicontrol('Parent',pl_grid,'Style','edit','String','0');
+ uicontrol('Parent',pl_grid,'Style','text','String','Max');
+ uicontrol('Parent',pl_grid,'Style','edit','String','1000');
+ uicontrol('Parent',pl_grid,'Style','text','String','Step');
+ uicontrol('Parent',pl_grid,'Style','edit','String','200');
+
+ mc_pn = uipanel('Parent',pl_grid);
+ uicontrol('Parent', mc_pn, 'Style','text','String','Misc.','Position',[0 0 65 25]);
+ uicontrol('Parent',pl_grid,'Style','text','String','a');
+ uicontrol('Parent',pl_grid,'Style','text','String','a');
+ uicontrol('Parent',pl_grid,'Style','text','String','a');
+ uicontrol('Parent',pl_grid,'Style','text','String','a');
+
+ if floating
+ uicontrol('Parent',pl_grid,'Style','text','String','a');
+ uicontrol('Parent',pl_grid,'Style','text','String','a');
+ else
+ tn = tabn;
+ uicontrol('Parent',pl_grid,'Style','pushbutton','String','Detach','callback',{@detach,tabn});
+ uicontrol('Parent',pl_grid,'Style','pushbutton','String','Retach','callback',@retach);
+ end
+
+ set( pl_grid, 'ColumnSizes', [-1 -1 -1], 'RowSizes', [35 20 25 20 25 20 25] );
+
+ set( vpanels, 'Sizes', [-1 190] );
+ set( hbox, 'Sizes', [-1 200] );
+ end
+ else
+ empty_tab = uix.HBoxFlex( 'Parent', erp_tabs, 'Spacing', 10 );
+ erp_tabs.TabNames = {'Empty'};
+ erp_tabs.TabSize = 120;
+ erp_tabs.SelectedChild = 1;
+
+ hbox = uiextras.HBox('Parent', empty_tab);
+ boxpan = uiextras.BoxPanel('Parent', hbox);
+
+ vpanels = uiextras.VBox('Parent', hbox);
+ dat_sel = uiextras.BoxPanel('Parent', vpanels,'Title','Data Selector');
+ pl_ops = uiextras.BoxPanel('Parent', vpanels,'Title','Plotting Options');
+
+ % Data Selector
+ ds_vb = uiextras.VBox('Parent',dat_sel);
+ ds_grid = uiextras.Grid('Parent',ds_vb);
+
+ uicontrol('Style','text','String','Chans','Parent',ds_grid);
+ chan_sel = uicontrol('Style','listbox','Parent',ds_grid,'String',{'ALL'},'callback',@temp,'Max',2,'Min',0);
+
+ uicontrol('Style','text','String','Bins','Parent',ds_grid);
+ bin_sel = uicontrol('Style','listbox','Parent',ds_grid,'String',{'ALL'},'callback',@temp,'Max',2,'Min',0);
+
+ set( ds_grid, 'ColumnSizes', [-1 -1], 'RowSizes', [25, -1] );
+
+ b_c = uicontrol('Style','popupmenu','Parent',ds_vb,'String',{'Channels by Bins','Bins by Channels'},'callback',@temp);
+
+ set( ds_vb, 'Sizes', [-1, 20] );
+
+ % Plotting Options
+ pl_grid = uiextras.Grid('Parent',pl_ops);
+
+ tr_pn = uipanel('Parent',pl_grid);
+ uicontrol('Parent', tr_pn, 'Style','text','String','Range','Position',[0 0 65 25]);
+ uicontrol('Parent',pl_grid,'Style','text','String','Min');
+ uicontrol('Parent',pl_grid,'Style','edit','String','0');
+ uicontrol('Parent',pl_grid,'Style','text','String','Max');
+ uicontrol('Parent',pl_grid,'Style','edit','String','1000');
+ uiextras.Empty('Parent', pl_grid);
+ uiextras.Empty('Parent', pl_grid);
+
+ tt_pn = uipanel('Parent',pl_grid);
+ uicontrol('Parent', tt_pn, 'Style','text','String','X Scale','Position',[0 0 65 25]);
+ uicontrol('Parent',pl_grid,'Style','text','String','Min');
+ uicontrol('Parent',pl_grid,'Style','edit','String','0');
+ uicontrol('Parent',pl_grid,'Style','text','String','Max');
+ uicontrol('Parent',pl_grid,'Style','edit','String','1000');
+ uicontrol('Parent',pl_grid,'Style','text','String','Step');
+ uicontrol('Parent',pl_grid,'Style','edit','String','200');
+
+ mc_pn = uipanel('Parent',pl_grid);
+ uicontrol('Parent', mc_pn, 'Style','text','String','Misc.','Position',[0 0 65 25]);
+ uicontrol('Parent',pl_grid,'Style','text','String','a');
+ uicontrol('Parent',pl_grid,'Style','text','String','a');
+ uicontrol('Parent',pl_grid,'Style','text','String','a');
+ uicontrol('Parent',pl_grid,'Style','text','String','a');
+ uicontrol('Parent',pl_grid,'Style','pushbutton','String','Detach','callback',@temp);
+ uicontrol('Parent',pl_grid,'Style','pushbutton','String','Retach','callback',@retach);
+
+ set( pl_grid, 'ColumnSizes', [-1 -1 -1], 'RowSizes', [35 20 25 20 25 20 25] );
+
+ set( vpanels, 'Sizes', [-1 190] );
+ set( hbox, 'Sizes', [-1 200] );
+ end
+ end
+
+ function drawERP(dat,p,terp)
+ ax = axes('Parent',p,'Color','none','Box','on');
+ %set( ax, 'XLim', [min max] )
+ ts = terp.times;
+ [a,c,b] = size(dat);
+ new_erp_data = zeros(a,b*c);
+ for j = 1:b
+ new_erp_data(:,((c*(j-1))+1):(c*j)) = dat(:,:,j);
+ end
+ this_plot = plot(ax,ts,new_erp_data);
+ %boxpan
+ end
+
+ function detach(~,~,tabn)
+ %tabn = erp_tabs.SelectedChild;
+ ddat = data(tabn);
+ data(tabn) = [];
+ drawUI();
+ child_vs(end+1) = {mini_viewer(ddat)};
+ end
+
+ function retach(~,~)
+ for j = child_vs
+ j = [j{1}];
+ data(end+1) = j.data;
+ delete(j.tabs.Parent);
+ end
+ drawUI();
+ child_vs = {};
+ end
+
+ function loc = erp2loc(erps)
+ news = nan(size(erps));
+ nerps = numel(erps);
+
+ cs = [erps(1).chanlocs.urchan];
+ bs = 1:numel(erps(1).bindescr);
+ es = {};
+ [d1,d2,d3] = size(erps(1).bindata);
+ for i = erps
+ [td1,td2,td3] = size(i.bindata);
+ if td1>d1
+ d1=td1;
+ end
+ if td2>d2
+ d2=td2;
+ end
+ if td3>d3
+ d3=td3;
+ end
+ end
+ ltdata = nan(d1,d2,d3,0);
+ for i = erps
+ for j = [i.chanlocs.urchan]
+ if ~ismember(j,cs)
+ cs(end+1) = j;
+ end
+ end
+ for j = 1:numel(i.bindescr)
+ if ~ismember(j,bs)
+ bs(end+1) = j;
+ end
+ end
+ es(end+1) = {i.erpname};
+ t = i.bindata;
+ try
+ if t(d1,d2,d3) == 0
+ beep;
+ end
+ catch
+ t(d1,d2,d3) = 0;
+ end
+ ltdata(:,:,:,end+1) = t;
+ end
+
+ nbs = {};
+ for i = 1:numel(bs)
+ tes = {};
+ ttes = {};
+ for j = 1:numel(erps)
+ if erps(j).nbin >= i
+ ttes(end+1) = {erps(j)};
+ tes(end+1) = es(j);
+ end
+ end
+
+ tcs = [];
+ for j = ttes
+ j1 = cell2mat(j);
+ for k = 1:j1.nchan
+ if ~ismember(k,tcs)
+ tcs(end+1) = k;
+ end
+ end
+ end
+ ttes1 = cell2mat(ttes(1));
+ nbs(end+1) = {struct('e',{tes},'b',bs(i),'c',tcs,'n',cell2mat(ttes1.bindescr(i)))};
+ end
+
+ ncs = {};
+ for i = 1:numel(cs)
+ tes = {};
+ ttes = {};
+ for j = 1:numel(erps)
+ if erps(j).nchan >= i
+ ttes(end+1) = {erps(j)};
+ tes(end+1) = es(j);
+ end
+ end
+
+ tbs = [];
+ for j = ttes
+ j1 = cell2mat(j);
+ for k = 1:j1.nbin
+ if ~ismember(k,tbs)
+ tbs(end+1) = k;
+ end
+ end
+ end
+ ttes1 = cell2mat(ttes(1));
+ tlb = {ttes1.chanlocs.labels};
+ ncs(end+1) = {struct('e',{tes},'b',tbs,'c',cs(i),'n',cell2mat(tlb(i)))};
+ end
+
+ nes = {};
+ for i = 1:numel(es)
+ nes(end+1) = {struct('e',es(i),'b',1:erps(i).nbin,'c',1:erps(i).nchan,'n',es(i))};
+ end
+
+ % Take [chans bins erpsets] and apply a filter of [2 1 3] or
+ % something to create desired permutation such as [bins chans
+ % erpsets]. Now we have [lines plots pages]!
+ nar = [numel(cs) numel(bs) numel(es)];
+ nop = nar(ord);
+
+ ar = {cs bs es};
+ op = nar(ord);
+
+ dar = {ncs nbs nes};
+ dop = dar(ord);
+
+ s = cell(1,nop(3));
+
+ for i = 1:nop(3)
+ % Iterate through all pages here
+
+ % Our data will be
+ %
+ % [ a1 a2 a3 b1 b2 b3
+ % a1 a2 a3 b1 b2 b3
+ % a1 a2 a3 b1 b2 b3 ]
+ %
+
+ temp1 = dop(3);
+ temp = temp1{:}{i};
+
+ % WARN IF BIN OR CHAN DOES NOT EXIST FOR ERPSET
+ todata = ltdata(temp.c,:,temp.b,find(strcmp(es,temp.e)));
+ t_s = [0 0 0];
+ t_s(ord) = [nop(1) nop(2) 1];
+ t_ds_o = ones(1,4);
+ t_ds = zeros(1,4);
+ t_ds_o(1:numel(size(todata))) = size(todata);
+ t_ds(1:numel(size(todata))) = size(todata);
+ if t_s(1) ~= t_ds(1)
+ ss = t_ds_o;
+ ss(1) = t_s(1);
+ todata(ss(1),ss(2),ss(3),ss(4)) = 0;
+ end
+ if t_s(2) ~= t_ds(3)
+ ss = t_ds_o;
+ ss(3) = t_s(2);
+ todata(ss(1),ss(2),ss(3),ss(4)) = 0;
+ end
+ if t_s(3) ~= t_ds(4)
+ ss = t_ds_o;
+ ss(4) = t_s(3);
+ todata(ss(1),ss(2),ss(3),ss(4)) = 0;
+ end
+
+ %if size(todata) ~= [ta tb tc ]
+ ntdata = reshape(todata,numel(erps(1).times),nop(1)*nop(2));
+
+
+ referp = dop(3);
+ referp = [referp{:}];
+ referp = referp{i};
+
+ nerp = erps(1);
+ for j = erps
+ if j.nbin > nerp.nbin
+ nerp = j;
+ end
+ end
+
+ cl = {nerp.chanlocs.labels};
+
+ s(i) = {struct('nlin',nop(1),'nplot',nop(2),'data',ntdata,'name',temp.n,'channames',{cl(referp.c)},'binnames',{nerp.bindescr(referp.b)},'erpnames',{referp.e},'times',nerp.times)};
+ clear cl nerp j temp1 t_s referp
+ end
+
+ loc = s;
+ end
+
+ function temp( src, ~ )
+ beep;
+ end
+end
\ No newline at end of file
diff --git a/studio_functions/Functions/EStudio/ERP Tab/ms_to_sample.m b/studio_functions/Functions/EStudio/ERP Tab/ms_to_sample.m
new file mode 100755
index 00000000..3657779d
--- /dev/null
+++ b/studio_functions/Functions/EStudio/ERP Tab/ms_to_sample.m
@@ -0,0 +1,67 @@
+% FORMAT:
+%
+% sampval = ms_to_sample(timems,fs,EpochStart, rounding)
+%
+% INPUTS:
+%
+% timems - time value in milliseconds
+% fs - sampling rate
+%
+% Optional inputs:
+%
+% rounding - 1 means round the result {default}, 0 means do not round
+% EpochStart - the left interval of epoch in ERP data (in milliseconds). Default 0
+%
+% OUTPUT:
+%
+% sampval - time in samples
+%
+% EXAMPLES:
+%
+% 1) For a time serie recorded from 0 to 5 secs, at fs=500 sps, get the sample index at the time 674 ms.
+%
+%>> sampval = ms_to_sample(674, 500)
+%
+%sampval =
+%
+% 338
+%
+% 2) For a time serie recorded from -1 to 5 secs, at fs=500 sps, get the sample index at the time 674 ms.
+%>> sampval674 = ms_to_sample(674, 500, -1000)
+%
+%sampval_all =
+%
+% 838
+%
+%
+% Author: Guanghui ZHANG
+% Center for Mind and Brain
+% University of California, Davis,
+% Davis, CA
+% 2022
+
+function sampval = ms_to_sample(timems,fs,offset)
+if nargin<1
+ help ms_to_sample
+ return
+end
+% if nargin<4
+% rounding = 3;
+% end
+if nargin<3
+ offset = 0;
+end
+if nargin<2
+ error('Two inputs are requiered at least.')
+% return;
+end
+
+if timems < offset
+ beep;
+ error('Input time shoule be larger than offset!!!')
+% return;
+end
+
+% offset = round(offset/50)*50;
+
+sampval = round((timems-offset)*fs/1000)+1;
\ No newline at end of file
diff --git a/studio_functions/Functions/EStudio/ERP Tab/redrawERP.m b/studio_functions/Functions/EStudio/ERP Tab/redrawERP.m
new file mode 100755
index 00000000..53c05ffd
--- /dev/null
+++ b/studio_functions/Functions/EStudio/ERP Tab/redrawERP.m
@@ -0,0 +1,769 @@
+function redrawERP()
+% Draw a demo ERP into the axes provided
+global gui_erp;
+global observe_ERPDAT;
+
+
+S_ws_geterpset= estudioworkingmemory('selectederpstudio');
+if isempty(S_ws_geterpset)
+ S_ws_geterpset = observe_ERPDAT.CURRENTERP;
+
+ if isempty(S_ws_geterpset)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+end
+
+S_ws_getbinchan = estudioworkingmemory('geterpbinchan');
+
+S_ws_geterpplot = estudioworkingmemory('geterpplot');
+
+
+%%Parameter from bin and channel panel
+Elecs_shown = S_ws_getbinchan.elecs_shown{S_ws_getbinchan.Select_index};
+Bins = S_ws_getbinchan.bins{S_ws_getbinchan.Select_index};
+Bin_chans = S_ws_getbinchan.bins_chans(S_ws_getbinchan.Select_index);
+Elec_list = S_ws_getbinchan.elec_list{S_ws_getbinchan.Select_index};
+Matlab_ver = S_ws_getbinchan.matlab_ver;
+
+
+
+%%Parameter from plotting panel
+try
+ Min_vspacing = S_ws_geterpplot.min_vspacing(S_ws_getbinchan.Select_index);
+ Min_time = S_ws_geterpplot.min(S_ws_getbinchan.Select_index);
+ Max_time = S_ws_geterpplot.max(S_ws_getbinchan.Select_index);
+ Yscale = S_ws_geterpplot.yscale(S_ws_getbinchan.Select_index);
+ Timet_low =S_ws_geterpplot.timet_low(S_ws_getbinchan.Select_index);
+ Timet_high =S_ws_geterpplot.timet_high(S_ws_getbinchan.Select_index);
+ Timet_step=S_ws_geterpplot.timet_step(S_ws_getbinchan.Select_index);
+ Fill = S_ws_geterpplot.fill(S_ws_getbinchan.Select_index);
+ Plority_plot = S_ws_geterpplot.Positive_up(S_ws_getbinchan.Select_index);
+ ColumnNum = S_ws_geterpplot.Plot_column;
+catch
+ return;
+end
+
+if Bin_chans == 0
+ elec_n = S_ws_getbinchan.elec_n(S_ws_getbinchan.Select_index);
+ max_elec_n = observe_ERPDAT.ALLERP(S_ws_geterpset(S_ws_getbinchan.Select_index)).nchan;
+else
+ elec_n = S_ws_getbinchan.bin_n(S_ws_getbinchan.Select_index);
+ max_elec_n = observe_ERPDAT.ALLERP(S_ws_geterpset(S_ws_getbinchan.Select_index)).nbin;
+end
+
+% We first clear the existing axes ready to build a new one
+if ishandle( gui_erp.ViewAxes )
+ delete( gui_erp.ViewAxes );
+end
+
+
+% Get chan labels
+S_chan.chan_label = cell(1,max_elec_n);
+S_chan.chan_label_place = zeros(1,max_elec_n);
+
+
+if Bin_chans == 0
+ for i = 1:elec_n
+ S_chan.chan_label{i} = observe_ERPDAT.ERP.chanlocs(Elecs_shown(i)).labels;
+ end
+else
+ for i = 1:elec_n
+ S_chan.chan_label{i} = observe_ERPDAT.ERP.bindescr(Bins(i));
+ end
+end
+
+
+%Sets the units of your root object (screen) to pixels
+set(0,'units','pixels')
+%Obtains this pixel information
+Pix_SS = get(0,'screensize');
+%Sets the units of your root object (screen) to inches
+set(0,'units','inches')
+%Obtains this inch information
+Inch_SS = get(0,'screensize');
+%Calculates the resolution (pixels per inch)
+Res = Pix_SS./Inch_SS;
+
+
+pb_height = Min_vspacing*Res(4); %px
+
+
+% Plot data in the main viewer fig
+splot_n = elec_n;
+tsize = 13;
+
+
+clear pb r_ax plotgrid;
+try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;%%Get background color
+catch
+ ColorB_def = [0.95 0.95 0.95];
+end
+if isempty(ColorB_def)
+ ColorB_def = [0.95 0.95 0.95];
+end
+gui_erp.plotgrid = uix.VBox('Parent',gui_erp.ViewContainer,'Padding',0,'Spacing',0,'BackgroundColor',ColorB_def);
+
+pageinfo_box = uiextras.HBox( 'Parent', gui_erp.plotgrid,'BackgroundColor',ColorB_def);
+
+gui_erp.plot_wav_legend = uiextras.HBox( 'Parent', gui_erp.plotgrid,'BackgroundColor',[1 1 1]);
+gui_erp.ViewAxes_legend = uix.ScrollingPanel( 'Parent', gui_erp.plot_wav_legend,'BackgroundColor',ColorB_def);
+
+gui_erp.ViewAxes = uix.ScrollingPanel( 'Parent', gui_erp.plot_wav_legend,'BackgroundColor',[1 1 1]);
+
+
+%%Changed by Guanghui Zhang 2 August 2022-------panel for display the processing procedure for some functions, e.g., filtering
+xaxis_panel = uiextras.HBox( 'Parent', gui_erp.plotgrid,'BackgroundColor',ColorB_def);%%%Message
+gui_erp.Process_messg = uicontrol('Parent',xaxis_panel,'Style','text','String','','FontSize',20,'FontWeight','bold','BackgroundColor',ColorB_def);
+
+
+%%Setting title
+gui_erp.pageinfo_minus = uicontrol('Parent',pageinfo_box,'Style', 'pushbutton', 'String', '<','Callback',@page_minus,'FontSize',30,'BackgroundColor',[1 1 1]);
+if S_ws_getbinchan.Select_index ==1
+ gui_erp.pageinfo_minus.Enable = 'off';
+end
+
+gui_erp.pageinfo_plus = uicontrol('Parent',pageinfo_box,'Style', 'pushbutton', 'String', '>','Callback',@page_plus,'FontSize',30,'BackgroundColor',[1 1 1]);
+if S_ws_getbinchan.Select_index == numel(S_ws_geterpset)
+ gui_erp.pageinfo_plus.Enable = 'off';
+end
+
+pageinfo_str = ['Page',32,num2str(S_ws_getbinchan.Select_index),'/',num2str(numel(S_ws_geterpset)),':',32,observe_ERPDAT.ERP.erpname];
+
+pageinfo_text = uicontrol('Parent',pageinfo_box,'Style','text','String',pageinfo_str,'FontSize',20,'FontWeight','bold');
+
+if length(S_ws_geterpset) ==1
+ Enable_minus = 'off';
+ Enable_plus = 'off';
+ Enable_plus_BackgroundColor = [1 1 1];
+ Enable_minus_BackgroundColor = [0 0 0];
+else
+
+ if S_ws_getbinchan.Select_index ==1
+ Enable_minus = 'off';
+ Enable_plus = 'on';
+
+ Enable_plus_BackgroundColor = [0 1 0];
+ Enable_minus_BackgroundColor = [0 0 0];
+ elseif S_ws_getbinchan.Select_index == length(S_ws_geterpset)
+ Enable_minus = 'on';
+ Enable_plus = 'off';
+ Enable_plus_BackgroundColor = [0 0 0];
+ Enable_minus_BackgroundColor = [0 1 0];
+ else
+ Enable_minus = 'on';
+ Enable_plus = 'on';
+ Enable_plus_BackgroundColor = [0 1 0];
+ Enable_minus_BackgroundColor = [0 1 0];
+ end
+end
+gui_erp.pageinfo_minus.Enable = Enable_minus;
+gui_erp.pageinfo_plus.Enable = Enable_plus;
+gui_erp.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor;
+gui_erp.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor;
+
+set(pageinfo_box, 'Sizes', [50 50 -1] );
+set(pageinfo_box,'BackgroundColor',ColorB_def);
+set(pageinfo_text,'BackgroundColor',ColorB_def);
+%Setting title. END,'BackgroundColor',ColorB_def
+
+%for i=1:splot_n
+
+ndata = 0;
+nplot = 0;
+if Bin_chans == 0
+ ndata = Bins;
+ nplot = Elecs_shown;
+else
+ ndata = Elecs_shown;
+ nplot = Bins;
+end
+
+%
+timeor = observe_ERPDAT.ERP.times; % original time vector
+timex = timeor;
+[xxx, latsamp, latdiffms] = closest(timex, [Min_time Max_time]);
+tmin = latsamp(1);
+tmax = latsamp(2);
+
+if tmin < 1
+ tmin = 1;
+end
+
+if tmax > numel(observe_ERPDAT.ERP.times)
+ tmax = numel(observe_ERPDAT.ERP.times);
+end
+
+plot_erp_data = nan(tmax-tmin+1,numel(ndata));
+for i = 1:splot_n
+ if Bin_chans == 0
+ for i_bin = 1:numel(ndata)
+ plot_erp_data(:,i_bin,i) = observe_ERPDAT.ERP.bindata(Elecs_shown(i),tmin:tmax,Bins(i_bin))'*Plority_plot; %
+ end
+ else
+ for i_bin = 1:numel(ndata)
+ plot_erp_data(:,i_bin,i) = observe_ERPDAT.ERP.bindata(Elecs_shown(i_bin),tmin:tmax,Bins(i))'*Plority_plot; %
+ end
+ end
+end
+
+perc_lim = Yscale;
+percentile = perc_lim*3/2;
+
+[~,~,b] = size(plot_erp_data);
+
+%How to get x unique colors?
+
+
+%%----------------------Modify the data into multiple-columns---------------------------------------
+rowNum = ceil(b/ColumnNum(S_ws_getbinchan.Select_index));
+plot_erp_data_new = zeros(size(plot_erp_data,1),size(plot_erp_data,2),rowNum*ColumnNum(S_ws_getbinchan.Select_index));
+
+plot_erp_data_new(:,:,1:size(plot_erp_data,3)) = plot_erp_data;
+plot_erp_data_new_trans = [];
+for Numofrow = 1:rowNum
+ plot_erp_data_new_trans(:,:,:,Numofrow) = plot_erp_data_new(:,:,(Numofrow-1)*ColumnNum(S_ws_getbinchan.Select_index)+1:Numofrow*ColumnNum(S_ws_getbinchan.Select_index));
+end
+
+clear plot_erp_data;
+
+plot_erp_data_new_trans = permute(plot_erp_data_new_trans,[1,3,2,4]) ;
+plot_erp_data = reshape(plot_erp_data_new_trans,size(plot_erp_data_new_trans,1)*size(plot_erp_data_new_trans,2),size(plot_erp_data_new_trans,3),size(plot_erp_data_new_trans,4));
+
+% Min_time = Min_time*ColumnNum(S_ws_getbinchan.Select_index);
+% Max_time = Max_time*ColumnNum(S_ws_getbinchan.Select_index);
+ind_plot_height = percentile*2; % Height of each individual subplot
+
+offset = [];
+if Bin_chans == 0
+ offset = (size(plot_erp_data,3)-1:-1:0)*ind_plot_height;
+else
+ offset = (size(plot_erp_data,3)-1:-1:0)*ind_plot_height;
+end
+[~,~,b] = size(plot_erp_data);
+
+for i = 1:b
+ plot_erp_data(:,:,i) = plot_erp_data(:,:,i) + ones(size(plot_erp_data(:,:,i)))*offset(i);
+end
+
+
+
+r_ax = axes('Parent', gui_erp.ViewAxes,'Color','none','Box','on');
+hold(r_ax,'on');
+set(gui_erp.plot_wav_legend,'Sizes',[80 -10]);
+r_ax_legend = axes('Parent', gui_erp.ViewAxes_legend,'Color','none','Box','off');
+hold(r_ax_legend,'on');
+
+
+Min_time_onecolm = S_ws_geterpplot.min(S_ws_getbinchan.Select_index);
+Max_time_onecolm = S_ws_geterpplot.max(S_ws_getbinchan.Select_index);
+
+try
+ f_bin = 1000/observe_ERPDAT.ERP.srate;
+catch
+ f_bin = 1;
+end
+
+ts = observe_ERPDAT.ERP.times(tmin:tmax);
+ts_colmn = ts;
+xticks_clomn = (Min_time:Timet_step:Max_time);
+xticks = (Min_time:Timet_step:Max_time);
+if ColumnNum(S_ws_getbinchan.Select_index)>1 % Plotting waveforms with munltiple-columns
+
+ for Numofcolumn = 1:ColumnNum(S_ws_getbinchan.Select_index)-1
+ ts_colmn = [ts_colmn,ts+ones(1,numel(ts))*(ts_colmn(end)+f_bin-ts(1))];
+ xticks_clomn = [xticks_clomn,xticks(2:end)];
+ end
+ X_zero_line(1) =ts(1);
+ for Numofcolumn = 1:ColumnNum(S_ws_getbinchan.Select_index)-1
+ X_zero_line(Numofcolumn+1) = X_zero_line(Numofcolumn)+ ts(end)-ts(1)+f_bin;
+ end
+
+ ts = ts_colmn;
+
+ Min_time = ts(1);
+ Max_time = ts(end);
+ xticks = xticks_clomn;
+
+else%% Plotting waveforms with single-column
+ xticks = (Min_time:Timet_step:Max_time);
+ X_zero_line(1) =ts(1);
+end
+
+for Numofxlabel = 1:numel(xticks)
+ xticks_labels{Numofxlabel} = num2str(xticks(Numofxlabel));
+end
+
+splot_n = size(plot_erp_data,3);%%Adjust the columns
+
+set(r_ax,'XLim',[Min_time Max_time]);
+
+[a,c,b] = size(plot_erp_data);
+new_erp_data = zeros(a,b*c);
+for i = 1:b
+ new_erp_data(:,((c*(i-1))+1):(c*i)) = plot_erp_data(:,:,i);
+end
+
+
+line_colors = erpworkingmemory('PWColor');
+if size(line_colors,1)~= numel(ndata)
+ if numel(ndata)> size(line_colors,1)
+ line_colors = get_colors(numel(ndata));
+ else
+ line_colors = line_colors(1:numel(ndata),:,:);
+ end
+end
+
+if isempty(line_colors)
+ line_colors = get_colors(numel(ndata));
+end
+
+line_colors = repmat(line_colors,[splot_n 1]); %repeat the colors once for every plot
+
+if ColumnNum(S_ws_getbinchan.Select_index)>1
+ for ii = 1:numel(X_zero_line)
+ xline_p = xline(r_ax,X_zero_line(ii),'--','Color', [0 0 0],'LineWidth',1.5);%%Marking start time point for each column
+ xline_p.FontSize = 18;
+ end
+
+
+end
+
+
+%%%------------Setting xticklabels for each row of each wave--------------
+x_axs = ones(size(new_erp_data,1),1);
+if numel(offset)>1
+
+ for jj = 1:numel(offset)
+ x_axset = plot(r_ax,ts,x_axs.*offset(jj),'k','LineWidth',1);
+ set(r_ax,'XTick',[Min_time:Timet_step:Max_time], ...
+ 'box','off', 'Color','none','xticklabels',xticks_labels,'FontWeight','bold');
+ end
+
+end
+if numel(offset)>1
+
+ for jj = 1:numel(offset)
+ x_axset = plot(r_ax,ts,x_axs.*offset(end-1),'k','LineWidth',1);
+ set(r_ax,'XTick',[Min_time:Timet_step:Max_time], ...
+ 'box','off', 'Color','none','xticklabels',xticks_labels,'FontWeight','bold');
+ myX_Crossing = offset(jj);
+ props = get(r_ax);
+
+ tick_bottom = -props.TickLength(1)*diff(props.YLim);
+ if abs(tick_bottom) > abs(Yscale)/5
+ try
+ tick_bottom = - abs(Yscale)/5;
+ catch
+ tick_bottom = tick_bottom;
+ end
+ end
+ tick_top = 0;
+
+ h_xaxis = line(r_ax,props.XLim, [0 0] + myX_Crossing, 'color', 'k');
+
+ if ~isempty(props.XTick)
+ xtick_x = repmat(props.XTick, 2, 1);
+ xtick_y = repmat([tick_bottom; tick_top] + myX_Crossing, 1, length(props.XTick));
+ h_ticks = line(r_ax,xtick_x, xtick_y, 'color', 'k');
+ end
+ set(r_ax, 'XTick', [], 'XTickLabel', []);
+ % tick_bottom = -props.TickLength(1)*diff(props.YLim);
+ nTicks = length(props.XTick);
+ h_ticklabels = zeros(size(props.XTick));
+ if nTicks>1
+ if numel(offset)==jj
+ kkkk = 1;
+ else
+ kkkk = 2;
+ end
+ for iCount = kkkk:nTicks
+ xtick_label = (props.XTickLabel(iCount, :));
+ text(r_ax,props.XTick(iCount), tick_bottom + myX_Crossing, ...
+ xtick_label, ...
+ 'HorizontalAlignment', 'Center', ...
+ 'VerticalAlignment', 'Top', ...
+ 'FontSize', 12, ...
+ 'FontName', props.FontName, ...
+ 'FontAngle', props.FontAngle, ...
+ 'FontUnits', props.FontUnits, ...
+ 'FontWeight', 'bold');
+ end
+ end
+
+ end
+end
+%%%%%%%%-----------------------------
+
+% set(r_ax,'XDir','reverse')
+
+pb_here = plot(r_ax,ts, [repmat((1:numel(nplot)-1)*ind_plot_height,[numel(ts) 1]) new_erp_data],'LineWidth',1);
+r_ax.LineWidth=1.5;
+set(r_ax, 'XTick', [], 'XTickLabel', [])
+
+%
+yticks = -perc_lim:perc_lim:((2*percentile*b)-(2*perc_lim));
+ylabs = repmat([-perc_lim 0 perc_lim],[1,b]);
+oldlim = [-percentile yticks(end)-perc_lim+percentile];
+top_vspace = max( max( new_erp_data))-oldlim(2);
+bot_vspace = min( min( new_erp_data))-oldlim(1);
+if top_vspace < 0
+ top_vspace = 0;
+end
+
+if bot_vspace > 0
+ bot_vspace = 0;
+end
+newlim = oldlim + [bot_vspace top_vspace];
+set(r_ax,'XLim',[Min_time Max_time],'Ylim',newlim);
+
+
+for i = 0:numel(nplot)-2
+ r_ax.Children(end-i).Color = [0 0 0];
+end
+
+
+for i = numel(nplot):numel(pb_here)
+ pb_here(i).Color = line_colors((i-numel(nplot)+1),:);
+
+end
+
+for i = 1:numel(nplot)-1
+ pb_here(i).Color = [0 0 0];
+end
+
+
+
+ylabs = [fliplr(-perc_lim:-perc_lim:newlim(1)) ylabs(2:end-1) (yticks(end):perc_lim:newlim(2))-yticks(end)+perc_lim];
+yticks = [fliplr(-perc_lim:-perc_lim:newlim(1)) yticks(2:end-1) yticks(end):perc_lim:newlim(2)];
+
+
+
+Ylabels_new = ylabs.*Plority_plot;
+[~,Y_label] = find(Ylabels_new == -0);
+Ylabels_new(Y_label) = 0;
+if ColumnNum(S_ws_getbinchan.Select_index)==1
+ % Ylabels_fin = {};
+ % count = 0;
+ % for Numofylabel = numel(Ylabels_new):-1:1
+ %
+ % if Ylabels_new(Numofylabel)==0
+ % count =count+1;
+ %
+ % if Bin_chans == 0
+ % Ylabels_fin{Numofylabel} = strcat(Elec_list{Elecs_shown(count)},'(',num2str(Elecs_shown(count)),')');
+ % else
+ % Ylabels_fin{Numofylabel} = ['Bin',num2str(Bins(count))];
+ % end
+ % else
+ % Ylabels_fin{Numofylabel} = num2str(roundn(Ylabels_new(Numofylabel),-1));
+ % end
+ %
+ % end
+ % else%% Getting y ticks and legends for multiple-columns
+ % for Numofylabel = numel(Ylabels_new):-1:1
+ % Ylabels_fin{Numofylabel} = num2str(roundn(Ylabels_new(Numofylabel),-1));
+ % end
+ if numel(offset)>1
+ count = 0;
+ for i = 0:numel(offset)-1
+ leg_str = '';
+ for Numofcolumn = 1: ColumnNum(S_ws_getbinchan.Select_index)
+ count = count+1;
+ try
+ if Bin_chans == 0
+ leg_str = sprintf('%s',Elec_list{Elecs_shown(count)});
+ else
+ leg_str = sprintf('%s',observe_ERPDAT.ERP.bindescr{Bins(count)});
+ end
+ catch
+ leg_str = '';
+ end
+ text(r_ax,X_zero_line(Numofcolumn),offset(i+1)+offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 18);
+ end
+ end
+ end
+
+
+ count = (numel(offset)-1)*ColumnNum(S_ws_getbinchan.Select_index);
+ leg_str = '';
+ for Numofcolumn = 1: ColumnNum(S_ws_getbinchan.Select_index)
+ count = count+1;
+ try
+ if Bin_chans == 0
+ leg_str = sprintf('%s',Elec_list{Elecs_shown(count)});
+ else
+ leg_str = sprintf('%s',observe_ERPDAT.ERP.bindescr{Bins(count)});
+ end
+ catch%%
+ leg_str = '';
+ end
+ try
+ text(r_ax,X_zero_line(Numofcolumn),offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 18);
+ catch
+ text(r_ax,X_zero_line(Numofcolumn),Yscale/2,leg_str,'FontWeight','bold','FontSize', 18);
+ end
+ end
+
+end
+
+
+
+
+% xticks = (Min_time:Timet_step:Max_time);
+% some options currently only work post Matlab R2016a ,'XLim',[Min_time Max_time],'XLim',[Min_time Max_time]
+if Matlab_ver >= 2016
+ set(r_ax,'FontSize',tsize,'FontWeight','bold','XAxisLocation','origin',...
+ 'XGrid','on','YGrid','on','YTick',yticks,'YTickLabel',Ylabels_new, ...
+ 'YLim',newlim,'XTick',[Min_time:Timet_step:Max_time], ...
+ 'box','off', 'Color','none','xticklabels',xticks_labels);
+else
+ set(r_ax,'FontSize',tsize,'FontWeight','bold','XAxisLocation','bottom',...
+ 'XGrid','on','YGrid','on','YTick',yticks,'YTickLabel',Ylabels_new, ...
+ 'YLim',newlim, 'XTick',[Min_time:Timet_step:Max_time], ...
+ 'box','off', 'Color','none','xticklabels',xticks_labels);
+ hline(0,'k'); % backup xaxis
+end
+if numel(offset)>1
+ set(r_ax, 'XTick', [], 'XTickLabel', [])
+end
+
+%%%%%%%%%%%%
+hold(r_ax,'off');
+% r_ax.Position(2) =r_ax.Position(2)-5;
+line_colors_ldg = erpworkingmemory('PWColor');
+if isempty(line_colors_ldg)
+ line_colors_ldg = get_colors(numel(ndata));
+end
+
+if size(line_colors_ldg,1)~= numel(ndata)
+ if numel(ndata)> size(line_colors_ldg,1)
+ line_colors_ldg = get_colors(numel(ndata));
+ else
+ line_colors_ldg = line_colors_ldg(1:numel(ndata),:,:);
+ end
+end
+
+for Numofplot = 1:size(plot_erp_data,2)
+ plot(r_ax_legend,[0 0],'Color',line_colors_ldg(Numofplot,:,:),'LineWidth',3)
+end
+
+if Bin_chans == 0
+
+ Leg_Name = {};
+
+ for Numofbin = 1:numel(Bins)
+ Leg_Name{Numofbin} = strcat('Bin',num2str(Bins(Numofbin)));
+
+ end
+
+else
+ for Numofchan = 1:numel(Elecs_shown)
+ Leg_Name{Numofchan} = Elec_list{Numofchan};
+ end
+end
+legend(r_ax_legend,Leg_Name,'FontSize',14,'TextColor','blue');
+legend(r_ax_legend,'boxoff');
+% title(here_lgd,'Legend');
+
+% fix scaling shrinkage
+pos_fix = r_ax.Position;
+pos_fix(2) = 1; % Start at the bottom
+pos_fix(4) = pb_height - 1; % fill the height;
+
+gui_erp.plotgrid.Heights(1) = 30; % set the first element (pageinfo) to 30px high
+gui_erp.plotgrid.Heights(3) = 30; % set the second element (x axis) to 30px high
+gui_erp.plotgrid.Units = 'pixels';
+if splot_n*pb_height<(gui_erp.plotgrid.Position(4)-gui_erp.plotgrid.Heights(1))&&Fill
+ pb_height = (gui_erp.plotgrid.Position(4)-gui_erp.plotgrid.Heights(1)-gui_erp.plotgrid.Heights(2))/splot_n;
+end
+
+gui_erp.ViewAxes.Heights = splot_n*pb_height;
+gui_erp.plotgrid.Units = 'normalized';
+
+end % redrawDemo
+
+
+function colors = get_colors(ncolors)
+% Each color gets 1 point divided into up to 2 of 3 groups (RGB).
+degree_step = 6/ncolors;
+angles = (0:ncolors-1)*degree_step;
+colors = nan(numel(angles),3);
+for i = 1:numel(angles)
+ if angles(i) < 1
+ colors(i,:) = [1 (angles(i)-floor(angles(i))) 0]*0.75;
+ elseif angles(i) < 2
+ colors(i,:) = [(1-(angles(i)-floor(angles(i)))) 1 0]*0.75;
+ elseif angles(i) < 3
+ colors(i,:) = [0 1 (angles(i)-floor(angles(i)))]*0.75;
+ elseif angles(i) < 4
+ colors(i,:) = [0 (1-(angles(i)-floor(angles(i)))) 1]*0.75;
+ elseif angles(i) < 5
+ colors(i,:) = [(angles(i)-floor(angles(i))) 0 1]*0.75;
+ else
+ colors(i,:) = [1 0 (1-(angles(i)-floor(angles(i))))]*0.75;
+ end
+end
+end
+
+
+
+%------------------Display the waveform for proir ERPset--------------------
+function page_minus(~,~)
+global observe_ERPDAT;
+global gui_erp;
+
+
+S_ws_geterpset= estudioworkingmemory('selectederpstudio');
+if isempty(S_ws_geterpset)
+ S_ws_geterpset = observe_ERPDAT.CURRENTERP;
+
+ if isempty(S_ws_geterpset)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+end
+
+S_ws_getbinchan = estudioworkingmemory('geterpbinchan');
+
+
+S_ws_getbinchan.Select_index = S_ws_getbinchan.Select_index-1;
+Current_erp_Index = S_ws_geterpset(S_ws_getbinchan.Select_index);
+if Current_erp_Index > length(observe_ERPDAT.ALLERP)
+ beep;
+ disp('Waiting for modifing');
+ return;
+end
+
+observe_ERPDAT.CURRENTERP = Current_erp_Index;
+observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_erp_Index);
+
+
+estudioworkingmemory('geterpbinchan',S_ws_getbinchan);
+
+
+observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+
+
+if length(S_ws_geterpset) ==1
+ Enable_minus = 'off';
+ Enable_plus = 'off';
+ Enable_plus_BackgroundColor = [0 0 0];
+ Enable_minus_BackgroundColor = [0 0 0];
+else
+
+ if S_ws_getbinchan.Select_index ==1
+ Enable_minus = 'off';
+ Enable_plus = 'on';
+
+ Enable_plus_BackgroundColor = [0 1 0];
+ Enable_minus_BackgroundColor = [0 0 0];
+ elseif S_ws_getbinchan.Select_index == length(S_ws_geterpset)
+ Enable_minus = 'on';
+ Enable_plus = 'off';
+ Enable_plus_BackgroundColor = [0 0 0];
+ Enable_minus_BackgroundColor = [0 1 0];
+ else
+ Enable_minus = 'on';
+ Enable_plus = 'on';
+ Enable_plus_BackgroundColor = [0 1 0];
+ Enable_minus_BackgroundColor = [0 1 0];
+ end
+end
+gui_erp.pageinfo_minus.Enable = Enable_minus;
+gui_erp.pageinfo_plus.Enable = Enable_plus;
+% f_redrawERP_mt_viewer();
+gui_erp.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor;
+gui_erp.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor;
+end
+
+
+
+
+
+%------------------Display the waveform for next ERPset--------------------
+function page_plus(~,~)
+global observe_ERPDAT;
+global gui_erp;
+
+
+S_ws_geterpset= estudioworkingmemory('selectederpstudio');
+if isempty(S_ws_geterpset)
+ S_ws_geterpset = observe_ERPDAT.CURRENTERP;
+
+ if isempty(S_ws_geterpset)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+end
+
+S_ws_getbinchan = estudioworkingmemory('geterpbinchan');
+
+
+
+
+S_ws_getbinchan.Select_index = S_ws_getbinchan.Select_index+1;
+Current_erp_Index = S_ws_geterpset(S_ws_getbinchan.Select_index);
+if Current_erp_Index > length(observe_ERPDAT.ALLERP)
+ beep;
+ disp('Waiting for modifing');
+ return;
+end
+
+observe_ERPDAT.CURRENTERP = Current_erp_Index;
+observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_erp_Index);
+
+estudioworkingmemory('geterpbinchan',S_ws_getbinchan);
+
+observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+
+
+if length(S_ws_geterpset) ==1
+ Enable_minus = 'off';
+ Enable_plus = 'off';
+ Enable_plus_BackgroundColor = [0 0 0];
+ Enable_minus_BackgroundColor = [0 0 0];
+else
+
+ if S_ws_getbinchan.Select_index ==1
+ Enable_minus = 'off';
+ Enable_plus = 'on';
+ Enable_plus_BackgroundColor = [0 1 0];
+ Enable_minus_BackgroundColor = [1 1 1];
+ elseif S_ws_getbinchan.Select_index == length(S_ws_geterpset)
+ Enable_minus = 'on';
+ Enable_plus = 'off';
+ Enable_plus_BackgroundColor = [0 0 0];
+ Enable_minus_BackgroundColor = [0 1 0];
+
+
+ else
+ Enable_minus = 'on';
+ Enable_plus = 'on';
+ Enable_plus_BackgroundColor = [0 1 0];
+ Enable_minus_BackgroundColor = [0 1 0];
+ end
+end
+gui_erp.pageinfo_minus.Enable = Enable_minus;
+gui_erp.pageinfo_plus.Enable = Enable_plus;
+gui_erp.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor;
+gui_erp.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor;
+end
+
+
diff --git a/studio_functions/Functions/EStudio/ERP Tab/sample_to_ms.m b/studio_functions/Functions/EStudio/ERP Tab/sample_to_ms.m
new file mode 100755
index 00000000..33e45937
--- /dev/null
+++ b/studio_functions/Functions/EStudio/ERP Tab/sample_to_ms.m
@@ -0,0 +1,70 @@
+% FORMAT:
+%
+% sampval = sample_to_ms(timesam, fs,EpochStart, rounding)
+%
+% INPUTS:
+%
+% timesam - time value in time samples
+% fs - sampling rate (in Hz)
+%
+%
+% Optional inputs:
+%
+% rounding - 1 means round the result {default}, 0 means do not round
+% EpochStart - the left interval of epoch/trial (e.g., -200ms). Default is 0 ms.
+
+
+% OUTPUT:
+%
+% sampval - time in milliseconds
+%
+% EXAMPLES:
+%
+% 1) For a time serie recorded from 0 to 5 secs, at fs=500 sps, get the time in ms for the sample # 337.
+%
+% msval = sample_to_ms(337, 500)
+%
+% msval =
+%
+% 672
+%
+% 2) For a time serie recorded from -1 to 5 secs, at fs=500 sps, get the absolute time in ms for the sample # 337.
+%
+% msval = sample_to_ms(337, 500, -1000)
+%
+% msval =
+%
+% -328
+%
+%
+% Author: Guanghui ZHANG
+% Center for Mind and Brain
+% University of California, Davis,
+% Davis, CA
+% Feb., 2022
+
+function msval = sample_to_ms(timesam,fs,offset, rounding)
+if nargin<1
+ help sample_to_ms
+ return
+end
+
+if nargin<4
+ rounding = 0;
+end
+%
+if nargin < 3
+ offset = 0;
+end
+
+if nargin<2
+ error('Two inputs are required at least!!!');
+end
+
+
+msval = 1000*(timesam-1)/fs+offset;
+
+if rounding
+ msval = round(msval);
+end
+
diff --git a/studio_functions/Functions/EStudio/ERP Tab/working_mem_save_load.m b/studio_functions/Functions/EStudio/ERP Tab/working_mem_save_load.m
new file mode 100755
index 00000000..f58a2338
--- /dev/null
+++ b/studio_functions/Functions/EStudio/ERP Tab/working_mem_save_load.m
@@ -0,0 +1,91 @@
+% PURPOSE: saves or loads the ERPLAB working memory to another location
+%
+% FORMAT
+%
+% working_mem_save_load(save_or_load)
+%
+% INPUT
+%
+% save_or_load - 1 for save; 2 for load
+%
+% OUTPUT
+%
+% Mat-file .erpm written to disk, or memory structure loaded.
+%
+% *** This function is part of ERPLAB Toolbox ***
+% Author: Andrew Stewart
+% Center for Mind and Brain
+% University of California, Davis,
+% Davis, CA
+% 2016
+
+%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b
+%
+% ERPLAB Toolbox
+% Copyright © 2007 The Regents of the University of California
+% Created by Javier Lopez-Calderon and Steven Luck
+% Center for Mind and Brain, University of California, Davis,
+% javlopez@ucdavis.edu, sjluck@ucdavis.edu
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see .
+
+
+
+function [wm_loaded] = working_mem_save_load(save_or_load)
+
+if save_or_load == 1
+
+ wm_loaded = [];
+
+ % prompt for path with file browser ui
+ [wm_fname, wm_pathname] = uiputfile({'*.erpm', 'ERP working memory file (*.erpm)';
+ '*.*' , 'All Files (*.*)'},'Save working memory file as',...
+ 'custom_memoryerp.erpm');
+
+ try
+ vmemoryerp = evalin('base', 'vmemoryerp');
+
+ % save
+ save(fullfile(wm_pathname, wm_fname), 'vmemoryerp');
+
+
+ catch
+ errordlg('Memory save problem. Perhaps memory was empty?');
+ end
+
+
+
+
+
+elseif save_or_load == 2
+
+
+ % prompt for path with file browser ui
+ [wm_load_fname, wm_load_pathname] = uigetfile({'*.erpm', 'ERP working memory file (*.erpm)';
+ '*.*' , 'All Files (*.*)'},'Pick an existing working memory file to load',...
+ 'custom_memoryerp.erpm');
+ if isempty(wm_load_pathname) || length(wm_load_pathname)==1
+ beep;
+ disp('User selected cancel');
+ wm_loaded =[];
+ return;
+ end
+ wm_loaded = load(fullfile(wm_load_pathname,wm_load_fname), '-mat');
+
+else
+ errordlg('WM save function error?');
+end
+
+end
+
diff --git a/studio_functions/Functions/EStudio/f_get_default_fontsize.m b/studio_functions/Functions/EStudio/f_get_default_fontsize.m
new file mode 100644
index 00000000..bb0af327
--- /dev/null
+++ b/studio_functions/Functions/EStudio/f_get_default_fontsize.m
@@ -0,0 +1,20 @@
+
+
+
+
+function FonsizeDefault = f_get_default_fontsize()
+
+if ismac
+ % Code to run on Mac platform
+ FonsizeDefault = 12;
+elseif isunix
+ % Code to run on Linux platform
+ FonsizeDefault = 9;
+elseif ispc
+ % Code to run on Windows platform
+ FonsizeDefault = 9;
+else
+ FonsizeDefault = 9;
+end
+
+end
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/BoxPanel.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/BoxPanel.m
new file mode 100644
index 00000000..4c2e741f
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/BoxPanel.m
@@ -0,0 +1,144 @@
+classdef BoxPanel < uix.BoxPanel
+ %uiextras.BoxPanel Show one element inside a box panel
+ %
+ % obj = uiextras.BoxPanel() creates a box-styled panel object with
+ % automatic management of the contained widget or layout. The
+ % properties available are largely the same as the builtin UIPANEL
+ % object. Where more than one child is added, the currently visible
+ % child is determined using the SelectedChild property.
+ %
+ % obj = uiextras.BoxPanel(param,value,...) also sets one or more
+ % property values.
+ %
+ % See the documentation for more detail and the list of properties.
+ %
+ % Examples:
+ % >> f = figure();
+ % >> p = uiextras.BoxPanel( 'Parent', f, 'Title', 'A BoxPanel', 'Padding', 5 );
+ % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'r' )
+ %
+ % >> f = figure();
+ % >> p = uiextras.BoxPanel( 'Parent', f, 'Title', 'A BoxPanel', 'Padding', 5 );
+ % >> b = uiextras.HBox( 'Parent', p, 'Spacing', 5 );
+ % >> uicontrol( 'Style', 'listbox', 'Parent', b, 'String', {'Item 1','Item 2'} );
+ % >> uicontrol( 'Style', 'frame', 'Parent', b, 'Background', 'b' );
+ % >> set( b, 'Sizes', [100 -1] );
+ % >> p.FontSize = 12;
+ % >> p.FontWeight = 'bold';
+ % >> p.HelpFcn = @(x,y) disp('Help me!');
+ %
+ % See also: uiextras.Panel
+ % uiextras.TabPanel
+ % uiextras.HBoxFlex
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Hidden, Access = public, Dependent )
+ IsDocked
+ IsMinimized
+ SelectedChild % deprecated
+ end
+
+ methods
+
+ function obj = BoxPanel( varargin )
+
+ % Call uix constructor
+ obj@uix.BoxPanel( varargin{:} )
+
+ % Add Enable property
+ if ~isprop( obj, 'Enable' )
+ p = addprop( obj, 'Enable' );
+ p.GetMethod = @getEnable;
+ p.SetMethod = @setEnable;
+ end
+
+ % Auto-parent
+ if ~ismember( 'Parent', varargin(1:2:end) )
+ obj.Parent = gcf();
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = getEnable( ~ )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ % Return
+ value = 'on';
+
+ end % getEnable
+
+ function setEnable( ~, value )
+
+ % Check
+ assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ...
+ 'uiextras:InvalidPropertyValue', ...
+ 'Property ''Enable'' must be ''on'' or ''off''.' )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ end % setEnable
+
+ function value = get.IsDocked( obj )
+
+ % Get
+ value = obj.Docked;
+
+ end % get.IsDocked
+
+ function set.IsDocked( obj, value )
+
+ % Get
+ obj.Docked = value;
+
+ end % set.IsDocked
+
+ function value = get.IsMinimized( obj )
+
+ % Get
+ value = obj.Minimized;
+
+ end % get.IsMinimized
+
+ function set.IsMinimized( obj, value )
+
+ % Get
+ obj.Minimized = value;
+
+ end % set.IsMinimized
+
+ function value = get.SelectedChild( obj )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''SelectedChild'' will be removed in a future release.' )
+
+ % Get
+ if isempty( obj.Contents_ )
+ value = [];
+ else
+ value = 1;
+ end
+
+ end % get.SelectedChild
+
+ function set.SelectedChild( ~, ~ )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''SelectedChild'' will be removed in a future release.' )
+
+ end % set.SelectedChild
+
+ end % accessors
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/CardPanel.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/CardPanel.m
new file mode 100644
index 00000000..4ac8b13b
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/CardPanel.m
@@ -0,0 +1,92 @@
+classdef CardPanel < uix.CardPanel
+ %uiextras.CardPanel Show one element (card) from a list
+ %
+ % obj = uiextras.CardPanel() creates a new card panel which allows
+ % selection between the different child objects contained, making the
+ % selected child fill the space available and all other children
+ % invisible. This is commonly used for creating wizards or quick
+ % switching between different views of a single data-set.
+ %
+ % obj = uiextras.CardPanel(param,value,...) also sets one or more
+ % property values.
+ %
+ % See the documentation for more detail and the list of properties.
+ %
+ % Examples:
+ % >> f = figure();
+ % >> p = uiextras.CardPanel( 'Parent', f, 'Padding', 5 );
+ % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'r' );
+ % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'b' );
+ % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'g' );
+ % >> p.SelectedChild = 2;
+ %
+ % See also: uiextras.Panel
+ % uiextras.BoxPanel
+ % uiextras.TabPanel
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Hidden, Access = public, Dependent )
+ Enable % deprecated
+ SelectedChild
+ end
+
+ methods
+
+ function obj = CardPanel( varargin )
+
+ % Call uix constructor
+ obj@uix.CardPanel( varargin{:} )
+
+ % Auto-parent
+ if ~ismember( 'Parent', varargin(1:2:end) )
+ obj.Parent = gcf();
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = get.Enable( ~ )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ % Return
+ value = 'on';
+
+ end % get.Enable
+
+ function set.Enable( ~, value )
+
+ % Check
+ assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ...
+ 'uiextras:InvalidPropertyValue', ...
+ 'Property ''Enable'' must be ''on'' or ''off''.' )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ end % set.Enable
+
+ function value = get.SelectedChild( obj )
+
+ % Get
+ value = obj.Selection;
+
+ end % get.SelectedChild
+
+ function set.SelectedChild( obj, value )
+
+ % Set
+ obj.Selection = value;
+
+ end % set.SelectedChild
+
+ end % accessors
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/Empty.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/Empty.m
new file mode 100644
index 00000000..af923f55
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/Empty.m
@@ -0,0 +1,29 @@
+function obj = Empty( varargin )
+%uiextras.Empty Create an empty space
+%
+% obj = uiextras.Empty() creates an empty space that can be used to add
+% gaps between elements in layouts.
+%
+% obj = uiextras.Empty(param,value,...) also sets one or more property
+% values.
+%
+% See the documentation for more detail and the list of properties.
+%
+% Examples:
+% >> f = figure();
+% >> box = uiextras.HBox( 'Parent', f );
+% >> uicontrol( 'Parent', box, 'Background', 'r' )
+% >> uiextras.Empty( 'Parent', box )
+% >> uicontrol( 'Parent', box, 'Background', 'b' )
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+% Call uix construction function
+obj = uix.Empty( varargin{:} );
+
+% Auto-parent
+if ~ismember( 'Parent', varargin(1:2:end) )
+ obj.Parent = gcf();
+end
+
+end % uiextras.Empty
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/Grid.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/Grid.m
new file mode 100644
index 00000000..062be330
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/Grid.m
@@ -0,0 +1,142 @@
+classdef Grid < uix.Grid
+ %uiextras.Grid Container with contents arranged in a grid
+ %
+ % obj = uiextras.Grid() creates a new new grid layout with all
+ % properties set to defaults. The number of rows and columns to use
+ % is determined from the number of elements in the RowSizes and
+ % ColumnSizes properties respectively. Child elements are arranged
+ % down column one first, then column two etc. If there are
+ % insufficient columns then a new one is added. The output is a new
+ % layout object that can be used as the parent for other
+ % user-interface components. The output is a new layout object that
+ % can be used as the parent for other user-interface components.
+ %
+ % obj = uiextras.Grid(param,value,...) also sets one or more
+ % parameter values.
+ %
+ % See the documentation for more detail and the list of properties.
+ %
+ % Examples:
+ % >> f = figure();
+ % >> g = uiextras.Grid( 'Parent', f, 'Spacing', 5 );
+ % >> uicontrol( 'Style', 'frame', 'Parent', g, 'Background', 'r' )
+ % >> uicontrol( 'Style', 'frame', 'Parent', g, 'Background', 'b' )
+ % >> uicontrol( 'Style', 'frame', 'Parent', g, 'Background', 'g' )
+ % >> uiextras.Empty( 'Parent', g )
+ % >> uicontrol( 'Style', 'frame', 'Parent', g, 'Background', 'c' )
+ % >> uicontrol( 'Style', 'frame', 'Parent', g, 'Background', 'y' )
+ % >> set( g, 'ColumnSizes', [-1 100 -2], 'RowSizes', [-1 100] );
+ %
+ % See also: uiextras.GridFlex
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Hidden, Access = public, Dependent )
+ Enable % deprecated
+ RowSizes % heights of contents, in pixels and/or weights
+ MinimumRowSizes % minimum heights of contents, in pixels
+ ColumnSizes % widths of contents, in pixels and/or weights
+ MinimumColumnSizes % minimum widths of contents, in pixels
+ end
+
+ methods
+
+ function obj = Grid( varargin )
+
+ % Call uix constructor
+ obj@uix.Grid( varargin{:} )
+
+ % Auto-parent
+ if ~ismember( 'Parent', varargin(1:2:end) )
+ obj.Parent = gcf();
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = get.Enable( ~ )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ % Return
+ value = 'on';
+
+ end % get.Enable
+
+ function set.Enable( ~, value )
+
+ % Check
+ assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ...
+ 'uiextras:InvalidPropertyValue', ...
+ 'Property ''Enable'' must be ''on'' or ''off''.' )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ end % set.Enable
+
+ function value = get.RowSizes( obj )
+
+ % Get
+ value = obj.Heights;
+
+ end % get.RowSizes
+
+ function set.RowSizes( obj, value )
+
+ % Set
+ obj.Heights = value;
+
+ end % set.RowSizes
+
+ function value = get.MinimumRowSizes( obj )
+
+ % Get
+ value = obj.MinimumHeights;
+
+ end % get.MinimumRowSizes
+
+ function set.MinimumRowSizes( obj, value )
+
+ % Set
+ obj.MinimumHeights = value;
+
+ end % set.MinimumRowSizes
+
+ function value = get.ColumnSizes( obj )
+
+ % Get
+ value = obj.Widths;
+
+ end % get.ColumnSizes
+
+ function set.ColumnSizes( obj, value )
+
+ % Get
+ obj.Widths = value;
+
+ end % set.ColumnSizes
+
+ function value = get.MinimumColumnSizes( obj )
+
+ % Get
+ value = obj.MinimumWidths;
+
+ end % get.MinimumColumnSizes
+
+ function set.MinimumColumnSizes( obj, value )
+
+ % Get
+ obj.MinimumWidths = value;
+
+ end % set.MinimumColumnSizes
+
+ end % accessors
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/GridFlex.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/GridFlex.m
new file mode 100644
index 00000000..4d3bf7f0
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/GridFlex.m
@@ -0,0 +1,160 @@
+classdef GridFlex < uix.GridFlex
+ %uiextras.GridFlex Container with contents arranged in a resizable grid
+ %
+ % obj = uiextras.GridFlex() creates a new new grid layout with
+ % draggable dividers between elements. The number of rows and columns
+ % to use is determined from the number of elements in the RowSizes
+ % and ColumnSizes properties respectively. Child elements are
+ % arranged down column one first, then column two etc. If there are
+ % insufficient columns then a new one is added. The output is a new
+ % layout object that can be used as the parent for other
+ % user-interface components. The output is a new layout object that
+ % can be used as the parent for other user-interface components.
+ %
+ % obj = uiextras.GridFlex(param,value,...) also sets one or more
+ % parameter values.
+ %
+ % See the documentation for more detail and the list of properties.
+ %
+ % Examples:
+ % >> f = figure();
+ % >> g = uiextras.GridFlex( 'Parent', f, 'Spacing', 5 );
+ % >> uicontrol( 'Parent', g, 'Background', 'r' )
+ % >> uicontrol( 'Parent', g, 'Background', 'b' )
+ % >> uicontrol( 'Parent', g, 'Background', 'g' )
+ % >> uiextras.Empty( 'Parent', g )
+ % >> uicontrol( 'Parent', g, 'Background', 'c' )
+ % >> uicontrol( 'Parent', g, 'Background', 'y' )
+ % >> set( g, 'ColumnSizes', [-1 100 -2], 'RowSizes', [-1 -2] );
+ %
+ % See also: uiextras.Grid
+ % uiextras.HBoxFlex
+ % uiextras.VBoxFlex
+ % uiextras.Empty
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Hidden, Access = public, Dependent )
+ Enable % deprecated
+ RowSizes % heights of contents, in pixels and/or weights
+ MinimumRowSizes % minimum heights of contents, in pixels
+ ColumnSizes % widths of contents, in pixels and/or weights
+ MinimumColumnSizes % minimum widths of contents, in pixels
+ ShowMarkings
+ end
+
+ methods
+
+ function obj = GridFlex( varargin )
+
+ % Call uix constructor
+ obj@uix.GridFlex( varargin{:} )
+
+ % Auto-parent
+ if ~ismember( 'Parent', varargin(1:2:end) )
+ obj.Parent = gcf();
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = get.Enable( ~ )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ % Return
+ value = 'on';
+
+ end % get.Enable
+
+ function set.Enable( ~, value )
+
+ % Check
+ assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ...
+ 'uiextras:InvalidPropertyValue', ...
+ 'Property ''Enable'' must be ''on'' or ''off''.' )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ end % set.Enable
+
+ function value = get.RowSizes( obj )
+
+ % Get
+ value = obj.Heights;
+
+ end % get.RowSizes
+
+ function set.RowSizes( obj, value )
+
+ % Set
+ obj.Heights = value;
+
+ end % set.RowSizes
+
+ function value = get.MinimumRowSizes( obj )
+
+ % Get
+ value = obj.MinimumHeights;
+
+ end % get.MinimumRowSizes
+
+ function set.MinimumRowSizes( obj, value )
+
+ % Set
+ obj.MinimumHeights = value;
+
+ end % set.MinimumRowSizes
+
+ function value = get.ColumnSizes( obj )
+
+ % Get
+ value = obj.Widths;
+
+ end % get.ColumnSizes
+
+ function set.ColumnSizes( obj, value )
+
+ % Get
+ obj.Widths = value;
+
+ end % set.ColumnSizes
+
+ function value = get.MinimumColumnSizes( obj )
+
+ % Get
+ value = obj.MinimumWidths;
+
+ end % get.MinimumColumnSizes
+
+ function set.MinimumColumnSizes( obj, value )
+
+ % Get
+ obj.MinimumWidths = value;
+
+ end % set.MinimumColumnSizes
+
+ function value = get.ShowMarkings( obj )
+
+ % Get
+ value = obj.DividerMarkings;
+
+ end % get.ShowMarkings
+
+ function set.ShowMarkings( obj, value )
+
+ % Set
+ obj.DividerMarkings = value;
+
+ end % set.ShowMarkings
+
+ end % accessors
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/HBox.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/HBox.m
new file mode 100644
index 00000000..97f7d011
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/HBox.m
@@ -0,0 +1,113 @@
+classdef HBox < uix.HBox
+ %uiextras.HBox Arrange elements in a single horizontal row
+ %
+ % obj = uiextras.HBox() creates a new horizontal box layout with
+ % all parameters set to defaults. The output is a new layout object
+ % that can be used as the parent for other user-interface components.
+ %
+ % obj = uiextras.HBox(param,value,...) also sets one or more
+ % parameter values.
+ %
+ % See the documentation for more detail and the list of properties.
+ %
+ % Examples:
+ % >> f = figure();
+ % >> b = uiextras.HBox( 'Parent', f );
+ % >> uicontrol( 'Parent', b, 'Background', 'r' )
+ % >> uicontrol( 'Parent', b, 'Background', 'b' )
+ % >> uicontrol( 'Parent', b, 'Background', 'g' )
+ % >> set( b, 'Sizes', [-1 100 -2], 'Spacing', 5 );
+ %
+ % >> f = figure();
+ % >> b1 = uiextras.VBox( 'Parent', f );
+ % >> b2 = uiextras.HBox( 'Parent', b1, 'Padding', 5, 'Spacing', 5 );
+ % >> uicontrol( 'Style', 'frame', 'Parent', b1, 'Background', 'r' )
+ % >> uicontrol( 'Parent', b2, 'String', 'Button1' )
+ % >> uicontrol( 'Parent', b2, 'String', 'Button2' )
+ % >> set( b1, 'Sizes', [30 -1] );
+ %
+ % See also: uiextras.VBox
+ % uiextras.HBoxFlex
+ % uiextras.Grid
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Hidden, Access = public, Dependent )
+ Enable % deprecated
+ Sizes
+ MinimumSizes
+ end
+
+ methods
+
+ function obj = HBox( varargin )
+
+ % Call uix constructor
+ obj@uix.HBox( varargin{:} )
+
+ % Auto-parent
+ if ~ismember( 'Parent', varargin(1:2:end) )
+ obj.Parent = gcf();
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = get.Enable( ~ )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ % Return
+ value = 'on';
+
+ end % get.Enable
+
+ function set.Enable( ~, value )
+
+ % Check
+ assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ...
+ 'uiextras:InvalidPropertyValue', ...
+ 'Property ''Enable'' must be ''on'' or ''off''.' )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ end % set.Enable
+
+ function value = get.Sizes( obj )
+
+ % Get
+ value = transpose( obj.Widths );
+
+ end % get.Sizes
+
+ function set.Sizes( obj, value )
+
+ % Set
+ obj.Widths = value;
+
+ end % set.Sizes
+
+ function value = get.MinimumSizes( obj )
+
+ % Get
+ value = transpose( obj.MinimumWidths );
+
+ end % get.MinimumSizes
+
+ function set.MinimumSizes( obj, value )
+
+ % Get
+ obj.MinimumWidths = value;
+
+ end % set.MinimumSizes
+
+ end % accessors
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/HBoxFlex.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/HBoxFlex.m
new file mode 100644
index 00000000..d97fdeab
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/HBoxFlex.m
@@ -0,0 +1,122 @@
+classdef HBoxFlex < uix.HBoxFlex
+ %uiextras.HBoxFlex A dynamically resizable horizontal layout
+ %
+ % obj = uiextras.HBoxFlex() creates a new dynamically resizable
+ % horizontal box layout with all parameters set to defaults. The
+ % output is a new layout object that can be used as the parent for
+ % other user-interface components.
+ %
+ % obj = uiextras.HBoxFlex(param,value,...) also sets one or more
+ % parameter values.
+ %
+ % See the documentation for more detail and the list of properties.
+ %
+ % Examples:
+ % >> f = figure( 'Name', 'uiextras.HBoxFlex example' );
+ % >> b = uiextras.HBoxFlex( 'Parent', f );
+ % >> uicontrol( 'Parent', b, 'Background', 'r' )
+ % >> uicontrol( 'Parent', b, 'Background', 'b' )
+ % >> uicontrol( 'Parent', b, 'Background', 'g' )
+ % >> uicontrol( 'Parent', b, 'Background', 'y' )
+ % >> set( b, 'Sizes', [-1 100 -2 -1], 'Spacing', 5 );
+ %
+ % See also: uiextras.VBoxFlex
+ % uiextras.HBox
+ % uiextras.Grid
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Hidden, Access = public, Dependent )
+ Enable % deprecated
+ Sizes
+ MinimumSizes
+ ShowMarkings
+ end
+
+ methods
+
+ function obj = HBoxFlex( varargin )
+
+ % Call uix constructor
+ obj@uix.HBoxFlex( varargin{:} )
+
+ % Auto-parent
+ if ~ismember( 'Parent', varargin(1:2:end) )
+ obj.Parent = gcf();
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = get.Enable( ~ )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ % Return
+ value = 'on';
+
+ end % get.Enable
+
+ function set.Enable( ~, value )
+
+ % Check
+ assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ...
+ 'uiextras:InvalidPropertyValue', ...
+ 'Property ''Enable'' must be ''on'' or ''off''.' )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ end % set.Enable
+
+ function value = get.Sizes( obj )
+
+ % Get
+ value = transpose( obj.Widths );
+
+ end % get.Sizes
+
+ function set.Sizes( obj, value )
+
+ % Set
+ obj.Widths = value;
+
+ end % set.Sizes
+
+ function value = get.MinimumSizes( obj )
+
+ % Get
+ value = transpose( obj.MinimumWidths );
+
+ end % get.MinimumSizes
+
+ function set.MinimumSizes( obj, value )
+
+ % Get
+ obj.MinimumWidths = value;
+
+ end % set.MinimumSizes
+
+ function value = get.ShowMarkings( obj )
+
+ % Get
+ value = obj.DividerMarkings;
+
+ end % get.ShowMarkings
+
+ function set.ShowMarkings( obj, value )
+
+ % Set
+ obj.DividerMarkings = value;
+
+ end % set.ShowMarkings
+
+ end % accessors
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/HButtonBox.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/HButtonBox.m
new file mode 100644
index 00000000..270d1c09
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/HButtonBox.m
@@ -0,0 +1,45 @@
+classdef HButtonBox < uix.HButtonBox
+ %uiextras.HButtonBox Arrange buttons horizontally in a single row
+ %
+ % obj = uiextras.HButtonBox() is a type of HBox specialised for
+ % arranging a row of buttons, check-boxes or similar graphical
+ % elements. All buttons are given equal size and by default are
+ % centered in the drawing area. The justification can be changed as
+ % required.
+ %
+ % obj = uiextras.HButtonBox(param,value,...) also sets one or more
+ % parameter values.
+ %
+ % See the documentation for more detail and the list of properties.
+ %
+ % Examples:
+ % >> f = figure();
+ % >> b = uiextras.HButtonBox( 'Parent', f );
+ % >> uicontrol( 'Parent', b, 'String', 'One' );
+ % >> uicontrol( 'Parent', b, 'String', 'Two' );
+ % >> uicontrol( 'Parent', b, 'String', 'Three' );
+ % >> set( b, 'ButtonSize', [130 35], 'Spacing', 5 );
+ %
+ % See also: uiextras.VButtonBox
+ % uiextras.HBox
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ methods
+
+ function obj = HButtonBox( varargin )
+ %uiextras.HButtonBox Create a new horizontal button box
+
+ % Call uix constructor
+ obj@uix.HButtonBox( varargin{:} )
+
+ % Auto-parent
+ if ~ismember( 'Parent', varargin(1:2:end) )
+ obj.Parent = gcf();
+ end
+
+ end % constructor
+
+ end % structors
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/Panel.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/Panel.m
new file mode 100644
index 00000000..edf75cdc
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/Panel.m
@@ -0,0 +1,111 @@
+classdef Panel < uix.Panel
+ %uiextras.Panel Show one element inside a panel
+ %
+ % obj = uiextras.Panel() creates a standard UIPANEL object but with
+ % automatic management of the contained widget or layout. The
+ % properties available are largely the same as the builtin UIPANEL
+ % object. Where more than one child is added, the currently visible
+ % child is determined using the SelectedChild property.
+ %
+ % obj = uiextras.Panel(param,value,...) also sets one or more
+ % property values.
+ %
+ % See the documentation for more detail and the list of properties.
+ %
+ % Examples:
+ % >> f = figure();
+ % >> p = uiextras.Panel( 'Parent', f, 'Title', 'A Panel', 'Padding', 5 );
+ % >> uicontrol( 'Parent', p, 'Background', 'r' )
+ %
+ % >> f = figure();
+ % >> p = uiextras.Panel( 'Parent', f, 'Title', 'A Panel', 'Padding', 5 );
+ % >> b = uiextras.HBox( 'Parent', p, 'Spacing', 5 );
+ % >> uicontrol( 'Style', 'listbox', 'Parent', b, 'String', {'Item 1','Item 2'} );
+ % >> uicontrol( 'Parent', b, 'Background', 'b' );
+ % >> set( b, 'Sizes', [100 -1] );
+ %
+ % See also: uipanel
+ % uiextras.BoxPanel
+ % uiextras.HBox
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Hidden, Access = public, Dependent )
+ SelectedChild
+ end
+
+ methods
+
+ function obj = Panel( varargin )
+
+ % Call uix constructor
+ obj@uix.Panel( varargin{:} )
+
+ % Add Enable property
+ if ~isprop( obj, 'Enable' )
+ p = addprop( obj, 'Enable' );
+ p.GetMethod = @getEnable;
+ p.SetMethod = @setEnable;
+ end
+
+ % Auto-parent
+ if ~ismember( 'Parent', varargin(1:2:end) )
+ obj.Parent = gcf();
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = getEnable( ~ )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ % Return
+ value = 'on';
+
+ end % getEnable
+
+ function setEnable( ~, value )
+
+ % Check
+ assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ...
+ 'uiextras:InvalidPropertyValue', ...
+ 'Property ''Enable'' must be ''on'' or ''off''.' )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ end % setEnable
+
+ function value = get.SelectedChild( obj )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''SelectedChild'' will be removed in a future release.' )
+
+ % Get
+ if isempty( obj.Contents_ )
+ value = [];
+ else
+ value = 1;
+ end
+
+ end % get.SelectedChild
+
+ function set.SelectedChild( ~, ~ )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''SelectedChild'' will be removed in a future release.' )
+
+ end % set.SelectedChild
+
+ end % accessors
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/TabPanel.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/TabPanel.m
new file mode 100644
index 00000000..9ec22907
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/TabPanel.m
@@ -0,0 +1,223 @@
+classdef TabPanel < uix.TabPanel
+ %TabPanel Show one element inside a tabbed panel
+ %
+ % obj = uiextras.TabPanel() creates a panel with tabs along one edge
+ % to allow selection between the different child objects contained.
+ %
+ % obj = uiextras.TabPanel(param,value,...) also sets one or more
+ % property values.
+ %
+ % See the documentation for more detail and the list of properties.
+ %
+ % Examples:
+ % >> f = figure();
+ % >> p = uiextras.TabPanel( 'Parent', f, 'Padding', 5 );
+ % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'r' );
+ % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'b' );
+ % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'g' );
+ % >> p.TabNames = {'Red', 'Blue', 'Green'};
+ % >> p.SelectedChild = 2;
+ %
+ % See also: uiextras.Panel
+ % uiextras.BoxPanel
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Hidden, Access = public, Dependent )
+ Callback
+ end
+
+ properties( Access = private )
+ Callback_ = '' % backing for Callback
+ end
+
+ properties( Hidden, Access = public, Dependent )
+ Enable % deprecated
+ SelectedChild
+ TabEnable
+ TabNames
+ TabPosition
+ TabSize
+ end
+
+ properties( Access = private )
+ SelectionChangedListener % listener
+ end
+
+ methods
+
+ function obj = TabPanel( varargin )
+
+ % Call uix constructor
+ obj@uix.TabPanel( varargin{:} )
+
+ % Auto-parent
+ if ~ismember( 'Parent', varargin(1:2:end) )
+ obj.Parent = gcf();
+ end
+
+ % Create listeners
+ selectionChangedListener = event.listener( obj, ...
+ 'SelectionChanged', @obj.onSelectionChanged );
+
+ % Store properties
+ obj.SelectionChangedListener = selectionChangedListener;
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = get.Enable( ~ )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ % Return
+ value = 'on';
+
+ end % get.Enable
+
+ function set.Enable( ~, value )
+
+ % Check
+ assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ...
+ 'uiextras:InvalidPropertyValue', ...
+ 'Property ''Enable'' must be ''on'' or ''off''.' )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ end % set.Enable
+
+ function value = get.Callback( obj )
+
+ % Get
+ value = obj.Callback_;
+
+ end % get.Callback
+
+ function set.Callback( obj, value )
+
+ % Check
+ if ischar( value ) % string
+ % OK
+ elseif isa( value, 'function_handle' ) && ...
+ isequal( size( value ), [1 1] ) % function handle
+ % OK
+ elseif iscell( value ) && ndims( value ) == 2 && ...
+ size( value, 1 ) == 1 && size( value, 2 ) > 0 && ...
+ isa( value{1}, 'function_handle' ) && ...
+ isequal( size( value{1} ), [1 1] ) %#ok % cell callback
+ % OK
+ else
+ error( 'uiextras:InvalidPropertyValue', ...
+ 'Property ''Callback'' must be a valid callback.' )
+ end
+
+ % Set
+ obj.Callback_ = value;
+
+ end % set.Callback
+
+ function value = get.SelectedChild( obj )
+
+ % Get
+ value = obj.Selection;
+
+ end % get.SelectedChild
+
+ function set.SelectedChild( obj, value )
+
+ % Set
+ obj.Selection = value;
+
+ end % set.SelectedChild
+
+ function value = get.TabEnable( obj )
+
+ % Get
+ value = transpose( obj.TabEnables );
+
+ end % get.TabEnable
+
+ function set.TabEnable( obj, value )
+
+ % Set
+ obj.TabEnables = value;
+
+ end % set.TabEnable
+
+ function value = get.TabNames( obj )
+
+ % Get
+ value = transpose( obj.TabTitles );
+
+ end % get.TabNames
+
+ function set.TabNames( obj, value )
+
+ % Set
+ obj.TabTitles = value;
+
+ end % set.TabNames
+
+ function value = get.TabPosition( obj )
+
+ % Get
+ value = obj.TabLocation;
+
+ end % get.TabPosition
+
+ function set.TabPosition( obj, value )
+
+ % Set
+ obj.TabLocation = value;
+
+ end % set.TabPosition
+
+ function value = get.TabSize( obj )
+
+ % Get
+ value = obj.TabWidth;
+
+ end % get.TabSize
+
+ function set.TabSize( obj, value )
+
+ % Set
+ obj.TabWidth = value;
+
+ end % set.TabSize
+
+ end % accessors
+
+ methods( Access = private )
+
+ function onSelectionChanged( obj, source, eventData )
+
+ % Create legacy event data structure
+ oldEventData = struct( 'Source', eventData.Source, ...
+ 'PreviousChild', eventData.OldValue, ...
+ 'SelectedChild', eventData.NewValue );
+
+ % Call callback
+ callback = obj.Callback_;
+ if ischar( callback ) && isequal( callback, '' )
+ % do nothing
+ elseif ischar( callback )
+ feval( callback, source, oldEventData )
+ elseif isa( callback, 'function_handle' )
+ callback( source, oldEventData )
+ elseif iscell( callback )
+ feval( callback{1}, source, oldEventData, callback{2:end} )
+ end
+
+ end % onSelectionChanged
+
+ end % event handlers
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/VBox.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/VBox.m
new file mode 100644
index 00000000..281ba69b
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/VBox.m
@@ -0,0 +1,113 @@
+classdef VBox < uix.VBox
+ %uiextras.VBox Arrange elements vertically in a single column
+ %
+ % obj = uiextras.VBox() creates a new vertical box layout with all
+ % parameters set to defaults. The output is a new layout object that
+ % can be used as the parent for other user-interface components.
+ %
+ % obj = uiextras.VBox(param,value,...) also sets one or more
+ % parameter values.
+ %
+ % See the documentation for more detail and the list of properties.
+ %
+ % Examples:
+ % >> f = figure();
+ % >> b = uiextras.VBox( 'Parent', f );
+ % >> uicontrol( 'Parent', b, 'Background', 'r' )
+ % >> uicontrol( 'Parent', b, 'Background', 'b' )
+ % >> uicontrol( 'Parent', b, 'Background', 'g' )
+ % >> set( b, 'Sizes', [-1 100 -2], 'Spacing', 5 );
+ %
+ % >> f = figure();
+ % >> b1 = uiextras.VBox( 'Parent', f );
+ % >> b2 = uiextras.HBox( 'Parent', b1, 'Padding', 5, 'Spacing', 5 );
+ % >> uicontrol( 'Style', 'frame', 'Parent', b1, 'Background', 'r' )
+ % >> uicontrol( 'Parent', b2, 'String', 'Button1' )
+ % >> uicontrol( 'Parent', b2, 'String', 'Button2' )
+ % >> set( b1, 'Sizes', [30 -1] );
+ %
+ % See also: uiextras.HBox
+ % uiextras.VBoxFlex
+ % uiextras.Grid
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Hidden, Access = public, Dependent )
+ Enable % deprecated
+ Sizes
+ MinimumSizes
+ end
+
+ methods
+
+ function obj = VBox( varargin )
+
+ % Call uix constructor
+ obj@uix.VBox( varargin{:} )
+
+ % Auto-parent
+ if ~ismember( 'Parent', varargin(1:2:end) )
+ obj.Parent = gcf();
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = get.Enable( ~ )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ % Return
+ value = 'on';
+
+ end % get.Enable
+
+ function set.Enable( ~, value )
+
+ % Check
+ assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ...
+ 'uiextras:InvalidPropertyValue', ...
+ 'Property ''Enable'' must be ''on'' or ''off''.' )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ end % set.Enable
+
+ function value = get.Sizes( obj )
+
+ % Get
+ value = transpose( obj.Heights );
+
+ end % get.Sizes
+
+ function set.Sizes( obj, value )
+
+ % Set
+ obj.Heights = value;
+
+ end % set.Sizes
+
+ function value = get.MinimumSizes( obj )
+
+ % Get
+ value = transpose( obj.MinimumHeights );
+
+ end % get.MinimumSizes
+
+ function set.MinimumSizes( obj, value )
+
+ % Get
+ obj.MinimumHeights = value;
+
+ end % set.MinimumSizes
+
+ end % accessors
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/VBoxFlex.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/VBoxFlex.m
new file mode 100644
index 00000000..3cbe30d9
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/VBoxFlex.m
@@ -0,0 +1,122 @@
+classdef VBoxFlex < uix.VBoxFlex
+ %uiextras.VBoxFlex A dynamically resizable vertical layout
+ %
+ % obj = uiextras.VBoxFlex() creates a new dynamically resizable
+ % vertical box layout with all parameters set to defaults. The output
+ % is a new layout object that can be used as the parent for other
+ % user-interface components.
+ %
+ % obj = uiextras.VBoxFlex(param,value,...) also sets one or more
+ % parameter values.
+ %
+ % See the documentation for more detail and the list of properties.
+ %
+ % Examples:
+ % >> f = figure( 'Name', 'uiextras.VBoxFlex example' );
+ % >> b = uiextras.VBoxFlex( 'Parent', f );
+ % >> uicontrol( 'Parent', b, 'Background', 'r' )
+ % >> uicontrol( 'Parent', b, 'Background', 'b' )
+ % >> uicontrol( 'Parent', b, 'Background', 'g' )
+ % >> uicontrol( 'Parent', b, 'Background', 'y' )
+ % >> set( b, 'Sizes', [-1 100 -2 -1], 'Spacing', 5 );
+ %
+ % See also: uiextras.HBoxFlex
+ % uiextras.VBox
+ % uiextras.Grid
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Hidden, Access = public, Dependent )
+ Enable % deprecated
+ Sizes
+ MinimumSizes
+ ShowMarkings
+ end
+
+ methods
+
+ function obj = VBoxFlex( varargin )
+
+ % Call uix constructor
+ obj@uix.VBoxFlex( varargin{:} )
+
+ % Auto-parent
+ if ~ismember( 'Parent', varargin(1:2:end) )
+ obj.Parent = gcf();
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = get.Enable( ~ )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ % Return
+ value = 'on';
+
+ end % get.Enable
+
+ function set.Enable( ~, value )
+
+ % Check
+ assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ...
+ 'uiextras:InvalidPropertyValue', ...
+ 'Property ''Enable'' must be ''on'' or ''off''.' )
+
+ % Warn
+ % warning( 'uiextras:Deprecated', ...
+ % 'Property ''Enable'' will be removed in a future release.' )
+
+ end % set.Enable
+
+ function value = get.Sizes( obj )
+
+ % Get
+ value = transpose( obj.Heights );
+
+ end % get.Sizes
+
+ function set.Sizes( obj, value )
+
+ % Set
+ obj.Heights = value;
+
+ end % set.Sizes
+
+ function value = get.MinimumSizes( obj )
+
+ % Get
+ value = transpose( obj.MinimumHeights );
+
+ end % get.MinimumSizes
+
+ function set.MinimumSizes( obj, value )
+
+ % Get
+ obj.MinimumHeights = value;
+
+ end % set.MinimumSizes
+
+ function value = get.ShowMarkings( obj )
+
+ % Get
+ value = obj.DividerMarkings;
+
+ end % get.ShowMarkings
+
+ function set.ShowMarkings( obj, value )
+
+ % Set
+ obj.DividerMarkings = value;
+
+ end % set.ShowMarkings
+
+ end % accessors
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/VButtonBox.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/VButtonBox.m
new file mode 100644
index 00000000..478562ba
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/VButtonBox.m
@@ -0,0 +1,45 @@
+classdef VButtonBox < uix.VButtonBox
+ %uiextras.VButtonBox Arrange buttons vertically in a single column
+ %
+ % obj = uiextras.VButtonBox() is a type of VBox specialised for
+ % arranging a column of buttons, check-boxes or similar graphical
+ % elements. All buttons are given equal size and by default are
+ % centered in the drawing area. The justification can be changed as
+ % required.
+ %
+ % obj = uiextras.VButtonBox(param,value,...) also sets one or more
+ % parameter values.
+ %
+ % See the documentation for more detail and the list of properties.
+ %
+ % Examples:
+ % >> f = figure();
+ % >> b = uiextras.VButtonBox( 'Parent', f );
+ % >> uicontrol( 'Parent', b, 'String', 'One' );
+ % >> uicontrol( 'Parent', b, 'String', 'Two' );
+ % >> uicontrol( 'Parent', b, 'String', 'Three' );
+ % >> set( b, 'ButtonSize', [130 35], 'Spacing', 5 );
+ %
+ % See also: uiextras.HButtonBox
+ % uiextras.VBox
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ methods
+
+ function obj = VButtonBox( varargin )
+ %uiextras.VButtonBox Create a new horizontal button box
+
+ % Call uix constructor
+ obj@uix.VButtonBox( varargin{:} )
+
+ % Auto-parent
+ if ~ismember( 'Parent', varargin(1:2:end) )
+ obj.Parent = gcf();
+ end
+
+ end % constructor
+
+ end % structor
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/get.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/get.m
new file mode 100644
index 00000000..fa1abd99
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/get.m
@@ -0,0 +1,14 @@
+function varargout = get( ~, ~ ) %#ok
+%uiextras.get Retrieve a default property value from a parent object
+%
+% This functionality has been removed.
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+% Check inputs
+narginchk( 2, 2 )
+
+% Error
+error( 'uiextras:Deprecated', 'uiextras.get has been removed.' )
+
+end % uiextras.get
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/set.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/set.m
new file mode 100644
index 00000000..5e15f637
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/set.m
@@ -0,0 +1,14 @@
+function set( ~, ~, ~ )
+%uiextras.set Store a default property value in a parent object
+%
+% This functionality has been removed.
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+% Check inputs
+narginchk( 3, 3 )
+
+% Warn
+warning( 'uiextras:Deprecated', 'uiextras.set has been removed.' )
+
+end % uiextras.set
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/unset.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/unset.m
new file mode 100644
index 00000000..6ef522ca
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/unset.m
@@ -0,0 +1,14 @@
+function unset( ~, ~, ~ )
+%uiextras.unset Clear a default property value from a parent object
+%
+% This functionality has been removed.
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+% Check inputs
+narginchk( 2, 2 )
+
+% Warn
+warning( 'uiextras:Deprecated', 'uiextras.unset has been removed.' )
+
+end % uiextras.unset
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/+mixin/Container.m b/studio_functions/GUI Layout Toolbox/layout/+uix/+mixin/Container.m
new file mode 100644
index 00000000..02d9d3e3
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/+mixin/Container.m
@@ -0,0 +1,319 @@
+classdef Container < handle
+ %uix.mixin.Container Container mixin
+ %
+ % uix.mixin.Container is a mixin class used by containers to provide
+ % various properties and template methods.
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Dependent, Access = public )
+ Contents % contents in layout order
+ end
+
+ properties( Access = public, Dependent, AbortSet )
+ Padding % space around contents, in pixels
+ end
+
+ properties( Access = protected )
+ Contents_ = gobjects( [0 1] ) % backing for Contents
+ Padding_ = 0 % backing for Padding
+ end
+
+ properties( Dependent, Access = protected )
+ Dirty % needs redraw
+ end
+
+ properties( Access = private )
+ Dirty_ = false % backing for Dirty
+ FigureObserver % observer
+ FigureListener % listener
+ ChildObserver % observer
+ ChildAddedListener % listener
+ ChildRemovedListener % listener
+ SizeChangedListener % listener
+ ActivePositionPropertyListeners = cell( [0 1] ) % listeners
+ end
+
+ methods
+
+ function obj = Container()
+ %uix.mixin.Container Initialize
+ %
+ % c@uix.mixin.Container() initializes the container c.
+
+ % Create observers and listeners
+ figureObserver = uix.FigureObserver( obj );
+ figureListener = event.listener( figureObserver, ...
+ 'FigureChanged', @obj.onFigureChanged );
+ childObserver = uix.ChildObserver( obj );
+ childAddedListener = event.listener( ...
+ childObserver, 'ChildAdded', @obj.onChildAdded );
+ childRemovedListener = event.listener( ...
+ childObserver, 'ChildRemoved', @obj.onChildRemoved );
+ sizeChangedListener = event.listener( ...
+ obj, 'SizeChanged', @obj.onSizeChanged );
+
+ % Store observers and listeners
+ obj.FigureObserver = figureObserver;
+ obj.FigureListener = figureListener;
+ obj.ChildObserver = childObserver;
+ obj.ChildAddedListener = childAddedListener;
+ obj.ChildRemovedListener = childRemovedListener;
+ obj.SizeChangedListener = sizeChangedListener;
+
+ % Track usage
+ obj.track()
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = get.Contents( obj )
+
+ value = obj.Contents_;
+
+ end % get.Contents
+
+ function set.Contents( obj, value )
+
+ % For those who can't tell a column from a row...
+ if isrow( value )
+ value = transpose( value );
+ end
+
+ % Check
+ [tf, indices] = ismember( value, obj.Contents_ );
+ assert( isequal( size( obj.Contents_ ), size( value ) ) && ...
+ numel( value ) == numel( unique( value ) ) && all( tf ), ...
+ 'uix:InvalidOperation', ...
+ 'Property ''Contents'' may only be set to a permutation of itself.' )
+
+ % Call reorder
+ obj.reorder( indices )
+
+ end % set.Contents
+
+ function value = get.Padding( obj )
+
+ value = obj.Padding_;
+
+ end % get.Padding
+
+ function set.Padding( obj, value )
+
+ % Check
+ assert( isa( value, 'double' ) && isscalar( value ) && ...
+ isreal( value ) && ~isinf( value ) && ...
+ ~isnan( value ) && value >= 0, ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''Padding'' must be a non-negative scalar.' )
+
+ % Set
+ obj.Padding_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.Padding
+
+ function value = get.Dirty( obj )
+
+ value = obj.Dirty_;
+
+ end % get.Dirty
+
+ function set.Dirty( obj, value )
+
+ if value
+ if obj.isDrawable() % drawable
+ obj.redraw() % redraw now
+ else % not drawable
+ obj.Dirty_ = true; % flag for future redraw
+ end
+ end
+
+ end % set.Dirty
+
+ end % accessors
+
+ methods( Access = private, Sealed )
+
+ function onFigureChanged( obj, ~, eventData )
+ %onFigureChanged Event handler
+
+ % Call template method
+ obj.reparent( eventData.OldFigure, eventData.NewFigure )
+
+ % Redraw if possible and if dirty
+ if obj.Dirty_ && obj.isDrawable()
+ obj.redraw()
+ obj.Dirty_ = false;
+ end
+
+ end % onFigureChanged
+
+ function onChildAdded( obj, ~, eventData )
+ %onChildAdded Event handler
+
+ % Do nothing if add is internal tree surgery
+ if isTreeSurgery( eventData.Child ), return, end
+
+ % Call template method
+ obj.addChild( eventData.Child )
+
+ end % onChildAdded
+
+ function onChildRemoved( obj, ~, eventData )
+ %onChildRemoved Event handler
+
+ % Do nothing if container is being deleted
+ if strcmp( obj.BeingDeleted, 'on' ), return, end
+
+ % Do nothing if remove is internal tree surgery
+ if isTreeSurgery( eventData.Child ), return, end
+
+ % Call template method
+ obj.removeChild( eventData.Child )
+
+ end % onChildRemoved
+
+ function onSizeChanged( obj, ~, ~ )
+ %onSizeChanged Event handler
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % onSizeChanged
+
+ function onActivePositionPropertyChanged( obj, ~, ~ )
+ %onActivePositionPropertyChanged Event handler
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % onActivePositionPropertyChanged
+
+ end % event handlers
+
+ methods( Abstract, Access = protected )
+
+ redraw( obj )
+
+ end % abstract template methods
+
+ methods( Access = protected )
+
+ function addChild( obj, child )
+ %addChild Add child
+ %
+ % c.addChild(d) adds the child d to the container c.
+
+ % Add to contents
+ obj.Contents_(end+1,:) = child;
+
+ % Add listeners
+ if isa( child, 'matlab.graphics.axis.Axes' )
+ obj.ActivePositionPropertyListeners{end+1,:} = ...
+ event.proplistener( child, ...
+ findprop( child, 'ActivePositionProperty' ), ...
+ 'PostSet', @obj.onActivePositionPropertyChanged );
+ else
+ obj.ActivePositionPropertyListeners{end+1,:} = [];
+ end
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % addChild
+
+ function removeChild( obj, child )
+ %removeChild Remove child
+ %
+ % c.removeChild(d) removes the child d from the container c.
+
+ % Remove from contents
+ contents = obj.Contents_;
+ tf = contents == child;
+ obj.Contents_(tf,:) = [];
+
+ % Remove listeners
+ obj.ActivePositionPropertyListeners(tf,:) = [];
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % removeChild
+
+ function reparent( obj, oldFigure, newFigure ) %#ok
+ %reparent Reparent container
+ %
+ % c.reparent(a,b) reparents the container c from the figure a
+ % to the figure b.
+
+ end % reparent
+
+ function reorder( obj, indices )
+ %reorder Reorder contents
+ %
+ % c.reorder(i) reorders the container contents using indices
+ % i, c.Contents = c.Contents(i).
+
+ % Reorder contents
+ obj.Contents_ = obj.Contents_(indices,:);
+
+ % Reorder listeners
+ obj.ActivePositionPropertyListeners = ...
+ obj.ActivePositionPropertyListeners(indices,:);
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % reorder
+
+ function tf = isDrawable( obj )
+ %isDrawable Test for drawability
+ %
+ % c.isDrawable() is true if the container c is drawable, and
+ % false otherwise. To be drawable, a container must be
+ % rooted.
+
+ tf = ~isempty( obj.FigureObserver.Figure );
+
+ end % isDrawable
+
+ function track( obj )
+ %track Track usage
+
+ persistent TRACKED % single shot
+ if isempty( TRACKED )
+ v = ver( 'layout' );
+ try %#ok
+ uix.tracking( 'UA-82270656-2', v(1).Version, class( obj ) )
+ end
+ TRACKED = true;
+ end
+
+ end % track
+
+ end % template methods
+
+end % classdef
+
+function tf = isTreeSurgery( child )
+%isTreeSurgery Test for internal tree surgery
+%
+% Certain internal operations perform tree surgery, removing a child
+% temporarily and adding it back under an additional node.
+
+if ~isa( child, 'matlab.graphics.axis.Axes' ) % only certain types
+ tf = false;
+elseif verLessThan( 'MATLAB', '9.5' ) % only certain versions
+ tf = false;
+else % check stack
+ s = dbstack();
+ tf = any( strcmp( 'ScribeStackManager.createLayer', {s.name} ) );
+end
+
+end % isTreeSurgery
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/+mixin/Flex.m b/studio_functions/GUI Layout Toolbox/layout/+uix/+mixin/Flex.m
new file mode 100644
index 00000000..09f0fe3e
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/+mixin/Flex.m
@@ -0,0 +1,70 @@
+classdef Flex < handle
+ %uix.mixin.Flex Flex mixin
+ %
+ % uix.mixin.Flex is a mixin class used by flex containers to provide
+ % various properties and helper methods.
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( GetAccess = protected, SetAccess = private )
+ Pointer = 'unset' % mouse pointer
+ end
+
+ properties( Access = private )
+ Figure = gobjects( 0 ); % mouse pointer figure
+ Token = -1 % mouse pointer token
+ end
+
+ methods
+
+ function delete( obj )
+ %delete Destructor
+
+ % Clean up
+ if ~strcmp( obj.Pointer, 'unset' )
+ obj.unsetPointer()
+ end
+
+ end % destructor
+
+ end % structors
+
+ methods( Access = protected )
+
+ function setPointer( obj, figure, pointer )
+ %setPointer Set pointer
+ %
+ % c.setPointer(f,p) sets the pointer for the figure f to p.
+
+ % If set, unset
+ if obj.Token ~= -1
+ obj.unsetPointer()
+ end
+
+ % Set
+ obj.Token = uix.PointerManager.setPointer( figure, pointer );
+ obj.Figure = figure;
+ obj.Pointer = pointer;
+
+ end % setPointer
+
+ function unsetPointer( obj )
+ %unsetPointer Unset pointer
+ %
+ % c.unsetPointer() undoes the previous pointer set.
+
+ % Check
+ assert( obj.Token ~= -1, 'uix:InvalidOperation', ...
+ 'Pointer is already unset.' )
+
+ % Unset
+ uix.PointerManager.unsetPointer( obj.Figure, obj.Token );
+ obj.Figure = gobjects( 0 );
+ obj.Pointer = 'unset';
+ obj.Token = -1;
+
+ end % unsetPointer
+
+ end % helper methods
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/+mixin/Panel.m b/studio_functions/GUI Layout Toolbox/layout/+uix/+mixin/Panel.m
new file mode 100644
index 00000000..ec718124
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/+mixin/Panel.m
@@ -0,0 +1,187 @@
+classdef Panel < uix.mixin.Container
+ %uix.mixin.Panel Panel mixin
+ %
+ % uix.mixin.Panel is a mixin class used by panels to provide various
+ % properties and template methods.
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Access = public, Dependent, AbortSet )
+ Selection % selected contents
+ end
+
+ properties( Access = protected )
+ Selection_ = 0 % backing for Selection
+ end
+
+ properties( Access = protected )
+ G1218142 = false % bug flag
+ end
+
+ events( NotifyAccess = protected )
+ SelectionChanged % selection changed
+ end
+
+ methods
+
+ function value = get.Selection( obj )
+
+ value = obj.Selection_;
+
+ end % get.Selection
+
+ function set.Selection( obj, value )
+
+ % Check
+ assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ...
+ 'Property ''Selection'' must be of type double.' )
+ assert( isequal( size( value ), [1 1] ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''Selection'' must be scalar.' )
+ assert( isreal( value ) && rem( value, 1 ) == 0, ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''Selection'' must be an integer.' )
+ n = numel( obj.Contents_ );
+ if n == 0
+ assert( value == 0, 'uix:InvalidPropertyValue', ...
+ 'Property ''Selection'' must be 0 for a container with no children.' )
+ else
+ assert( value >= 1 && value <= n, 'uix:InvalidPropertyValue', ...
+ 'Property ''Selection'' must be between 1 and the number of children.' )
+ end
+
+ % Set
+ oldSelection = obj.Selection_;
+ newSelection = value;
+ obj.Selection_ = newSelection;
+
+ % Show selected child
+ obj.showSelection()
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ % Raise event
+ notify( obj, 'SelectionChanged', ...
+ uix.SelectionData( oldSelection, newSelection ) )
+
+ end % set.Selection
+
+ end % accessors
+
+ methods( Access = protected )
+
+ function addChild( obj, child )
+
+ % Check for bug
+ if verLessThan( 'MATLAB', '8.5' ) && strcmp( child.Visible, 'off' )
+ obj.G1218142 = true;
+ end
+
+ % Select new content
+ oldSelection = obj.Selection_;
+ newSelection = numel( obj.Contents_ ) + 1;
+ obj.Selection_ = newSelection;
+
+ % Call superclass method
+ addChild@uix.mixin.Container( obj, child )
+
+ % Show selected child
+ obj.showSelection()
+
+ % Notify selection change
+ obj.notify( 'SelectionChanged', ...
+ uix.SelectionData( oldSelection, newSelection ) )
+
+ end % addChild
+
+ function removeChild( obj, child )
+
+ % Adjust selection if required
+ contents = obj.Contents_;
+ index = find( contents == child );
+ oldSelection = obj.Selection_;
+ if index < oldSelection
+ newSelection = oldSelection - 1;
+ elseif index == oldSelection
+ newSelection = min( oldSelection, numel( contents ) - 1 );
+ else % index > oldSelection
+ newSelection = oldSelection;
+ end
+ obj.Selection_ = newSelection;
+
+ % Call superclass method
+ removeChild@uix.mixin.Container( obj, child )
+
+ % Show selected child
+ obj.showSelection()
+
+ % Notify selection change
+ if oldSelection ~= newSelection
+ obj.notify( 'SelectionChanged', ...
+ uix.SelectionData( oldSelection, newSelection ) )
+ end
+
+ end % removeChild
+
+ function reorder( obj, indices )
+ %reorder Reorder contents
+ %
+ % c.reorder(i) reorders the container contents using indices
+ % i, c.Contents = c.Contents(i).
+
+ % Reorder
+ selection = obj.Selection_;
+ if selection ~= 0
+ obj.Selection_ = find( indices == selection );
+ end
+
+ % Call superclass method
+ reorder@uix.mixin.Container( obj, indices )
+
+ end % reorder
+
+ function showSelection( obj )
+ %showSelection Show selected child, hide the others
+ %
+ % c.showSelection() shows the selected child of the container
+ % c, and hides the others.
+
+ % Set positions and visibility
+ selection = obj.Selection_;
+ children = obj.Contents_;
+ for ii = 1:numel( children )
+ child = children(ii);
+ if ii == selection
+ if obj.G1218142
+ warning( 'uix:G1218142', ...
+ 'Selected child of %s is not visible due to bug G1218142. The child will become visible at the next redraw.', ...
+ class( obj ) )
+ obj.G1218142 = false;
+ else
+ child.Visible = 'on';
+ end
+ if isa( child, 'matlab.graphics.axis.Axes' )
+ child.ContentsVisible = 'on';
+ end
+ else
+ child.Visible = 'off';
+ if isa( child, 'matlab.graphics.axis.Axes' )
+ child.ContentsVisible = 'off';
+ end
+ % As a remedy for g1100294, move off-screen too
+ margin = 1000;
+ if isa( child, 'matlab.graphics.axis.Axes' ) ...
+ && strcmp(child.ActivePositionProperty, 'outerposition' )
+ child.OuterPosition(1) = -child.OuterPosition(3)-margin;
+ else
+ child.Position(1) = -child.Position(3)-margin;
+ end
+ end
+ end
+
+ end % showSelection
+
+ end % template methods
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Box.m b/studio_functions/GUI Layout Toolbox/layout/+uix/Box.m
new file mode 100644
index 00000000..b06c3cf6
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/Box.m
@@ -0,0 +1,44 @@
+classdef Box < uix.Container & uix.mixin.Container
+ %uix.Box Box and grid base class
+ %
+ % uix.Box is a base class for containers with spacing between
+ % contents.
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Access = public, Dependent, AbortSet )
+ Spacing = 0 % space between contents, in pixels
+ end
+
+ properties( Access = protected )
+ Spacing_ = 0 % backing for Spacing
+ end
+
+ methods
+
+ function value = get.Spacing( obj )
+
+ value = obj.Spacing_;
+
+ end % get.Spacing
+
+ function set.Spacing( obj, value )
+
+ % Check
+ assert( isa( value, 'double' ) && isscalar( value ) && ...
+ isreal( value ) && ~isinf( value ) && ...
+ ~isnan( value ) && value >= 0, ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''Spacing'' must be a non-negative scalar.' )
+
+ % Set
+ obj.Spacing_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.Spacing
+
+ end % accessors
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/BoxPanel.m b/studio_functions/GUI Layout Toolbox/layout/+uix/BoxPanel.m
new file mode 100644
index 00000000..6e8e0254
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/BoxPanel.m
@@ -0,0 +1,646 @@
+classdef BoxPanel < uix.Panel & uix.mixin.Panel
+ %uix.BoxPanel Box panel
+ %
+ % p = uix.BoxPanel(p1,v1,p2,v2,...) constructs a box panel and sets
+ % parameter p1 to value v1, etc.
+ %
+ % A box panel is a decorated container with a title box, border, and
+ % buttons to dock and undock, minimize, get help, and close. A box
+ % panel shows one of its contents and hides the others.
+ %
+ % See also: uix.Panel, uipanel, uix.CardPanel
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Dependent )
+ TitleColor % title background color [RGB]
+ Minimized % minimized [true|false]
+ MinimizeFcn % minimize callback
+ Docked % docked [true|false]
+ DockFcn % dock callback
+ HelpFcn % help callback
+ CloseRequestFcn % close request callback
+ end
+
+ properties( Dependent, SetAccess = private )
+ TitleHeight % title panel height [pixels]
+ end
+
+ properties( Access = private )
+ TitleBox % title bar box
+ TitleText % title text label
+ EmptyTitle = '' % title when empty, [] otherwise
+ TitleAccess = 'public' % 'private' when getting or setting Title, 'public' otherwise
+ TitleHeight_ = -1 % cache of title text height (-1 denotes stale cache)
+ MinimizeButton % title button
+ DockButton % title button
+ HelpButton % title button
+ CloseButton % title button
+ Docked_ = true % backing for Docked
+ Minimized_ = false % backing for Minimized
+ end
+
+ properties( Constant, Access = private )
+ NullTitle = char.empty( [2 0] ) % an obscure empty string, the actual panel Title
+ BlankTitle = ' ' % a non-empty blank string, the empty uicontrol String
+ end
+
+ properties
+ MaximizeTooltipString = 'Expand this panel' % tooltip string
+ MinimizeTooltipString = 'Collapse this panel' % tooltip string
+ UndockTooltipString = 'Undock this panel' % tooltip string
+ DockTooltipString = 'Dock this panel' % tooltip string
+ HelpTooltipString = 'Get help on this panel' % tooltip string
+ CloseTooltipString = 'Close this panel' % tooltip string
+ end
+
+ methods
+
+ function obj = BoxPanel( varargin )
+ %uix.BoxPanel Box panel constructor
+ %
+ % p = uix.BoxPanel() constructs a box panel.
+ %
+ % p = uix.BoxPanel(p1,v1,p2,v2,...) sets parameter p1 to value
+ % v1, etc.
+
+ % Define default colors
+ foregroundColor = [1 1 1];
+ backgroundColor = [0.05 0.25 0.5];
+
+ % Set default colors
+ obj.ForegroundColor = foregroundColor;
+
+ % Create panels and decorations
+ titleBox = uix.HBox( 'Internal', true, 'Parent', obj, ...
+ 'Units', 'pixels', 'BackgroundColor', backgroundColor );
+ titleText = uix.Text( 'Parent', titleBox, ...
+ 'ForegroundColor', foregroundColor, ...
+ 'BackgroundColor', backgroundColor, ...
+ 'String', obj.BlankTitle, 'HorizontalAlignment', 'left' );
+
+ % Create buttons
+ minimizeButton = uix.Text( ...
+ 'ForegroundColor', foregroundColor, ...
+ 'BackgroundColor', backgroundColor, ...
+ 'FontWeight', 'bold', 'Enable', 'on' );
+ dockButton = uix.Text( ...
+ 'ForegroundColor', foregroundColor, ...
+ 'BackgroundColor', backgroundColor, ...
+ 'FontWeight', 'bold', 'Enable', 'on' );
+ helpButton = uix.Text( ...
+ 'ForegroundColor', foregroundColor, ...
+ 'BackgroundColor', backgroundColor, ...
+ 'FontWeight', 'bold', 'String', '?', ...
+ 'TooltipString', obj.HelpTooltipString, 'Enable', 'on' );
+ closeButton = uix.Text( ...
+ 'ForegroundColor', foregroundColor, ...
+ 'BackgroundColor', backgroundColor, ...
+ 'FontWeight', 'bold', 'String', char( 215 ), ...
+ 'TooltipString', obj.CloseTooltipString, 'Enable', 'on' );
+
+ % Store properties
+ obj.Title = obj.NullTitle;
+ obj.TitleBox = titleBox;
+ obj.TitleText = titleText;
+ obj.MinimizeButton = minimizeButton;
+ obj.DockButton = dockButton;
+ obj.HelpButton = helpButton;
+ obj.CloseButton = closeButton;
+
+ % Create listeners
+ addlistener( obj, 'BorderWidth', 'PostSet', ...
+ @obj.onBorderWidthChanged );
+ addlistener( obj, 'BorderType', 'PostSet', ...
+ @obj.onBorderTypeChanged );
+ addlistener( obj, 'FontAngle', 'PostSet', ...
+ @obj.onFontAngleChanged );
+ addlistener( obj, 'FontName', 'PostSet', ...
+ @obj.onFontNameChanged );
+ addlistener( obj, 'FontSize', 'PostSet', ...
+ @obj.onFontSizeChanged );
+ addlistener( obj, 'FontUnits', 'PostSet', ...
+ @obj.onFontUnitsChanged );
+ addlistener( obj, 'FontWeight', 'PostSet', ...
+ @obj.onFontWeightChanged );
+ addlistener( obj, 'ForegroundColor', 'PostSet', ...
+ @obj.onForegroundColorChanged );
+ addlistener( obj, 'Title', 'PreGet', ...
+ @obj.onTitleReturning );
+ addlistener( obj, 'Title', 'PostGet', ...
+ @obj.onTitleReturned );
+ addlistener( obj, 'Title', 'PostSet', ...
+ @obj.onTitleChanged );
+
+ % Draw buttons
+ obj.redrawButtons()
+
+ % Set properties
+ try
+ uix.set( obj, varargin{:} )
+ catch e
+ delete( obj )
+ e.throwAsCaller()
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = get.TitleColor( obj )
+
+ value = obj.TitleBox.BackgroundColor;
+
+ end % get.TitleColor
+
+ function set.TitleColor( obj, value )
+
+ % Set
+ obj.TitleBox.BackgroundColor = value;
+ obj.TitleText.BackgroundColor = value;
+ obj.MinimizeButton.BackgroundColor = value;
+ obj.DockButton.BackgroundColor = value;
+ obj.HelpButton.BackgroundColor = value;
+ obj.CloseButton.BackgroundColor = value;
+
+ end % set.TitleColor
+
+ function value = get.CloseRequestFcn( obj )
+
+ value = obj.CloseButton.Callback;
+
+ end % get.CloseRequestFcn
+
+ function set.CloseRequestFcn( obj, value )
+
+ % Set
+ obj.CloseButton.Callback = value;
+
+ % Mark as dirty
+ obj.redrawButtons()
+
+ end % set.CloseRequestFcn
+
+ function value = get.DockFcn( obj )
+
+ value = obj.DockButton.Callback;
+
+ end % get.DockFcn
+
+ function set.DockFcn( obj, value )
+
+ % Set
+ obj.DockButton.Callback = value;
+
+ % Mark as dirty
+ obj.redrawButtons()
+
+ end % set.DockFcn
+
+ function value = get.HelpFcn( obj )
+
+ value = obj.HelpButton.Callback;
+
+ end % get.HelpFcn
+
+ function set.HelpFcn( obj, value )
+
+ % Set
+ obj.HelpButton.Callback = value;
+
+ % Mark as dirty
+ obj.redrawButtons()
+
+ end % set.HelpFcn
+
+ function value = get.MinimizeFcn( obj )
+
+ value = obj.MinimizeButton.Callback;
+
+ end % get.MinimizeFcn
+
+ function set.MinimizeFcn( obj, value )
+
+ % Set
+ obj.MinimizeButton.Callback = value;
+ obj.TitleText.Callback = value;
+ if isempty( value )
+ obj.TitleText.Enable = 'inactive';
+ else
+ obj.TitleText.Enable = 'on';
+ end
+
+ % Mark as dirty
+ obj.redrawButtons()
+
+ end % set.MinimizeFcn
+
+ function value = get.Docked( obj )
+
+ value = obj.Docked_;
+
+ end % get.Docked
+
+ function set.Docked( obj, value )
+
+ % Check
+ assert( islogical( value ) && isequal( size( value ), [1 1] ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''Docked'' must be true or false.' )
+
+ % Set
+ obj.Docked_ = value;
+
+ % Mark as dirty
+ obj.redrawButtons()
+
+ end % set.Docked
+
+ function value = get.Minimized( obj )
+
+ value = obj.Minimized_;
+
+ end % get.Minimized
+
+ function set.Minimized( obj, value )
+
+ % Check
+ assert( islogical( value ) && isequal( size( value ), [1 1] ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''Minimized'' must be true or false.' )
+
+ % Set
+ obj.Minimized_ = value;
+
+ % Show selected child
+ obj.showSelection()
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.Minimized
+
+ function value = get.TitleHeight( obj )
+
+ value = obj.TitleBox.Position(4);
+
+ end % get.TitleHeight
+
+ function set.MaximizeTooltipString( obj, value )
+
+ % Check
+ assert( ischar( value ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''MaximizeTooltipString'' must be a string.' )
+
+ % Set
+ obj.MaximizeTooltipString = value;
+
+ % Mark as dirty
+ obj.redrawButtons()
+
+ end % set.MaximizeTooltipString
+
+ function set.MinimizeTooltipString( obj, value )
+
+ % Check
+ assert( ischar( value ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''MinimizeTooltipString'' must be a string.' )
+
+ % Set
+ obj.MinimizeTooltipString = value;
+
+ % Mark as dirty
+ obj.redrawButtons()
+
+ end % set.MinimizeTooltipString
+
+ function set.UndockTooltipString( obj, value )
+
+ % Check
+ assert( ischar( value ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''UndockTooltipString'' must be a string.' )
+
+ % Set
+ obj.UndockTooltipString = value;
+
+ % Mark as dirty
+ obj.redrawButtons()
+
+ end % set.UndockTooltipString
+
+ function set.DockTooltipString( obj, value )
+
+ % Check
+ assert( ischar( value ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''DockTooltipString'' must be a string.' )
+
+ % Set
+ obj.DockTooltipString = value;
+
+ % Mark as dirty
+ obj.redrawButtons()
+
+ end % set.DockTooltipString
+
+ function set.HelpTooltipString( obj, value )
+
+ % Check
+ assert( ischar( value ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''HelpTooltipString'' must be a string.' )
+
+ % Set
+ obj.HelpTooltipString = value;
+
+ % Mark as dirty
+ obj.redrawButtons()
+
+ end % set.HelpTooltipString
+
+ function set.CloseTooltipString( obj, value )
+
+ % assert that value is a char array
+ assert( ischar( value ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''CloseTooltipString'' must be a string.' )
+
+ obj.CloseTooltipString = value;
+
+ % Mark as dirty
+ obj.redrawButtons()
+
+ end % set.CloseTooltipString
+
+ end % accessors
+
+ methods( Access = private )
+
+ function onBorderWidthChanged( obj, ~, ~ )
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % onBorderWidthChanged
+
+ function onBorderTypeChanged( obj, ~, ~ )
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % onBorderTypeChanged
+
+ function onFontAngleChanged( obj, ~, ~ )
+
+ obj.TitleText.FontAngle = obj.FontAngle;
+
+ end % onFontAngleChanged
+
+ function onFontNameChanged( obj, ~, ~ )
+
+ % Set
+ obj.TitleText.FontName = obj.FontName;
+
+ % Mark as dirty
+ obj.TitleHeight_ = -1;
+ obj.Dirty = true;
+
+ end % onFontNameChanged
+
+ function onFontSizeChanged( obj, ~, ~ )
+
+ % Set
+ fontSize = obj.FontSize;
+ obj.TitleText.FontSize = fontSize;
+ obj.HelpButton.FontSize = fontSize;
+ obj.CloseButton.FontSize = fontSize;
+ obj.DockButton.FontSize = fontSize;
+ obj.MinimizeButton.FontSize = fontSize;
+
+ % Mark as dirty
+ obj.TitleHeight_ = -1;
+ obj.Dirty = true;
+
+ end % onFontSizeChanged
+
+ function onFontUnitsChanged( obj, ~, ~ )
+
+ fontUnits = obj.FontUnits;
+ obj.TitleText.FontUnits = fontUnits;
+ obj.HelpButton.FontUnits = fontUnits;
+ obj.CloseButton.FontUnits = fontUnits;
+ obj.DockButton.FontUnits = fontUnits;
+ obj.MinimizeButton.FontUnits = fontUnits;
+
+ end % onFontUnitsChanged
+
+ function onFontWeightChanged( obj, ~, ~ )
+
+ obj.TitleText.FontWeight = obj.FontWeight;
+
+ end % onFontWeightChanged
+
+ function onForegroundColorChanged( obj, ~, ~ )
+
+ foregroundColor = obj.ForegroundColor;
+ obj.TitleText.ForegroundColor = foregroundColor;
+ obj.MinimizeButton.ForegroundColor = foregroundColor;
+ obj.DockButton.ForegroundColor = foregroundColor;
+ obj.HelpButton.ForegroundColor = foregroundColor;
+ obj.CloseButton.ForegroundColor = foregroundColor;
+
+ end % onForegroundColorChanged
+
+ function onTitleReturning( obj, ~, ~ )
+
+ if strcmp( obj.TitleAccess, 'public' )
+
+ obj.TitleAccess = 'private'; % start
+ if ischar( obj.EmptyTitle )
+ obj.Title = obj.EmptyTitle;
+ else
+ obj.Title = obj.TitleText.String;
+ end
+
+ end
+
+ end % onTitleReturning
+
+ function onTitleReturned( obj, ~, ~ )
+
+ obj.Title = obj.NullTitle; % unset Title
+ obj.TitleAccess = 'public'; % finish
+
+ end % onTitleReturned
+
+ function onTitleChanged( obj, ~, ~ )
+
+ if strcmp( obj.TitleAccess, 'public' )
+
+ % Set
+ obj.TitleAccess = 'private'; % start
+ title = obj.Title;
+ if isempty( title )
+ obj.EmptyTitle = title; % store
+ obj.TitleText.String = obj.BlankTitle; % set String to blank
+ else
+ obj.EmptyTitle = []; % not empty
+ obj.TitleText.String = title; % set String to title
+ end
+ obj.Title = obj.NullTitle; % unset Title
+ obj.TitleAccess = 'public'; % finish
+
+ % Mark as dirty
+ obj.TitleHeight_ = -1;
+ obj.Dirty = true;
+
+ end
+
+ end % onTitleChanged
+
+ end % property event handlers
+
+ methods( Access = protected )
+
+ function redraw( obj )
+ %redraw Redraw
+ %
+ % p.redraw() redraws the panel.
+ %
+ % See also: redrawButtons
+
+ % Compute positions
+ bounds = hgconvertunits( ancestor( obj, 'figure' ), ...
+ [0 0 1 1], 'normalized', 'pixels', obj );
+ tX = 1;
+ tW = max( bounds(3), 1 );
+ tH = obj.TitleHeight_; % title height
+ if tH == -1 % cache stale, refresh
+ tH = ceil( obj.TitleText.Extent(4) );
+ obj.TitleHeight_ = tH; % store
+ end
+ tY = 1 + bounds(4) - tH;
+ p = obj.Padding_;
+ cX = 1 + p;
+ cW = max( bounds(3) - 2 * p, 1 );
+ cH = max( bounds(4) - tH - 2 * p, 1 );
+ cY = tY - p - cH;
+ contentsPosition = [cX cY cW cH];
+
+ % Redraw contents
+ selection = obj.Selection_;
+ if selection ~= 0
+ uix.setPosition( obj.Contents_(selection), contentsPosition, 'pixels' )
+ end
+ obj.TitleBox.Position = [tX tY tW tH];
+ obj.redrawButtons()
+
+ end % redraw
+
+ function showSelection( obj )
+ %showSelection Show selected child, hide the others
+ %
+ % c.showSelection() shows the selected child of the container
+ % c, and hides the others.
+
+ % Call superclass method
+ showSelection@uix.mixin.Panel( obj )
+
+ % If minimized, hide selected contents too
+ selection = obj.Selection_;
+ if selection ~= 0 && obj.Minimized_
+ child = obj.Contents_(selection);
+ child.Visible = 'off';
+ if isa( child, 'matlab.graphics.axis.Axes' )
+ child.ContentsVisible = 'off';
+ end
+ % As a remedy for g1100294, move off-screen too
+ margin = 1000;
+ if isa( child, 'matlab.graphics.axis.Axes' ) ...
+ && strcmp(child.ActivePositionProperty, 'outerposition' )
+ child.OuterPosition(1) = -child.OuterPosition(3)-margin;
+ else
+ child.Position(1) = -child.Position(3)-margin;
+ end
+ end
+
+ end % showSelection
+
+ end % template methods
+
+ methods( Access = private )
+
+ function redrawButtons( obj )
+ %redrawButtons Redraw buttons
+ %
+ % p.redrawButtons() redraws the titlebar buttons.
+ %
+ % Buttons use unicode arrow symbols:
+ % https://en.wikipedia.org/wiki/Arrow_%28symbol%29#Arrows_in_Unicode
+
+ % Retrieve button box and buttons
+ box = obj.TitleBox;
+ titleText = obj.TitleText;
+ minimizeButton = obj.MinimizeButton;
+ dockButton = obj.DockButton;
+ helpButton = obj.HelpButton;
+ closeButton = obj.CloseButton;
+
+ % Detach all buttons
+ titleText.Parent = [];
+ minimizeButton.Parent = [];
+ dockButton.Parent = [];
+ helpButton.Parent = [];
+ closeButton.Parent = [];
+
+ % Attach active buttons
+ titleText.Parent = box;
+ minimize = ~isempty( obj.MinimizeFcn );
+ if minimize
+ minimizeButton.Parent = box;
+ box.Widths(end) = minimizeButton.Extent(3);
+ end
+ dock = ~isempty( obj.DockFcn );
+ if dock
+ dockButton.Parent = box;
+ box.Widths(end) = dockButton.Extent(3);
+ end
+ help = ~isempty( obj.HelpFcn );
+ if help
+ helpButton.Parent = box;
+ helpButton.TooltipString = obj.HelpTooltipString;
+ box.Widths(end) = helpButton.Extent(3);
+ end
+ close = ~isempty( obj.CloseRequestFcn );
+ if close
+ closeButton.Parent = box;
+ closeButton.TooltipString = obj.CloseTooltipString;
+ box.Widths(end) = closeButton.Extent(3);
+ end
+
+ % Update icons
+ if obj.Minimized_
+ minimizeButton.String = char( 9662 );
+ minimizeButton.TooltipString = obj.MaximizeTooltipString;
+ else
+ minimizeButton.String = char( 9652 );
+ minimizeButton.TooltipString = obj.MinimizeTooltipString;
+ end
+ if obj.Docked_
+ dockButton.String = char( 8599 );
+ dockButton.TooltipString = obj.UndockTooltipString;
+ else
+ dockButton.String = char( 8600 );
+ dockButton.TooltipString = obj.DockTooltipString;
+ end
+
+ end % redrawButtons
+
+ end % helper methods
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/ButtonBox.m b/studio_functions/GUI Layout Toolbox/layout/+uix/ButtonBox.m
new file mode 100644
index 00000000..086117a2
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/ButtonBox.m
@@ -0,0 +1,95 @@
+classdef ButtonBox < uix.Box
+ %uix.ButtonBox Button box base class
+ %
+ % uix.ButtonBox is a base class for containers that lay out buttons.
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Access = public, Dependent, AbortSet )
+ ButtonSize % button size, in pixels
+ HorizontalAlignment % horizontal alignment [left|center|right]
+ VerticalAlignment % vertical alignment [top|middle|bottom]
+ end
+
+ properties( Access = protected )
+ ButtonSize_ = [60 20] % backing for ButtonSize
+ HorizontalAlignment_ = 'center' % backing for HorizontalAlignment
+ VerticalAlignment_ = 'middle' % backing for VerticalAlignment
+ end
+
+ methods
+
+ function value = get.ButtonSize( obj )
+
+ value = obj.ButtonSize_;
+
+ end % get.ButtonSize
+
+ function set.ButtonSize( obj, value )
+
+ % Check
+ assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ...
+ 'Property ''ButtonSize'' must be of type double.' )
+ assert( isequal( size( value ), [1 2] ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Size of property ''ButtonSize'' must by 1-by-2.' )
+ assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ...
+ ~any( isnan( value ) ) && ~any( value <= 0 ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Elements of property ''ButtonSize'' must be real, finite and positive.' )
+
+ % Set
+ obj.ButtonSize_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.ButtonSize
+
+ function value = get.HorizontalAlignment( obj )
+
+ value = obj.HorizontalAlignment_;
+
+ end % get.HorizontalAlignment
+
+ function set.HorizontalAlignment( obj, value )
+
+ % Check
+ assert( ischar( value ), 'uix:InvalidPropertyValue', ...
+ 'Property ''HorizontalAlignment'' must be a string.' )
+ assert( any( strcmp( value, {'left';'center';'right'} ) ), ...
+ 'Property ''HorizontalAlignment'' must be ''left'', ''center'' or ''right''.' )
+
+ % Set
+ obj.HorizontalAlignment_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.HorizontalAlignment
+
+ function value = get.VerticalAlignment( obj )
+
+ value = obj.VerticalAlignment_;
+
+ end % get.VerticalAlignment
+
+ function set.VerticalAlignment( obj, value )
+
+ % Check
+ assert( ischar( value ), 'uix:InvalidPropertyValue', ...
+ 'Property ''VerticalAlignment'' must be a string.' )
+ assert( any( strcmp( value, {'top';'middle';'bottom'} ) ), ...
+ 'Property ''VerticalAlignment'' must be ''top'', ''middle'' or ''bottom''.' )
+
+ % Set
+ obj.VerticalAlignment_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.VerticalAlignment
+
+ end % accessors
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/CardPanel.m b/studio_functions/GUI Layout Toolbox/layout/+uix/CardPanel.m
new file mode 100644
index 00000000..3942deca
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/CardPanel.m
@@ -0,0 +1,59 @@
+classdef CardPanel < uix.Container & uix.mixin.Panel
+ %uix.CardPanel Card panel
+ %
+ % b = uix.CardPanel(p1,v1,p2,v2,...) constructs a card panel and sets
+ % parameter p1 to value v1, etc.
+ %
+ % A card panel is a standard container (uicontainer) that shows one
+ % its contents and hides the others.
+ %
+ % See also: uix.Panel, uix.BoxPanel, uix.TabPanel, uicontainer
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ methods
+
+ function obj = CardPanel( varargin )
+ %uix.CardPanel Card panel constructor
+ %
+ % p = uix.CardPanel() constructs a card panel.
+ %
+ % p = uix.CardPanel(p1,v1,p2,v2,...) sets parameter p1 to
+ % value v1, etc.
+
+ % Set properties
+ try
+ uix.set( obj, varargin{:} )
+ catch e
+ delete( obj )
+ e.throwAsCaller()
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods( Access = protected )
+
+ function redraw( obj )
+ %redraw Redraw
+
+ % Compute positions
+ bounds = hgconvertunits( ancestor( obj, 'figure' ), ...
+ [0 0 1 1], 'normalized', 'pixels', obj );
+ padding = obj.Padding_;
+ xSizes = uix.calcPixelSizes( bounds(3), -1, 1, padding, 0 );
+ ySizes = uix.calcPixelSizes( bounds(4), -1, 1, padding, 0 );
+ position = [padding+1 padding+1 xSizes ySizes];
+
+ % Redraw contents
+ selection = obj.Selection_;
+ if selection ~= 0
+ uix.setPosition( obj.Contents_(selection), position, 'pixels' )
+ end
+
+ end % redraw
+
+ end % template methods
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/ChildEvent.m b/studio_functions/GUI Layout Toolbox/layout/+uix/ChildEvent.m
new file mode 100644
index 00000000..fa066a3b
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/ChildEvent.m
@@ -0,0 +1,27 @@
+classdef( Hidden, Sealed ) ChildEvent < event.EventData
+ %uix.ChildEvent Event data for child event
+ %
+ % e = uix.ChildEvent(c) creates event data including the child c.
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( SetAccess = private )
+ Child % child
+ end
+
+ methods
+
+ function obj = ChildEvent( child )
+ %uix.ChildEvent Event data for child event
+ %
+ % e = uix.ChildEvent(c) creates event data including the child
+ % c.
+
+ % Set properties
+ obj.Child = child;
+
+ end % constructor
+
+ end % structors
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/ChildObserver.m b/studio_functions/GUI Layout Toolbox/layout/+uix/ChildObserver.m
new file mode 100644
index 00000000..b3bc02bc
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/ChildObserver.m
@@ -0,0 +1,223 @@
+classdef ( Hidden, Sealed ) ChildObserver < handle
+ %uix.ChildObserver Child observer
+ %
+ % co = uix.ChildObserver(o) creates a child observer for the graphics
+ % object o. A child observer raises events when objects are added to
+ % and removed from the property Children of o.
+ %
+ % See also: uix.Node
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Access = private )
+ Root % root node
+ end
+
+ events( NotifyAccess = private )
+ ChildAdded % child added
+ ChildRemoved % child removed
+ end
+
+ methods
+
+ function obj = ChildObserver( oRoot )
+ %uix.ChildObserver Child observer
+ %
+ % co = uix.ChildObserver(o) creates a child observer for the
+ % graphics object o. A child observer raises events when
+ % objects are added to and removed from the property Children
+ % of o.
+
+ % Check
+ assert( ispositionable( oRoot ) && ...
+ isequal( size( oRoot ), [1 1] ), 'uix.InvalidArgument', ...
+ 'Object must be a graphics object.' )
+
+ % Create root node
+ nRoot = uix.Node( oRoot );
+ childAddedListener = event.listener( oRoot, ...
+ 'ObjectChildAdded', ...
+ @(~,e)obj.addChild(nRoot,e.Child) );
+ childAddedListener.Recursive = true;
+ nRoot.addprop( 'ChildAddedListener' );
+ nRoot.ChildAddedListener = childAddedListener;
+ childRemovedListener = event.listener( oRoot, ...
+ 'ObjectChildRemoved', ...
+ @(~,e)obj.removeChild(nRoot,e.Child) );
+ childRemovedListener.Recursive = true;
+ nRoot.addprop( 'ChildRemovedListener' );
+ nRoot.ChildRemovedListener = childRemovedListener;
+
+ % Add children
+ oChildren = hgGetTrueChildren( oRoot );
+ for ii = 1:numel( oChildren )
+ obj.addChild( nRoot, oChildren(ii) )
+ end
+
+ % Store properties
+ obj.Root = nRoot;
+
+ end % constructor
+
+ end % structors
+
+ methods( Access = private )
+
+ function addChild( obj, nParent, oChild )
+ %addChild Add child object to parent node
+ %
+ % co.addChild(np,oc) adds the child object oc to the parent
+ % node np, either as part of construction of the child
+ % observer co, or in response to an ObjectChildAdded event on
+ % an object of interest to co. This may lead to ChildAdded
+ % events being raised on co.
+
+ % Create child node
+ nChild = uix.Node( oChild );
+ nParent.addChild( nChild )
+ positionable = ispositionable( oChild );
+ if positionable == true
+ % Add Internal PreSet property listener
+ internalPreSetListener = event.proplistener( oChild, ...
+ findprop( oChild, 'Internal' ), 'PreSet', ...
+ @(~,~)obj.preSetInternal(nChild) );
+ nChild.addprop( 'InternalPreSetListener' );
+ nChild.InternalPreSetListener = internalPreSetListener;
+ % Add Internal PostSet property listener
+ internalPostSetListener = event.proplistener( oChild, ...
+ findprop( oChild, 'Internal' ), 'PostSet', ...
+ @(~,~)obj.postSetInternal(nChild) );
+ nChild.addprop( 'InternalPostSetListener' );
+ nChild.InternalPostSetListener = internalPostSetListener;
+ else
+ % Add ObjectChildAdded listener
+ childAddedListener = event.listener( oChild, ...
+ 'ObjectChildAdded', ...
+ @(~,e)obj.addChild(nChild,e.Child) );
+ nChild.addprop( 'ChildAddedListener' );
+ nChild.ChildAddedListener = childAddedListener;
+ % Add ObjectChildRemoved listener
+ childRemovedListener = event.listener( oChild, ...
+ 'ObjectChildRemoved', ...
+ @(~,e)obj.removeChild(nChild,e.Child) );
+ nChild.addprop( 'ChildRemovedListener' );
+ nChild.ChildRemovedListener = childRemovedListener;
+ end
+
+ % Raise ChildAdded event
+ if positionable == true && oChild.Internal == false
+ notify( obj, 'ChildAdded', uix.ChildEvent( oChild ) )
+ end
+
+ % Add grandchildren
+ if positionable == false && isblacklisted( oChild ) == false
+ oGrandchildren = hgGetTrueChildren( oChild );
+ for ii = 1:numel( oGrandchildren )
+ obj.addChild( nChild, oGrandchildren(ii) )
+ end
+ end
+
+ end % addChild
+
+ function removeChild( obj, nParent, oChild )
+ %removeChild Remove child object from parent node
+ %
+ % co.removeChild(np,oc) removes the child object oc from the
+ % parent node np, in response to an ObjectChildRemoved event
+ % on an object of interest to co. This may lead to
+ % ChildRemoved events being raised on co.
+
+ % Get child node
+ nChildren = nParent.Children;
+ tf = oChild == [nChildren.Object];
+ nChild = nChildren(tf);
+
+ % Raise ChildRemoved event(s)
+ notifyChildRemoved( nChild )
+
+ % Delete child node
+ delete( nChild )
+
+ function notifyChildRemoved( nc )
+
+ % Process child nodes
+ ngc = nc.Children;
+ for ii = 1:numel( ngc )
+ notifyChildRemoved( ngc(ii) )
+ end
+
+ % Process this node
+ oc = nc.Object;
+ if ispositionable( oc ) == true && oc.Internal == false
+ notify( obj, 'ChildRemoved', uix.ChildEvent( oc ) )
+ end
+
+ end % notifyChildRemoved
+
+ end % removeChild
+
+ function preSetInternal( ~, nChild )
+ %preSetInternal Perform property PreSet tasks
+ %
+ % co.preSetInternal(n) caches the previous value of the
+ % property Internal of the object referenced by the node n, to
+ % enable PostSet tasks to identify whether the value changed.
+ % This is necessary since Internal AbortSet is false.
+
+ oldInternal = nChild.Object.Internal;
+ nChild.addprop( 'OldInternal' );
+ nChild.OldInternal = oldInternal;
+
+ end % preSetInternal
+
+ function postSetInternal( obj, nChild )
+ %postSetInternal Perform property PostSet tasks
+ %
+ % co.postSetInternal(n) raises a ChildAdded or ChildRemoved
+ % event on the child observer co in response to a change of
+ % the value of the property Internal of the object referenced
+ % by the node n.
+
+ % Retrieve old and new values
+ oChild = nChild.Object;
+ newInternal = oChild.Internal;
+ oldInternal = nChild.OldInternal;
+
+ % Clean up node
+ delete( findprop( nChild, 'OldInternal' ) )
+
+ % Raise event
+ switch newInternal
+ case oldInternal % no change
+ % no event
+ case true % false to true
+ notify( obj, 'ChildRemoved', uix.ChildEvent( oChild ) )
+ case false % true to false
+ notify( obj, 'ChildAdded', uix.ChildEvent( oChild ) )
+ end
+
+ end % postSetInternal
+
+ end % event handlers
+
+end % classdef
+
+function tf = ispositionable( o )
+%ispositionable True for positionable graphics
+
+p = findprop( o, 'Position' );
+tf = isgraphics( o ) && ~isempty( p ) && ...
+ isequal( p.GetAccess, 'public' ) && ...
+ isequal( p.SetAccess, 'public' ) && ...
+ isequal( size( o.Position ), [1 4] );
+
+end % ispositionable
+
+function tf = isblacklisted( o )
+%isblacklisted True for objects that never have positionable graphics
+
+tf = isa( o, 'matlab.ui.container.Menu' ) || ...
+ isa( o, 'matlab.ui.container.Toolbar' ) || ...
+ isa( o, 'matlab.graphics.shape.internal.AnnotationPane' );
+
+end % isblacklisted
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Container.m b/studio_functions/GUI Layout Toolbox/layout/+uix/Container.m
new file mode 100644
index 00000000..e071a82b
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/Container.m
@@ -0,0 +1,8 @@
+classdef Container < matlab.ui.container.internal.UIContainer
+ %uix.Container Container base class
+ %
+ % uix.Container is base class for containers that extend uicontainer.
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Divider.m b/studio_functions/GUI Layout Toolbox/layout/+uix/Divider.m
new file mode 100644
index 00000000..8ec39d41
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/Divider.m
@@ -0,0 +1,346 @@
+classdef ( Hidden ) Divider < matlab.mixin.SetGet
+ %uix.Divider Draggable divider
+ %
+ % d = uix.Divider() creates a divider.
+ %
+ % d = uix.Divider(p1,v1,p2,v2,...) creates a divider and sets
+ % specified property p1 to value v1, etc.
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Dependent )
+ Parent % parent
+ Units % units [inches|centimeters|characters|normalized|points|pixels]
+ Position % position
+ Visible % visible [on|off]
+ BackgroundColor % background color [RGB]
+ HighlightColor % border highlight color [RGB]
+ ShadowColor % border shadow color [RGB]
+ Orientation % orientation [vertical|horizontal]
+ Markings % markings [pixels]
+ end
+
+ properties( Access = private )
+ Control % uicontrol
+ BackgroundColor_ = get( 0, 'DefaultUicontrolBackgroundColor' ) % backing for BackgroundColor
+ HighlightColor_ = [1 1 1] % backing for HighlightColor
+ ShadowColor_ = [0.7 0.7 0.7] % backing for ShadowColor
+ Orientation_ = 'vertical' % backing for Orientation
+ Markings_ = zeros( [0 1] ) % backing for Markings
+ SizeChangedListener % listener
+ end
+
+ methods
+
+ function obj = Divider( varargin )
+ %uix.Divider Draggable divider
+ %
+ % d = uix.Divider() creates a divider.
+ %
+ % d = uix.Divider(p1,v1,p2,v2,...) creates a dividerand sets
+ % specified property p1 to value v1, etc.
+
+ % Create control
+ control = matlab.ui.control.UIControl( ...
+ 'Style', 'checkbox', 'Internal', true, ...
+ 'Enable', 'inactive', 'DeleteFcn', @obj.onDeleted,...
+ 'Tag', 'uix.Divider' );
+
+ % Store control
+ obj.Control = control;
+
+ % Set properties
+ try
+ uix.set( obj, varargin{:} )
+ catch e
+ delete( obj )
+ e.throwAsCaller()
+ end
+
+ % Force update
+ obj.update()
+
+ % Create listener
+ sizeChangedListener = event.listener( control, 'SizeChanged', ...
+ @obj.onSizeChanged );
+
+ % Store listener
+ obj.SizeChangedListener = sizeChangedListener;
+
+ end % constructor
+
+ function delete( obj )
+ %delete Destructor
+
+ control = obj.Control;
+ if isgraphics( control ) && strcmp( control.BeingDeleted, 'off' )
+ delete( control )
+ end
+
+ end % destructor
+
+ end % structors
+
+ methods
+
+ function value = get.Parent( obj )
+
+ value = obj.Control.Parent;
+
+ end % get.Parent
+
+ function set.Parent( obj, value )
+
+ obj.Control.Parent = value;
+
+ end % set.Parent
+
+ function value = get.Units( obj )
+
+ value = obj.Control.Units;
+
+ end % get.Units
+
+ function set.Units( obj, value )
+
+ obj.Control.Units = value;
+
+ end % set.Units
+
+ function value = get.Position( obj )
+
+ value = obj.Control.Position;
+
+ end % get.Position
+
+ function set.Position( obj, value )
+
+ obj.Control.Position = value;
+
+ end % set.Position
+
+ function value = get.Visible( obj )
+
+ value = obj.Control.Visible;
+
+ end % get.Visible
+
+ function set.Visible( obj, value )
+
+ obj.Control.Visible = value;
+
+ end % set.Visible
+
+ function value = get.BackgroundColor( obj )
+
+ value = obj.BackgroundColor_;
+
+ end % get.BackgroundColor
+
+ function set.BackgroundColor( obj, value )
+
+ % Check
+ assert( isa( value, 'double' ) && ...
+ isequal( size( value ), [1 3] ) && ...
+ all( value >= 0 ) && all( value <= 1 ), ...
+ 'uix:InvalidArgument', ...
+ 'Property ''BackgroundColor'' must be a valid colorspec.' )
+
+ % Set
+ obj.BackgroundColor_ = value;
+
+ % Update
+ obj.update()
+
+ end % set.BackgroundColor
+
+ function value = get.HighlightColor( obj )
+
+ value = obj.HighlightColor_;
+
+ end % get.HighlightColor
+
+ function set.HighlightColor( obj, value )
+
+ % Check
+ assert( isnumeric( value ) && isequal( size( value ), [1 3] ) && ...
+ all( isreal( value ) ) && all( value >= 0 ) && all( value <= 1 ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''HighlightColor'' must be an RGB triple.' )
+
+ % Set
+ obj.HighlightColor_ = value;
+
+ % Update
+ obj.update()
+
+ end % set.HighlightColor
+
+ function value = get.ShadowColor( obj )
+
+ value = obj.ShadowColor_;
+
+ end % get.ShadowColor
+
+ function set.ShadowColor( obj, value )
+
+ % Check
+ assert( isnumeric( value ) && isequal( size( value ), [1 3] ) && ...
+ all( isreal( value ) ) && all( value >= 0 ) && all( value <= 1 ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''ShadowColor'' must be an RGB triple.' )
+
+ % Set
+ obj.ShadowColor_ = value;
+
+ % Update
+ obj.update()
+
+ end % set.ShadowColor
+
+ function value = get.Orientation( obj )
+
+ value = obj.Orientation_;
+
+ end % get.Orientation
+
+ function set.Orientation( obj, value )
+
+ % Check
+ assert( ischar( value ) && ismember( value, ...
+ {'horizontal','vertical'} ) )
+
+ % Set
+ obj.Orientation_ = value;
+
+ % Update
+ obj.update()
+
+ end % set.Orientation
+
+ function value = get.Markings( obj )
+
+ value = obj.Markings_;
+
+ end % get.Markings
+
+ function set.Markings( obj, value )
+
+ % Check
+ assert( isa( value, 'double' ) && ndims( value ) == 2 && ...
+ size( value, 2 ) == 1 && all( isreal( value ) ) && ...
+ all( ~isinf( value ) ) && all( ~isnan( value ) ) && ...
+ all( value > 0 ), 'uix:InvalidPropertyValue', ...
+ 'Property ''Markings'' must be a vector of positive values.' ) %#ok
+
+ % Set
+ obj.Markings_ = value;
+
+ % Update
+ obj.update()
+
+ end % set.Markings
+
+ end % accessors
+
+ methods
+
+ function tf = isMouseOver( obj, eventData )
+ %isMouseOver Test for mouse over
+ %
+ % tf = d.isMouseOver(wmd) tests whether the WindowMouseData
+ % wmd is consistent with the mouse pointer being over the
+ % divider d.
+ %
+ % This method returns false for dividers that are being
+ % deleted.
+
+ tf = isvalid( obj ); % initialize
+ for ii = 1:numel( obj )
+ tf(ii) = tf(ii) && ~isempty( eventData.HitObject ) && ...
+ obj(ii).Control == eventData.HitObject;
+ end
+
+ end % isMouseOver
+
+ end % methods
+
+ methods( Access = private )
+
+ function onDeleted( obj, ~, ~ )
+ %onDeleted Event handler
+
+ % Call destructor
+ obj.delete()
+
+ end % onDeleted
+
+ function onSizeChanged( obj, ~, ~ )
+ %onSizeChanged Event handler
+
+ % Update
+ obj.update()
+
+ end % onSizeChanged
+
+ end % event handlers
+
+ methods( Access = private )
+
+ function update( obj )
+ %update Update divider
+ %
+ % d.update() updates the divider markings.
+
+ % Get properties
+ control = obj.Control;
+ position = control.Position;
+ backgroundColor = obj.BackgroundColor;
+ highlightColor = obj.HighlightColor;
+ shadowColor = obj.ShadowColor;
+ orientation = obj.Orientation;
+ markings = obj.Markings;
+
+ % Assemble mask
+ mask = zeros( floor( position([4 3]) ) - [1 1] ); % initialize
+ switch orientation
+ case 'vertical'
+ markings(markings < 4) = [];
+ markings(markings > position(4)-6) = [];
+ for ii = 1:numel( markings )
+ marking = markings(ii);
+ mask(floor( marking ) + [-3 0 3],1:end-1) = 1;
+ mask(floor( marking ) + [-2 1 4],1:end-1) = 2;
+ end
+ case 'horizontal'
+ markings(markings < 4) = [];
+ markings(markings > position(3)-6) = [];
+ for ii = 1:numel( markings )
+ marking = markings(ii);
+ mask(2:end,floor( marking ) + [-3 0 3]) = 1;
+ mask(2:end,floor( marking ) + [-2 1 4]) = 2;
+ end
+ end
+
+ % Assemble color data
+ cData1 = repmat( backgroundColor(1), size( mask ) );
+ cData1(mask==1) = highlightColor(1);
+ cData1(mask==2) = shadowColor(1);
+ cData2 = repmat( backgroundColor(2), size( mask ) );
+ cData2(mask==1) = highlightColor(2);
+ cData2(mask==2) = shadowColor(2);
+ cData3 = repmat( backgroundColor(3), size( mask ) );
+ cData3(mask==1) = highlightColor(3);
+ cData3(mask==2) = shadowColor(3);
+ cData = cat( 3, cData1, cData2, cData3 );
+
+ % Set properties
+ control.ForegroundColor = backgroundColor;
+ control.BackgroundColor = backgroundColor;
+ control.CData = cData;
+
+ end % update
+
+ end % methods
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Empty.m b/studio_functions/GUI Layout Toolbox/layout/+uix/Empty.m
new file mode 100644
index 00000000..b9402c38
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/Empty.m
@@ -0,0 +1,101 @@
+function obj = Empty( varargin )
+%uix.Empty Create an empty space
+%
+% obj = uix.Empty() creates an empty space that can be used to add gaps
+% between elements in layouts.
+%
+% obj = uix.Empty(param,value,...) also sets one or more property
+% values.
+%
+% See the documentation for more detail and the list of properties.
+%
+% Examples:
+% >> f = figure();
+% >> box = uix.HBox( 'Parent', f );
+% >> uicontrol( 'Parent', box, 'Background', 'r' )
+% >> uix.Empty( 'Parent', box )
+% >> uicontrol( 'Parent', box, 'Background', 'b' )
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+% Create uicontainer
+obj = matlab.ui.container.internal.UIContainer( 'Tag', 'empty', varargin{:} );
+
+% Create property for Parent listener
+p = addprop( obj, 'ParentListener' );
+p.Hidden = true;
+
+% Create Parent listener
+obj.ParentListener = event.proplistener( obj, ...
+ findprop( obj, 'Parent' ), 'PostSet', @(~,~)onParentChanged(obj) );
+
+% Create property for Parent color listener
+p = addprop( obj, 'ParentColorListener' );
+p.Hidden = true;
+
+% Initialize color and listener
+updateColor( obj )
+updateListener( obj )
+
+end % uix.Empty
+
+function onParentChanged( obj )
+%onParentColorChanged Event handler
+
+% Update color and listener
+updateColor( obj )
+updateListener( obj )
+
+end % onParentChanged
+
+function onParentColorChanged( obj )
+%onParentColorChanged Event handler
+
+% Update color
+updateColor( obj )
+
+end % onParentColorChanged
+
+function name = getColorProperty( obj )
+%getColorProperty Get color property
+
+names = {'Color','BackgroundColor'}; % possible names
+for ii = 1:numel( names ) % loop over possible names
+ name = names{ii};
+ if isprop( obj, name )
+ return
+ end
+end
+error( 'Cannot find color property for %s.', class( obj ) )
+
+end % getColorProperty
+
+function updateColor( obj )
+%updateColor Set uicontainer BackgroundColor to match Parent
+
+parent = obj.Parent;
+if isempty( parent ), return, end
+property = getColorProperty( parent );
+color = parent.( property );
+try
+ obj.BackgroundColor = color;
+catch e
+ warning( e.identifier, e.message ) % rethrow as warning
+end
+
+end % updateColor
+
+function updateListener( obj )
+%updateListener Create listener to parent color property
+
+parent = obj.Parent;
+if isempty( parent )
+ obj.ParentColorListener = [];
+else
+ property = getColorProperty( parent );
+ obj.ParentColorListener = event.proplistener( parent, ...
+ findprop( parent, property ), 'PostSet', ...
+ @(~,~)onParentColorChanged(obj) );
+end
+
+end % updateListener
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/FigureData.m b/studio_functions/GUI Layout Toolbox/layout/+uix/FigureData.m
new file mode 100644
index 00000000..9ed0a9aa
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/FigureData.m
@@ -0,0 +1,25 @@
+classdef ( Hidden, Sealed ) FigureData < event.EventData
+ %uix.FigureData Event data for FigureChanged on uix.FigureObserver
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( SetAccess = private )
+ OldFigure % old figure
+ NewFigure % new figure
+ end
+
+ methods( Access = ?uix.FigureObserver )
+
+ function obj = FigureData( oldFigure, newFigure )
+ %uix.FigureData Create event data
+ %
+ % d = uix.FigureData(oldFigure,newFigure)
+
+ obj.OldFigure = oldFigure;
+ obj.NewFigure = newFigure;
+
+ end % constructor
+
+ end % methods
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/FigureObserver.m b/studio_functions/GUI Layout Toolbox/layout/+uix/FigureObserver.m
new file mode 100644
index 00000000..1df743d2
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/FigureObserver.m
@@ -0,0 +1,97 @@
+classdef ( Hidden, Sealed ) FigureObserver < handle
+ %uix.FigureObserver Figure observer
+ %
+ % A figure observer raises an event FigureChanged when the figure
+ % ancestor of a subject changes.
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( SetAccess = private )
+ Subject % subject
+ Figure % figure ancestor
+ end
+
+ properties( Access = private )
+ PreSetListeners % listeners to Parent PreGet
+ PostSetListeners % listeners to Parent PreGet
+ OldFigure = gobjects( 0 ) % previous figure ancestor
+ end
+
+ events( NotifyAccess = private )
+ FigureChanged
+ end
+
+ methods
+
+ function obj = FigureObserver( subject )
+ %uix.FigureObserver Create figure observer
+ %
+ % o = uix.FigureObserver(s) creates a figure observer for the
+ % subject s.
+
+ % Check
+ validateattributes( subject, {'matlab.graphics.Graphics'}, ...
+ {'scalar'}, '', 'subject' )
+
+ % Store subject
+ obj.Subject = subject;
+
+ % Set up object
+ obj.update()
+
+ end % constructor
+
+ end % structors
+
+ methods( Access = private )
+
+ function update( obj )
+ %update Update listeners and Figure property
+
+ % Create fresh listeners
+ obj.PreSetListeners = event.proplistener.empty( [1 0] ); % clear
+ obj.PostSetListeners = event.proplistener.empty( [1 0] ); % clear
+ o = obj.Subject;
+ while ~isempty( o ) && ~isa( o, 'matlab.ui.Figure' )
+ obj.PreSetListeners(end+1) = event.proplistener( o, ...
+ findprop( o, 'Parent' ), 'PreSet', @obj.onParentPreSet );
+ obj.PostSetListeners(end+1) = event.proplistener( o, ...
+ findprop( o, 'Parent' ), 'PostSet', @obj.onParentPostSet );
+ o = o.Parent;
+ end
+
+ % Store figure
+ obj.Figure = o;
+
+ end % update
+
+ function onParentPreSet( obj, ~, ~ )
+ %onParentPreSet Event handler
+
+ % Store old figure
+ obj.OldFigure = obj.Figure;
+
+ end % onParentPreSet
+
+ function onParentPostSet( obj, ~, ~ )
+ %onParentPostSet Event handler
+
+ % Update object
+ obj.update()
+
+ % Raise event
+ oldFigure = obj.OldFigure;
+ newFigure = obj.Figure;
+ if ~isequal( oldFigure, newFigure )
+ notify( obj, 'FigureChanged', ...
+ uix.FigureData( oldFigure, newFigure ) )
+ end
+
+ % Clear old figure
+ obj.OldFigure = gobjects( 0 );
+
+ end % onParentPostSet
+
+ end % private methods
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Grid.m b/studio_functions/GUI Layout Toolbox/layout/+uix/Grid.m
new file mode 100644
index 00000000..db76b881
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/Grid.m
@@ -0,0 +1,316 @@
+classdef Grid < uix.Box
+ %uix.Grid Grid
+ %
+ % b = uix.Grid(p1,v1,p2,v2,...) constructs a grid and sets parameter
+ % p1 to value v1, etc.
+ %
+ % A grid lays out contents from top to bottom and left to right.
+ %
+ % See also: uix.HBox, uix.VBox, uix.GridFlex
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Access = public, Dependent, AbortSet )
+ Widths % widths of contents, in pixels and/or weights
+ MinimumWidths % minimum widths of contents, in pixels
+ Heights % heights of contents, in pixels and/or weights
+ MinimumHeights % minimum heights of contents, in pixels
+ end
+
+ properties( Access = protected )
+ Widths_ = zeros( [0 1] ) % backing for Widths
+ MinimumWidths_ = zeros( [0 1] ) % backing for MinimumWidths
+ Heights_ = zeros( [0 1] ) % backing for Heights
+ MinimumHeights_ = zeros( [0 1] ) % backing for MinimumHeights
+ end
+
+ methods
+
+ function obj = Grid( varargin )
+ %uix.Grid Grid constructor
+ %
+ % b = uix.Grid() constructs a grid.
+ %
+ % b = uix.Grid(p1,v1,p2,v2,...) sets parameter p1 to value v1,
+ % etc.
+
+ % Set properties
+ try
+ uix.set( obj, varargin{:} )
+ catch e
+ delete( obj )
+ e.throwAsCaller()
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = get.Widths( obj )
+
+ value = obj.Widths_;
+
+ end % get.Widths
+
+ function set.Widths( obj, value )
+
+ % For those who can't tell a column from a row...
+ if isrow( value )
+ value = transpose( value );
+ end
+
+ % Check
+ assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ...
+ 'Property ''Widths'' must be of type double.' )
+ assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ...
+ ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ...
+ 'Elements of property ''Widths'' must be real and finite.' )
+ n = numel( obj.Contents_ );
+ b = numel( obj.Widths_ );
+ q = numel( obj.Heights_ );
+ c = numel( value );
+ r = ceil( n / c );
+ if c < min( [1 n] )
+ error( 'uix:InvalidPropertyValue' , ...
+ 'Property ''Widths'' must be non-empty for non-empty contents.' )
+ elseif ceil( n / r ) < c
+ error( 'uix:InvalidPropertyValue' , ...
+ 'Size of property ''Widths'' must not lead to empty columns.' )
+ elseif c > n
+ error( 'uix:InvalidPropertyValue' , ...
+ 'Size of property ''Widths'' must be no larger than size of contents.' )
+ end
+
+ % Set
+ obj.Widths_ = value;
+ if c < b % number of columns decreasing
+ obj.MinimumWidths_(c+1:end,:) = [];
+ if r > q % number of rows increasing
+ obj.Heights_(end+1:r,:) = -1;
+ obj.MinimumHeights_(end+1:r,:) = 1;
+ end
+ elseif c > b % number of columns increasing
+ obj.MinimumWidths_(end+1:c,:) = -1;
+ if r < q % number of rows decreasing
+ obj.Heights_(r+1:end,:) = [];
+ obj.MinimumHeights_(r+1:end,:) = [];
+ end
+ end
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.Widths
+
+ function value = get.MinimumWidths( obj )
+
+ value = obj.MinimumWidths_;
+
+ end % get.MinimumWidths
+
+ function set.MinimumWidths( obj, value )
+
+ % For those who can't tell a column from a row...
+ if isrow( value )
+ value = transpose( value );
+ end
+
+ % Check
+ assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ...
+ 'Property ''MinimumWidths'' must be of type double.' )
+ assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ...
+ all( value >= 0 ), 'uix:InvalidPropertyValue', ...
+ 'Elements of property ''MinimumWidths'' must be non-negative.' )
+ assert( isequal( size( value ), size( obj.Widths_ ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Size of property ''MinimumWidths'' must match size of contents.' )
+
+ % Set
+ obj.MinimumWidths_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.MinimumWidths
+
+ function value = get.Heights( obj )
+
+ value = obj.Heights_;
+
+ end % get.Heights
+
+ function set.Heights( obj, value )
+
+ % For those who can't tell a column from a row...
+ if isrow( value )
+ value = transpose( value );
+ end
+
+ % Check
+ assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ...
+ 'Property ''Heights'' must be of type double.' )
+ assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ...
+ ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ...
+ 'Elements of property ''Heights'' must be real and finite.' )
+ n = numel( obj.Contents_ );
+ b = numel( obj.Widths_ );
+ q = numel( obj.Heights_ );
+ r = numel( value );
+ c = ceil( n / r );
+ if r < min( [1 n] )
+ error( 'uix:InvalidPropertyValue' , ...
+ 'Property ''Heights'' must be non-empty for non-empty contents.' )
+ elseif r > n
+ error( 'uix:InvalidPropertyValue' , ...
+ 'Size of property ''Heights'' must be no larger than size of contents.' )
+ end
+
+ % Set
+ obj.Heights_ = value;
+ if r < q % number of rows decreasing
+ obj.MinimumHeights_(r+1:end,:) = [];
+ if c > b % number of columns increasing
+ obj.Widths_(end+1:c,:) = -1;
+ obj.MinimumWidths_(end+1:c,:) = 1;
+ end
+ elseif r > q % number of rows increasing
+ obj.MinimumHeights_(end+1:r,:) = 1;
+ if c < b % number of columns decreasing
+ obj.Widths_(c+1:end,:) = [];
+ obj.MinimumWidths_(c+1:end,:) = [];
+ end
+ end
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.Heights
+
+ function value = get.MinimumHeights( obj )
+
+ value = obj.MinimumHeights_;
+
+ end % get.MinimumHeights
+
+ function set.MinimumHeights( obj, value )
+
+ % For those who can't tell a column from a row...
+ if isrow( value )
+ value = transpose( value );
+ end
+
+ % Check
+ assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ...
+ 'Property ''MinimumHeights'' must be of type double.' )
+ assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ...
+ all( value >= 0 ), 'uix:InvalidPropertyValue', ...
+ 'Elements of property ''MinimumHeights'' must be non-negative.' )
+ assert( isequal( size( value ), size( obj.Heights_ ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Size of property ''MinimumHeights'' must match size of contents.' )
+
+ % Set
+ obj.MinimumHeights_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.MinimumHeights
+
+ end % accessors
+
+ methods( Access = protected )
+
+ function redraw( obj )
+ %redraw Redraw
+ %
+ % c.redraw() redraws the container c.
+
+ % Compute positions
+ bounds = hgconvertunits( ancestor( obj, 'figure' ), ...
+ [0 0 1 1], 'normalized', 'pixels', obj );
+ widths = obj.Widths_;
+ minimumWidths = obj.MinimumWidths_;
+ heights = obj.Heights_;
+ minimumHeights = obj.MinimumHeights_;
+ padding = obj.Padding_;
+ spacing = obj.Spacing_;
+ c = numel( widths );
+ r = numel( heights );
+ n = numel( obj.Contents_ );
+ xSizes = uix.calcPixelSizes( bounds(3), widths, ...
+ minimumWidths, padding, spacing );
+ xPositions = [cumsum( [0; xSizes(1:end-1,:)] ) + padding + ...
+ spacing * transpose( 0:c-1 ) + 1, xSizes];
+ ySizes = uix.calcPixelSizes( bounds(4), heights, ...
+ minimumHeights, padding, spacing );
+ yPositions = [bounds(4) - cumsum( ySizes ) - padding - ...
+ spacing * transpose( 0:r-1 ) + 1, ySizes];
+ [iy, ix] = ind2sub( [r c], transpose( 1:n ) );
+ positions = [xPositions(ix,1), yPositions(iy,1), ...
+ xPositions(ix,2), yPositions(iy,2)];
+
+ % Set positions
+ children = obj.Contents_;
+ for ii = 1:numel( children )
+ uix.setPosition( children(ii), positions(ii,:), 'pixels' )
+ end
+
+ end % redraw
+
+ function addChild( obj, child )
+ %addChild Add child
+ %
+ % c.addChild(d) adds the child d to the container c.
+
+ % Add column and even a row if necessary
+ n = numel( obj.Contents_ );
+ c = numel( obj.Widths_ );
+ r = numel( obj.Heights_ );
+ if n == 0
+ obj.Widths_(end+1,:) = -1;
+ obj.MinimumWidths_(end+1,:) = 1;
+ obj.Heights_(end+1,:) = -1;
+ obj.MinimumHeights_(end+1,:) = 1;
+ elseif ceil( (n+1)/r ) > c
+ obj.Widths_(end+1,:) = -1;
+ obj.MinimumWidths_(end+1,:) = 1;
+ end
+
+ % Call superclass method
+ addChild@uix.Box( obj, child )
+
+ end % addChild
+
+ function removeChild( obj, child )
+ %removeChild Remove child
+ %
+ % c.removeChild(d) removes the child d from the container c.
+
+ % Remove column and even row if necessary
+ n = numel( obj.Contents_ );
+ c = numel( obj.Widths_ );
+ r = numel( obj.Heights_ );
+ if n == 1
+ obj.Widths_(end,:) = [];
+ obj.MinimumWidths_(end,:) = [];
+ obj.Heights_(end,:) = [];
+ obj.MinimumHeights_(end,:) = [];
+ elseif c == 1
+ obj.Heights_(end,:) = [];
+ obj.MinimumHeights_(end,:) = [];
+ elseif ceil( (n-1)/r ) < c
+ obj.Widths_(end,:) = [];
+ obj.MinimumWidths_(end,:) = [];
+ end
+
+ % Call superclass method
+ removeChild@uix.Box( obj, child )
+
+ end % removeChild
+
+ end % template methods
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/GridFlex.m b/studio_functions/GUI Layout Toolbox/layout/+uix/GridFlex.m
new file mode 100644
index 00000000..d93038bf
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/GridFlex.m
@@ -0,0 +1,473 @@
+classdef GridFlex < uix.Grid & uix.mixin.Flex
+ %uix.GridFlex Flexible grid
+ %
+ % b = uix.GridFlex(p1,v1,p2,v2,...) constructs a flexible grid and
+ % sets parameter p1 to value v1, etc.
+ %
+ % A grid lays out contents from top to bottom and left to right.
+ % Users can resize contents by dragging the dividers.
+ %
+ % See also: uix.HBoxFlex, uix.VBoxFlex, uix.Grid
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Access = public, Dependent, AbortSet )
+ DividerMarkings % divider markings [on|off]
+ end
+
+ properties( Access = private )
+ RowDividers = uix.Divider.empty( [0 1] )
+ ColumnDividers = uix.Divider.empty( [0 1] )
+ FrontDivider % front divider
+ DividerMarkings_ = 'on' % backing for DividerMarkings
+ MousePressListener = event.listener.empty( [0 0] ) % mouse press listener
+ MouseReleaseListener = event.listener.empty( [0 0] ) % mouse release listener
+ MouseMotionListener = event.listener.empty( [0 0] ) % mouse motion listener
+ ActiveDivider = 0 % active divider index
+ ActiveDividerPosition = [NaN NaN NaN NaN] % active divider position
+ MousePressLocation = [NaN NaN] % mouse press location
+ BackgroundColorListener % background color listener
+ end
+
+ methods
+
+ function obj = GridFlex( varargin )
+ %uix.GridFlex Flexible grid constructor
+ %
+ % b = uix.GridFlex() constructs a flexible grid.
+ %
+ % b = uix.GridFlex(p1,v1,p2,v2,...) sets parameter p1 to value
+ % v1, etc.
+
+ % Create front divider
+ frontDivider = uix.Divider( 'Parent', obj, ...
+ 'Orientation', 'vertical', ...
+ 'BackgroundColor', obj.BackgroundColor * 0.75, ...
+ 'Visible', 'off' );
+
+ % Create listeners
+ backgroundColorListener = event.proplistener( obj, ...
+ findprop( obj, 'BackgroundColor' ), 'PostSet', ...
+ @obj.onBackgroundColorChanged );
+
+ % Store properties
+ obj.FrontDivider = frontDivider;
+ obj.BackgroundColorListener = backgroundColorListener;
+
+ % Set Spacing property (may be overwritten by uix.set)
+ obj.Spacing = 5;
+
+ % Set properties
+ try
+ uix.set( obj, varargin{:} )
+ catch e
+ delete( obj )
+ e.throwAsCaller()
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = get.DividerMarkings( obj )
+
+ value = obj.DividerMarkings_;
+
+ end % get.DividerMarkings
+
+ function set.DividerMarkings( obj, value )
+
+ % Check
+ assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ...
+ 'uix:InvalidArgument', ...
+ 'Property ''DividerMarkings'' must be ''on'' or ''off'.' )
+
+ % Set
+ obj.DividerMarkings_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.DividerMarkings
+
+ end % accessors
+
+ methods( Access = protected )
+
+ function onMousePress( obj, source, eventData )
+ %onMousePress Handler for WindowMousePress events
+
+ % Check whether mouse is over a divider
+ locr = find( obj.RowDividers.isMouseOver( eventData ) );
+ locc = find( obj.ColumnDividers.isMouseOver( eventData ) );
+ if ~isempty( locr )
+ loc = locr;
+ divider = obj.RowDividers(locr);
+ elseif ~isempty( locc )
+ loc = -locc;
+ divider = obj.ColumnDividers(locc);
+ else
+ return
+ end
+
+ % Capture state at button down
+ obj.ActiveDivider = loc;
+ obj.ActiveDividerPosition = divider.Position;
+ root = groot();
+ obj.MousePressLocation = root.PointerLocation;
+
+ % Make sure the pointer is appropriate
+ obj.updateMousePointer( source, eventData );
+
+ % Activate divider
+ frontDivider = obj.FrontDivider;
+ frontDivider.Position = divider.Position;
+ frontDivider.Orientation = divider.Orientation;
+ divider.Visible = 'off';
+ frontDivider.Parent = [];
+ frontDivider.Parent = obj;
+ frontDivider.Visible = 'on';
+
+ end % onMousePress
+
+ function onMouseRelease( obj, ~, ~ )
+ %onMousePress Handler for WindowMouseRelease events
+
+ % Compute new positions
+ loc = obj.ActiveDivider;
+ if loc > 0
+ root = groot();
+ delta = root.PointerLocation(2) - obj.MousePressLocation(2);
+ ih = loc;
+ jh = loc + 1;
+ ic = loc;
+ jc = loc + 1;
+ divider = obj.RowDividers(loc);
+ contents = obj.Contents_;
+ ip = uix.getPosition( contents(ic), 'pixels' );
+ jp = uix.getPosition( contents(jc), 'pixels' );
+ oldPixelHeights = [ip(4); jp(4)];
+ minimumHeights = obj.MinimumHeights_(ih:jh,:);
+ if delta < 0 % limit to minimum distance from lower neighbor
+ delta = max( delta, minimumHeights(2) - oldPixelHeights(2) );
+ else % limit to minimum distance from upper neighbor
+ delta = min( delta, oldPixelHeights(1) - minimumHeights(1) );
+ end
+ oldHeights = obj.Heights_(loc:loc+1);
+ newPixelHeights = oldPixelHeights - delta * [1;-1];
+ if oldHeights(1) < 0 && oldHeights(2) < 0 % weight, weight
+ newHeights = oldHeights .* newPixelHeights ./ oldPixelHeights;
+ elseif oldHeights(1) < 0 && oldHeights(2) >= 0 % weight, pixels
+ newHeights = [oldHeights(1) * newPixelHeights(1) / ...
+ oldPixelHeights(1); newPixelHeights(2)];
+ elseif oldHeights(1) >= 0 && oldHeights(2) < 0 % pixels, weight
+ newHeights = [newPixelHeights(1); oldHeights(2) * ...
+ newPixelHeights(2) / oldPixelHeights(2)];
+ else % sizes(1) >= 0 && sizes(2) >= 0 % pixels, pixels
+ newHeights = newPixelHeights;
+ end
+ obj.Heights_(loc:loc+1) = newHeights;
+ elseif loc < 0
+ root = groot();
+ delta = root.PointerLocation(1) - obj.MousePressLocation(1);
+ iw = -loc;
+ jw = -loc + 1;
+ r = numel( obj.Heights_ );
+ ic = r * (-loc-1) + 1;
+ jc = r * -loc + 1;
+ divider = obj.ColumnDividers(iw);
+ contents = obj.Contents_;
+ ip = uix.getPosition( contents(ic), 'pixels' );
+ jp = uix.getPosition( contents(jc), 'pixels' );
+ oldPixelWidths = [ip(3); jp(3)];
+ minimumWidths = obj.MinimumWidths_(iw:jw,:);
+ if delta < 0 % limit to minimum distance from left neighbor
+ delta = max( delta, minimumWidths(1) - oldPixelWidths(1) );
+ else % limit to minimum distance from right neighbor
+ delta = min( delta, oldPixelWidths(2) - minimumWidths(2) );
+ end
+ oldWidths = obj.Widths_(iw:jw);
+ newPixelWidths = oldPixelWidths + delta * [1;-1];
+ if oldWidths(1) < 0 && oldWidths(2) < 0 % weight, weight
+ newWidths = oldWidths .* newPixelWidths ./ oldPixelWidths;
+ elseif oldWidths(1) < 0 && oldWidths(2) >= 0 % weight, pixels
+ newWidths = [oldWidths(1) * newPixelWidths(1) / ...
+ oldPixelWidths(1); newPixelWidths(2)];
+ elseif oldWidths(1) >= 0 && oldWidths(2) < 0 % pixels, weight
+ newWidths = [newPixelWidths(1); oldWidths(2) * ...
+ newPixelWidths(2) / oldPixelWidths(2)];
+ else % sizes(1) >= 0 && sizes(2) >= 0 % pixels, pixels
+ newWidths = newPixelWidths;
+ end
+ obj.Widths_(iw:jw) = newWidths;
+ else
+ return
+ end
+
+ % Deactivate divider
+ obj.FrontDivider.Visible = 'off';
+ divider.Visible = 'on';
+
+ % Reset state at button down
+ obj.ActiveDivider = 0;
+ obj.ActiveDividerPosition = [NaN NaN NaN NaN];
+ obj.MousePressLocation = [NaN NaN];
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % onMouseRelease
+
+ function onMouseMotion( obj, source, eventData )
+ %onMouseMotion Handler for WindowMouseMotion events
+
+ loc = obj.ActiveDivider;
+ if loc == 0 % hovering, update pointer
+ obj.updateMousePointer( source, eventData );
+ elseif loc > 0 % dragging row divider
+ root = groot();
+ delta = root.PointerLocation(2) - obj.MousePressLocation(2);
+ ih = loc;
+ jh = loc + 1;
+ ic = loc;
+ jc = loc + 1;
+ contents = obj.Contents_;
+ ip = uix.getPosition( contents(ic), 'pixels' );
+ jp = uix.getPosition( contents(jc), 'pixels' );
+ oldPixelHeights = [ip(4); jp(4)];
+ minimumHeights = obj.MinimumHeights_(ih:jh,:);
+ if delta < 0 % limit to minimum distance from lower neighbor
+ delta = max( delta, minimumHeights(2) - oldPixelHeights(2) );
+ else % limit to minimum distance from upper neighbor
+ delta = min( delta, oldPixelHeights(1) - minimumHeights(1) );
+ end
+ obj.FrontDivider.Position = ...
+ obj.ActiveDividerPosition + [0 delta 0 0];
+ else % loc < 0, dragging column divider
+ root = groot();
+ delta = root.PointerLocation(1) - obj.MousePressLocation(1);
+ iw = -loc;
+ jw = -loc + 1;
+ r = numel( obj.Heights_ );
+ ic = r * (-loc-1) + 1;
+ jc = r * -loc + 1;
+ contents = obj.Contents_;
+ ip = uix.getPosition( contents(ic), 'pixels' );
+ jp = uix.getPosition( contents(jc), 'pixels' );
+ oldPixelWidths = [ip(3); jp(3)];
+ minimumWidths = obj.MinimumWidths_(iw:jw,:);
+ if delta < 0 % limit to minimum distance from left neighbor
+ delta = max( delta, minimumWidths(1) - oldPixelWidths(1) );
+ else % limit to minimum distance from right neighbor
+ delta = min( delta, oldPixelWidths(2) - minimumWidths(2) );
+ end
+ obj.FrontDivider.Position = ...
+ obj.ActiveDividerPosition + [delta 0 0 0];
+ end
+
+ end % onMouseMotion
+
+ function onBackgroundColorChanged( obj, ~, ~ )
+ %onBackgroundColorChanged Handler for BackgroundColor changes
+
+ backgroundColor = obj.BackgroundColor;
+ highlightColor = min( [backgroundColor / 0.75; 1 1 1] );
+ shadowColor = max( [backgroundColor * 0.75; 0 0 0] );
+ rowDividers = obj.RowDividers;
+ for ii = 1:numel( rowDividers )
+ rowDivider = rowDividers(ii);
+ rowDivider.BackgroundColor = backgroundColor;
+ rowDivider.HighlightColor = highlightColor;
+ rowDivider.ShadowColor = shadowColor;
+ end
+ columnDividers = obj.ColumnDividers;
+ for jj = 1:numel( columnDividers )
+ columnDivider = columnDividers(jj);
+ columnDivider.BackgroundColor = backgroundColor;
+ columnDivider.HighlightColor = highlightColor;
+ columnDivider.ShadowColor = shadowColor;
+ end
+ frontDivider = obj.FrontDivider;
+ frontDivider.BackgroundColor = shadowColor;
+
+ end % onBackgroundColorChanged
+
+ end % event handlers
+
+ methods( Access = protected )
+
+ function redraw( obj )
+ %redraw Redraw contents
+ %
+ % c.redraw() redraws the container c.
+
+ % Call superclass method
+ redraw@uix.Grid( obj )
+
+ % Create or destroy column dividers
+ b = numel( obj.ColumnDividers ); % current number of dividers
+ c = max( [numel( obj.Widths_ )-1 0] ); % required number of dividers
+ if b < c % create
+ for ii = b+1:c
+ columnDivider = uix.Divider( 'Parent', obj, ...
+ 'Orientation', 'vertical', ...
+ 'BackgroundColor', obj.BackgroundColor );
+ obj.ColumnDividers(ii,:) = columnDivider;
+ end
+ elseif b > c % destroy
+ % Destroy dividers
+ delete( obj.ColumnDividers(c+1:b,:) )
+ obj.ColumnDividers(c+1:b,:) = [];
+ % Update pointer
+ if c == 0 && strcmp( obj.Pointer, 'left' )
+ obj.unsetPointer()
+ end
+ end
+
+ % Create or destroy row dividers
+ q = numel( obj.RowDividers ); % current number of dividers
+ r = max( [numel( obj.Heights_ )-1 0] ); % required number of dividers
+ if q < r % create
+ for ii = q+1:r
+ columnDivider = uix.Divider( 'Parent', obj, ...
+ 'Orientation', 'horizontal', ...
+ 'BackgroundColor', obj.BackgroundColor );
+ obj.RowDividers(ii,:) = columnDivider;
+ end
+ % Bring front divider to the front
+ frontDivider = obj.FrontDivider;
+ frontDivider.Parent = [];
+ frontDivider.Parent = obj;
+ elseif q > r % destroy
+ % Destroy dividers
+ delete( obj.RowDividers(r+1:q,:) )
+ obj.RowDividers(r+1:q,:) = [];
+ % Update pointer
+ if r == 0 && strcmp( obj.Pointer, 'top' )
+ obj.unsetPointer()
+ end
+ end
+
+ % Compute container bounds
+ bounds = hgconvertunits( ancestor( obj, 'figure' ), ...
+ [0 0 1 1], 'normalized', 'pixels', obj );
+
+ % Retrieve size properties
+ widths = obj.Widths_;
+ minimumWidths = obj.MinimumWidths_;
+ heights = obj.Heights_;
+ minimumHeights = obj.MinimumHeights_;
+ padding = obj.Padding_;
+ spacing = obj.Spacing_;
+
+ % Compute row divider positions
+ xRowPositions = [padding + 1, max( bounds(3) - 2 * padding, 1 )];
+ xRowPositions = repmat( xRowPositions, [r 1] );
+ yRowSizes = uix.calcPixelSizes( bounds(4), heights, ...
+ minimumHeights, padding, spacing );
+ yRowPositions = [bounds(4) - cumsum( yRowSizes(1:r,:) ) - padding - ...
+ spacing * transpose( 1:r ) + 1, repmat( spacing, [r 1] )];
+ rowPositions = [xRowPositions(:,1), yRowPositions(:,1), ...
+ xRowPositions(:,2), yRowPositions(:,2)];
+
+ % Compute column divider positions
+ xColumnSizes = uix.calcPixelSizes( bounds(3), widths, ...
+ minimumWidths, padding, spacing );
+ xColumnPositions = [cumsum( xColumnSizes(1:c,:) ) + padding + ...
+ spacing * transpose( 0:c-1 ) + 1, repmat( spacing, [c 1] )];
+ yColumnPositions = [padding + 1, max( bounds(4) - 2 * padding, 1 )];
+ yColumnPositions = repmat( yColumnPositions, [c 1] );
+ columnPositions = [xColumnPositions(:,1), yColumnPositions(:,1), ...
+ xColumnPositions(:,2), yColumnPositions(:,2)];
+
+ % Position row dividers
+ for ii = 1:r
+ rowDivider = obj.RowDividers(ii);
+ rowDivider.Position = rowPositions(ii,:);
+ switch obj.DividerMarkings_
+ case 'on'
+ rowDivider.Markings = cumsum( xColumnSizes ) + ...
+ spacing * transpose( 0:c ) - xColumnSizes / 2;
+ case 'off'
+ rowDivider.Markings = zeros( [0 1] );
+ end
+ end
+
+ % Position column dividers
+ for ii = 1:c
+ columnDivider = obj.ColumnDividers(ii);
+ columnDivider.Position = columnPositions(ii,:);
+ switch obj.DividerMarkings_
+ case 'on'
+ columnDivider.Markings = cumsum( yRowSizes ) + ...
+ spacing * transpose( 0:r ) - yRowSizes / 2;
+ case 'off'
+ columnDivider.Markings = zeros( [0 1] );
+ end
+ end
+
+ end % redraw
+
+ function reparent( obj, oldFigure, newFigure )
+ %reparent Reparent container
+ %
+ % c.reparent(a,b) reparents the container c from the figure a
+ % to the figure b.
+
+ % Update listeners
+ if isempty( newFigure )
+ mousePressListener = event.listener.empty( [0 0] );
+ mouseReleaseListener = event.listener.empty( [0 0] );
+ mouseMotionListener = event.listener.empty( [0 0] );
+ else
+ mousePressListener = event.listener( newFigure, ...
+ 'WindowMousePress', @obj.onMousePress );
+ mouseReleaseListener = event.listener( newFigure, ...
+ 'WindowMouseRelease', @obj.onMouseRelease );
+ mouseMotionListener = event.listener( newFigure, ...
+ 'WindowMouseMotion', @obj.onMouseMotion );
+ end
+ obj.MousePressListener = mousePressListener;
+ obj.MouseReleaseListener = mouseReleaseListener;
+ obj.MouseMotionListener = mouseMotionListener;
+
+ % Call superclass method
+ reparent@uix.Grid( obj, oldFigure, newFigure )
+
+ % Update pointer
+ if ~isempty( oldFigure ) && ~strcmp( obj.Pointer, 'unset' )
+ obj.unsetPointer()
+ end
+
+ end % reparent
+
+ end % template methods
+
+ methods( Access = protected )
+
+ function updateMousePointer ( obj, source, eventData )
+
+ oldPointer = obj.Pointer;
+ if any( obj.RowDividers.isMouseOver( eventData ) )
+ newPointer = 'top';
+ elseif any( obj.ColumnDividers.isMouseOver( eventData ) )
+ newPointer = 'left';
+ else
+ newPointer = 'unset';
+ end
+ switch newPointer
+ case oldPointer % no change
+ % do nothing
+ case 'unset' % change, unset
+ obj.unsetPointer()
+ otherwise % change, set
+ obj.setPointer( source, newPointer )
+ end
+
+ end % updateMousePointer
+
+ end % helpers methods
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/HBox.m b/studio_functions/GUI Layout Toolbox/layout/+uix/HBox.m
new file mode 100644
index 00000000..11ffd9c7
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/HBox.m
@@ -0,0 +1,189 @@
+classdef HBox < uix.Box
+ %uix.HBox Horizontal box
+ %
+ % b = uix.HBox(p1,v1,p2,v2,...) constructs a horizontal box and sets
+ % parameter p1 to value v1, etc.
+ %
+ % A horizontal box lays out contents from left to right.
+ %
+ % See also: uix.VBox, uix.Grid, uix.HButtonBox, uix.HBoxFlex
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Access = public, Dependent, AbortSet )
+ Widths % widths of contents, in pixels and/or weights
+ MinimumWidths % minimum widths of contents, in pixels
+ end
+
+ properties( Access = protected )
+ Widths_ = zeros( [0 1] ) % backing for Widths
+ MinimumWidths_ = zeros( [0 1] ) % backing for MinimumWidths
+ end
+
+ methods
+
+ function obj = HBox( varargin )
+ %uix.HBox Horizontal box constructor
+ %
+ % b = uix.HBox() constructs a horizontal box.
+ %
+ % b = uix.HBox(p1,v1,p2,v2,...) sets parameter p1 to value v1,
+ % etc.
+
+ % Set properties
+ try
+ uix.set( obj, varargin{:} )
+ catch e
+ delete( obj )
+ e.throwAsCaller()
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = get.Widths( obj )
+
+ value = obj.Widths_;
+
+ end % get.Widths
+
+ function set.Widths( obj, value )
+
+ % For those who can't tell a column from a row...
+ if isrow( value )
+ value = transpose( value );
+ end
+
+ % Check
+ assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ...
+ 'Property ''Widths'' must be of type double.' )
+ assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ...
+ ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ...
+ 'Elements of property ''Widths'' must be real and finite.' )
+ assert( isequal( size( value ), size( obj.Contents_ ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Size of property ''Widths'' must match size of contents.' )
+
+ % Set
+ obj.Widths_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.Widths
+
+ function value = get.MinimumWidths( obj )
+
+ value = obj.MinimumWidths_;
+
+ end % get.MinimumWidths
+
+ function set.MinimumWidths( obj, value )
+
+ % For those who can't tell a column from a row...
+ if isrow( value )
+ value = transpose( value );
+ end
+
+ % Check
+ assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ...
+ 'Property ''MinimumWidths'' must be of type double.' )
+ assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ...
+ all( value >= 0 ), 'uix:InvalidPropertyValue', ...
+ 'Elements of property ''MinimumWidths'' must be non-negative.' )
+ assert( isequal( size( value ), size( obj.Widths_ ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Size of property ''MinimumWidths'' must match size of contents.' )
+
+ % Set
+ obj.MinimumWidths_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.MinimumWidths
+
+ end % accessors
+
+ methods( Access = protected )
+
+ function redraw( obj )
+ %redraw Redraw
+ %
+ % c.redraw() redraws the container c.
+
+ % Compute positions
+ bounds = hgconvertunits( ancestor( obj, 'figure' ), ...
+ [0 0 1 1], 'normalized', 'pixels', obj );
+ widths = obj.Widths_;
+ minimumWidths = obj.MinimumWidths_;
+ padding = obj.Padding_;
+ spacing = obj.Spacing_;
+ c = numel( widths );
+ xSizes = uix.calcPixelSizes( bounds(3), widths, ...
+ minimumWidths, padding, spacing );
+ xPositions = [cumsum( [0; xSizes(1:c-1,:)] ) + padding + ...
+ spacing * transpose( 0:c-1 ) + 1, xSizes];
+ yPositions = [padding + 1, max( bounds(4) - 2 * padding, 1 )];
+ yPositions = repmat( yPositions, [c 1] );
+ positions = [xPositions(:,1), yPositions(:,1), ...
+ xPositions(:,2), yPositions(:,2)];
+
+ % Set positions
+ children = obj.Contents_;
+ for ii = 1:numel( children )
+ uix.setPosition( children(ii), positions(ii,:), 'pixels' )
+ end
+
+ end % redraw
+
+ function addChild( obj, child )
+ %addChild Add child
+ %
+ % c.addChild(d) adds the child d to the container c.
+
+ % Add to sizes
+ obj.Widths_(end+1,:) = -1;
+ obj.MinimumWidths_(end+1,:) = 1;
+
+ % Call superclass method
+ addChild@uix.Box( obj, child )
+
+ end % addChild
+
+ function removeChild( obj, child )
+ %removeChild Remove child
+ %
+ % c.removeChild(d) removes the child d from the container c.
+
+ % Remove from sizes
+ tf = obj.Contents_ == child;
+ obj.Widths_(tf,:) = [];
+ obj.MinimumWidths_(tf,:) = [];
+
+ % Call superclass method
+ removeChild@uix.Box( obj, child )
+
+ end % removeChild
+
+ function reorder( obj, indices )
+ %reorder Reorder contents
+ %
+ % c.reorder(i) reorders the container contents using indices
+ % i, c.Contents = c.Contents(i).
+
+ % Reorder
+ obj.Widths_ = obj.Widths_(indices,:);
+ obj.MinimumWidths_ = obj.MinimumWidths_(indices,:);
+
+ % Call superclass method
+ reorder@uix.Box( obj, indices )
+
+ end % reorder
+
+ end % template methods
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/HBoxFlex.m b/studio_functions/GUI Layout Toolbox/layout/+uix/HBoxFlex.m
new file mode 100644
index 00000000..43a7cdee
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/HBoxFlex.m
@@ -0,0 +1,351 @@
+classdef HBoxFlex < uix.HBox & uix.mixin.Flex
+ %uix.HBoxFlex Flexible horizontal box
+ %
+ % b = uix.HBoxFlex(p1,v1,p2,v2,...) constructs a flexible horizontal
+ % box and sets parameter p1 to value v1, etc.
+ %
+ % A horizontal box lays out contents from left to right. Users can
+ % resize contents by dragging the dividers.
+ %
+ % See also: uix.VBoxFlex, uix.GridFlex, uix.HBox, uix.HButtonBox
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Access = public, Dependent, AbortSet )
+ DividerMarkings % divider markings [on|off]
+ end
+
+ properties( Access = private )
+ ColumnDividers = uix.Divider.empty( [0 1] ) % column dividers
+ FrontDivider % front divider
+ DividerMarkings_ = 'on' % backing for DividerMarkings
+ MousePressListener = event.listener.empty( [0 0] ) % mouse press listener
+ MouseReleaseListener = event.listener.empty( [0 0] ) % mouse release listener
+ MouseMotionListener = event.listener.empty( [0 0] ) % mouse motion listener
+ ActiveDivider = 0 % active divider index
+ ActiveDividerPosition = [NaN NaN NaN NaN] % active divider position
+ MousePressLocation = [NaN NaN] % mouse press location
+ BackgroundColorListener % background color listener
+ end
+
+ methods
+
+ function obj = HBoxFlex( varargin )
+ %uix.HBoxFlex Flexible horizontal box constructor
+ %
+ % b = uix.HBoxFlex() constructs a flexible horizontal box.
+ %
+ % b = uix.HBoxFlex(p1,v1,p2,v2,...) sets parameter p1 to value
+ % v1, etc.
+
+ % Create front divider
+ frontDivider = uix.Divider( 'Parent', obj, ...
+ 'Orientation', 'vertical', ...
+ 'BackgroundColor', obj.BackgroundColor * 0.75, ...
+ 'Visible', 'off' );
+
+ % Create listeners
+ backgroundColorListener = event.proplistener( obj, ...
+ findprop( obj, 'BackgroundColor' ), 'PostSet', ...
+ @obj.onBackgroundColorChanged );
+
+ % Store properties
+ obj.FrontDivider = frontDivider;
+ obj.BackgroundColorListener = backgroundColorListener;
+
+ % Set Spacing property (may be overwritten by uix.set)
+ obj.Spacing = 5;
+
+ % Set properties
+ try
+ uix.set( obj, varargin{:} )
+ catch e
+ delete( obj )
+ e.throwAsCaller()
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = get.DividerMarkings( obj )
+
+ value = obj.DividerMarkings_;
+
+ end % get.DividerMarkings
+
+ function set.DividerMarkings( obj, value )
+
+ % Check
+ assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ...
+ 'uix:InvalidArgument', ...
+ 'Property ''DividerMarkings'' must be ''on'' or ''off'.' )
+
+ % Set
+ obj.DividerMarkings_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.DividerMarkings
+
+ end % accessors
+
+ methods( Access = protected )
+
+ function onMousePress( obj, source, eventData )
+ %onMousePress Handler for WindowMousePress events
+
+ % Check whether mouse is over a divider
+ loc = find( obj.ColumnDividers.isMouseOver( eventData ) );
+ if isempty( loc ), return, end
+
+ % Capture state at button down
+ divider = obj.ColumnDividers(loc);
+ obj.ActiveDivider = loc;
+ obj.ActiveDividerPosition = divider.Position;
+ root = groot();
+ obj.MousePressLocation = root.PointerLocation;
+
+ % Make sure the pointer is appropriate
+ obj.updateMousePointer( source, eventData );
+
+ % Activate divider
+ frontDivider = obj.FrontDivider;
+ frontDivider.Position = divider.Position;
+ divider.Visible = 'off';
+ frontDivider.Parent = [];
+ frontDivider.Parent = obj;
+ frontDivider.Visible = 'on';
+
+ end % onMousePress
+
+ function onMouseRelease( obj, ~, ~ )
+ %onMousePress Handler for WindowMouseRelease events
+
+ % Compute new positions
+ loc = obj.ActiveDivider;
+ if loc > 0
+ root = groot();
+ delta = root.PointerLocation(1) - obj.MousePressLocation(1);
+ iw = loc;
+ jw = loc + 1;
+ ic = loc;
+ jc = loc + 1;
+ divider = obj.ColumnDividers(loc);
+ contents = obj.Contents_;
+ ip = uix.getPosition( contents(ic), 'pixels' );
+ jp = uix.getPosition( contents(jc), 'pixels' );
+ oldPixelWidths = [ip(3); jp(3)];
+ minimumWidths = obj.MinimumWidths_(iw:jw,:);
+ if delta < 0 % limit to minimum distance from left neighbor
+ delta = max( delta, minimumWidths(1) - oldPixelWidths(1) );
+ else % limit to minimum distance from right neighbor
+ delta = min( delta, oldPixelWidths(2) - minimumWidths(2) );
+ end
+ oldWidths = obj.Widths_(iw:jw);
+ newPixelWidths = oldPixelWidths + delta * [1;-1];
+ if oldWidths(1) < 0 && oldWidths(2) < 0 % weight, weight
+ newWidths = oldWidths .* newPixelWidths ./ oldPixelWidths;
+ elseif oldWidths(1) < 0 && oldWidths(2) >= 0 % weight, pixels
+ newWidths = [oldWidths(1) * newPixelWidths(1) / ...
+ oldPixelWidths(1); newPixelWidths(2)];
+ elseif oldWidths(1) >= 0 && oldWidths(2) < 0 % pixels, weight
+ newWidths = [newPixelWidths(1); oldWidths(2) * ...
+ newPixelWidths(2) / oldPixelWidths(2)];
+ else % sizes(1) >= 0 && sizes(2) >= 0 % pixels, pixels
+ newWidths = newPixelWidths;
+ end
+ obj.Widths_(iw:jw) = newWidths;
+ else
+ return
+ end
+
+ % Deactivate divider
+ obj.FrontDivider.Visible = 'off';
+ divider.Visible = 'on';
+
+ % Reset state at button down
+ obj.ActiveDivider = 0;
+ obj.ActiveDividerPosition = [NaN NaN NaN NaN];
+ obj.MousePressLocation = [NaN NaN];
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % onMouseRelease
+
+ function onMouseMotion( obj, source, eventData )
+ %onMouseMotion Handler for WindowMouseMotion events
+
+ loc = obj.ActiveDivider;
+ if loc == 0 % hovering, update pointer
+ obj.updateMousePointer( source, eventData );
+ else % dragging column divider
+ root = groot();
+ delta = root.PointerLocation(1) - obj.MousePressLocation(1);
+ iw = loc;
+ jw = loc + 1;
+ ic = loc;
+ jc = loc + 1;
+ contents = obj.Contents_;
+ ip = uix.getPosition( contents(ic), 'pixels' );
+ jp = uix.getPosition( contents(jc), 'pixels' );
+ oldPixelWidths = [ip(3); jp(3)];
+ minimumWidths = obj.MinimumWidths_(iw:jw,:);
+ if delta < 0 % limit to minimum distance from left neighbor
+ delta = max( delta, minimumWidths(1) - oldPixelWidths(1) );
+ else % limit to minimum distance from right neighbor
+ delta = min( delta, oldPixelWidths(2) - minimumWidths(2) );
+ end
+ obj.FrontDivider.Position = ...
+ obj.ActiveDividerPosition + [delta 0 0 0];
+ end
+
+ end % onMouseMotion
+
+ function onBackgroundColorChanged( obj, ~, ~ )
+ %onBackgroundColorChanged Handler for BackgroundColor changes
+
+ backgroundColor = obj.BackgroundColor;
+ highlightColor = min( [backgroundColor / 0.75; 1 1 1] );
+ shadowColor = max( [backgroundColor * 0.75; 0 0 0] );
+ columnDividers = obj.ColumnDividers;
+ for jj = 1:numel( columnDividers )
+ columnDivider = columnDividers(jj);
+ columnDivider.BackgroundColor = backgroundColor;
+ columnDivider.HighlightColor = highlightColor;
+ columnDivider.ShadowColor = shadowColor;
+ end
+ frontDivider = obj.FrontDivider;
+ frontDivider.BackgroundColor = shadowColor;
+
+ end % onBackgroundColorChanged
+
+ end % event handlers
+
+ methods( Access = protected )
+
+ function redraw( obj )
+ %redraw Redraw contents
+ %
+ % c.redraw() redraws the container c.
+
+ % Call superclass method
+ redraw@uix.HBox( obj )
+
+ % Create or destroy column dividers
+ b = numel( obj.ColumnDividers ); % current number of dividers
+ c = max( [numel( obj.Widths_ )-1 0] ); % required number of dividers
+ if b < c % create
+ for ii = b+1:c
+ divider = uix.Divider( 'Parent', obj, ...
+ 'Orientation', 'vertical', ...
+ 'BackgroundColor', obj.BackgroundColor );
+ obj.ColumnDividers(ii,:) = divider;
+ end
+ elseif b > c % destroy
+ % Destroy dividers
+ delete( obj.ColumnDividers(c+1:b,:) )
+ obj.ColumnDividers(c+1:b,:) = [];
+ % Update pointer
+ if c == 0 && strcmp( obj.Pointer, 'left' )
+ obj.unsetPointer()
+ end
+ end
+
+ % Compute container bounds
+ bounds = hgconvertunits( ancestor( obj, 'figure' ), ...
+ [0 0 1 1], 'normalized', 'pixels', obj );
+
+ % Retrieve size properties
+ widths = obj.Widths_;
+ minimumWidths = obj.MinimumWidths_;
+ padding = obj.Padding_;
+ spacing = obj.Spacing_;
+
+ % Compute column divider positions
+ xColumnSizes = uix.calcPixelSizes( bounds(3), widths, ...
+ minimumWidths, padding, spacing );
+ xColumnPositions = [cumsum( xColumnSizes(1:c,:) ) + padding + ...
+ spacing * transpose( 0:c-1 ) + 1, repmat( spacing, [c 1] )];
+ yColumnPositions = [padding + 1, max( bounds(4) - 2 * padding, 1 )];
+ yColumnPositions = repmat( yColumnPositions, [c 1] );
+ columnPositions = [xColumnPositions(:,1), yColumnPositions(:,1), ...
+ xColumnPositions(:,2), yColumnPositions(:,2)];
+
+ % Position column dividers
+ for ii = 1:c
+ columnDivider = obj.ColumnDividers(ii);
+ columnDivider.Position = columnPositions(ii,:);
+ switch obj.DividerMarkings_
+ case 'on'
+ columnDivider.Markings = columnPositions(ii,4)/2;
+ case 'off'
+ columnDivider.Markings = zeros( [0 1] );
+ end
+ end
+
+ end % redraw
+
+ function reparent( obj, oldFigure, newFigure )
+ %reparent Reparent container
+ %
+ % c.reparent(a,b) reparents the container c from the figure a
+ % to the figure b.
+
+ % Update listeners
+ if isempty( newFigure )
+ mousePressListener = event.listener.empty( [0 0] );
+ mouseReleaseListener = event.listener.empty( [0 0] );
+ mouseMotionListener = event.listener.empty( [0 0] );
+ else
+ mousePressListener = event.listener( newFigure, ...
+ 'WindowMousePress', @obj.onMousePress );
+ mouseReleaseListener = event.listener( newFigure, ...
+ 'WindowMouseRelease', @obj.onMouseRelease );
+ mouseMotionListener = event.listener( newFigure, ...
+ 'WindowMouseMotion', @obj.onMouseMotion );
+ end
+ obj.MousePressListener = mousePressListener;
+ obj.MouseReleaseListener = mouseReleaseListener;
+ obj.MouseMotionListener = mouseMotionListener;
+
+ % Call superclass method
+ reparent@uix.HBox( obj, oldFigure, newFigure )
+
+ % Update pointer
+ if ~isempty( oldFigure ) && ~strcmp( obj.Pointer, 'unset' )
+ obj.unsetPointer()
+ end
+
+ end % reparent
+
+ end % template methods
+
+ methods( Access = protected )
+
+ function updateMousePointer ( obj, source, eventData )
+
+ oldPointer = obj.Pointer;
+ if any( obj.ColumnDividers.isMouseOver( eventData ) )
+ newPointer = 'left';
+ else
+ newPointer = 'unset';
+ end
+ switch newPointer
+ case oldPointer % no change
+ % do nothing
+ case 'unset' % change, unset
+ obj.unsetPointer()
+ otherwise % change, set
+ obj.setPointer( source, newPointer )
+ end
+
+ end % updateMousePointer
+
+ end % helpers methods
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/HButtonBox.m b/studio_functions/GUI Layout Toolbox/layout/+uix/HButtonBox.m
new file mode 100644
index 00000000..0f71f733
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/HButtonBox.m
@@ -0,0 +1,95 @@
+classdef HButtonBox < uix.ButtonBox
+ %uix.HButtonBox Horizontal button box
+ %
+ % b = uix.HButtonBox(p1,v1,p2,v2,...) constructs a horizontal button
+ % box and sets parameter p1 to value v1, etc.
+ %
+ % A horizontal button box lays out equally sized buttons from left to
+ % right.
+ %
+ % See also: uix.VButtonBox
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ methods
+
+ function obj = HButtonBox( varargin )
+ %uix.HButtonBox Horizontal button box constructor
+ %
+ % b = uix.HButtonBox() constructs a horizontal button box.
+ %
+ % b = uix.HButtonBox(p1,v1,p2,v2,...) sets parameter p1 to
+ % value v1, etc.
+
+ % Set properties
+ try
+ uix.set( obj, varargin{:} )
+ catch e
+ delete( obj )
+ e.throwAsCaller()
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods( Access = protected )
+
+ function redraw( obj )
+
+ % Compute positions
+ bounds = hgconvertunits( ancestor( obj, 'figure' ), ...
+ [0 0 1 1], 'normalized', 'pixels', obj );
+ buttonSize = obj.ButtonSize_;
+ padding = obj.Padding_;
+ spacing = obj.Spacing_;
+ c = numel( obj.Contents_ );
+ if 2 * padding + (c-1) * spacing + c * buttonSize(1) > bounds(3)
+ xSizes = uix.calcPixelSizes( bounds(3), -ones( [c 1] ), ...
+ ones( [c 1] ), padding, spacing ); % shrink to fit
+ else
+ xSizes = repmat( buttonSize(1), [c 1] );
+ end
+ switch obj.HorizontalAlignment
+ case 'left'
+ xPositions = [cumsum( [0; xSizes(1:c-1,:)] ) + ...
+ padding + spacing * transpose( 0:c-1 ) + 1, xSizes];
+ case 'center'
+ xPositions = [cumsum( [0; xSizes(1:c-1,:)] ) + ...
+ spacing * transpose( 0:c-1 ) + bounds(3) / 2 - ...
+ sum( xSizes ) / 2 - spacing * (c-1) / 2 + 1, ...
+ xSizes];
+ case 'right'
+ xPositions = [cumsum( [0; xSizes(1:c-1,:)] ) + ...
+ spacing * transpose( 0:c-1 ) + bounds(3) - ...
+ sum( xSizes ) - spacing * (c-1) - padding + 1, ...
+ xSizes];
+ end
+ if 2 * padding + buttonSize(2) > bounds(4)
+ ySizes = repmat( uix.calcPixelSizes( bounds(4), -1, 1, ...
+ padding, spacing ), [c 1] ); % shrink to fit
+ else
+ ySizes = repmat( buttonSize(2), [c 1] );
+ end
+ switch obj.VerticalAlignment
+ case 'top'
+ yPositions = [bounds(4) - ySizes - padding + 1, ySizes];
+ case 'middle'
+ yPositions = [(bounds(4) - ySizes) / 2 + 1, ySizes];
+ case 'bottom'
+ yPositions = [repmat( padding, [c 1] ) + 1, ySizes];
+ end
+ positions = [xPositions(:,1), yPositions(:,1), ...
+ xPositions(:,2), yPositions(:,2)];
+
+ % Set positions
+ children = obj.Contents_;
+ for ii = 1:numel( children )
+ uix.setPosition( children(ii), positions(ii,:), 'pixels' )
+ end
+
+ end % redraw
+
+ end % template methods
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Node.m b/studio_functions/GUI Layout Toolbox/layout/+uix/Node.m
new file mode 100644
index 00000000..e5e180fa
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/Node.m
@@ -0,0 +1,93 @@
+classdef ( Hidden ) Node < dynamicprops
+ %uix.Node Node
+ %
+ % n = uix.Node(o) creates a node for the handle o.
+ %
+ % Node is a helper class for managing trees of objects and associated
+ % listeners.
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( SetAccess = private )
+ Object % object
+ Children = uix.Node.empty( [0 1] ) % children
+ end
+
+ properties( Access = private )
+ ChildListeners = event.listener.empty( [0 1] ) % internal listeners
+ end
+
+ methods
+
+ function obj = Node( object )
+ %uix.Node Node
+ %
+ % n = uix.Node(o) creates a node for the handle o.
+
+ % Check
+ assert( isa( object, 'handle' ) && ...
+ isequal( size( object ), [1 1] ) && isvalid( object ), ...
+ 'uix:InvalidArgument', 'Object must be a handle.' )
+
+ % Set properties
+ obj.Object = object;
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function addChild( obj, child )
+ %addChild Add child
+ %
+ % n.addChild(c) adds the child node c to the parent node n.
+
+ % Check
+ assert( isa( child, 'uix.Node' ) && ...
+ isequal( size( child ), [1 1] ), ...
+ 'uix:InvalidArgument', 'Invalid node.' )
+
+ % Add
+ childListener = event.listener( child, ...
+ 'ObjectBeingDestroyed', @obj.onChildDeleted );
+ obj.Children(end+1,:) = child;
+ obj.ChildListeners(end+1,:) = childListener;
+
+ end % addChild
+
+ function removeChild( obj, child )
+ %removeChild Remove child
+ %
+ % n.removeChild(c) removes the child node c from the parent
+ % node n.
+
+ % Check
+ assert( isa( child, 'uix.Node' ) && ...
+ isequal( size( child ), [1 1] ), ...
+ 'uix:InvalidArgument', 'Invalid node.' )
+ assert( ismember( child, obj.Children ), ...
+ 'uix:ItemNotFound', 'Node not found.' )
+
+ % Remove
+ tf = child == obj.Children;
+ obj.Children(tf,:) = [];
+ obj.ChildListeners(tf,:) = [];
+
+ end % removeChild
+
+ end % public methods
+
+ methods( Access = private )
+
+ function onChildDeleted( obj, source, ~ )
+ %onChildDeleted Event handler for deletion of child nodes
+
+ % Remove
+ obj.removeChild( source )
+
+ end % onChildDeleted
+
+ end % event handlers
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Panel.m b/studio_functions/GUI Layout Toolbox/layout/+uix/Panel.m
new file mode 100644
index 00000000..0a416b8e
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/Panel.m
@@ -0,0 +1,58 @@
+classdef Panel < matlab.ui.container.Panel & uix.mixin.Panel
+ %uix.Panel Standard panel
+ %
+ % b = uix.Panel(p1,v1,p2,v2,...) constructs a standard panel and sets
+ % parameter p1 to value v1, etc.
+ %
+ % A card panel is a standard panel (uipanel) that shows one its
+ % contents and hides the others.
+ %
+ % See also: uix.CardPanel, uix.BoxPanel, uipanel
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ methods
+
+ function obj = Panel( varargin )
+ %uix.Panel Standard panel constructor
+ %
+ % p = uix.Panel() constructs a standard panel.
+ %
+ % p = uix.Panel(p1,v1,p2,v2,...) sets parameter p1 to value
+ % v1, etc.
+
+ % Set properties
+ try
+ uix.set( obj, varargin{:} )
+ catch e
+ delete( obj )
+ e.throwAsCaller()
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods( Access = protected )
+
+ function redraw( obj )
+
+ % Compute positions
+ bounds = hgconvertunits( ancestor( obj, 'figure' ), ...
+ [0 0 1 1], 'normalized', 'pixels', obj );
+ padding = obj.Padding_;
+ xSizes = uix.calcPixelSizes( bounds(3), -1, 1, padding, 0 );
+ ySizes = uix.calcPixelSizes( bounds(4), -1, 1, padding, 0 );
+ position = [padding+1 padding+1 xSizes ySizes];
+
+ % Redraw contents
+ selection = obj.Selection_;
+ if selection ~= 0
+ uix.setPosition( obj.Contents_(selection), position, 'pixels' )
+ end
+
+ end % redraw
+
+ end % template methods
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/PointerManager.m b/studio_functions/GUI Layout Toolbox/layout/+uix/PointerManager.m
new file mode 100644
index 00000000..b4b5d6c0
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/PointerManager.m
@@ -0,0 +1,152 @@
+classdef ( Hidden, Sealed ) PointerManager < handle
+ %uix.PointerManager Pointer manager
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( SetAccess = private )
+ Figure % figure
+ end
+
+ properties( Access = private )
+ Tokens % tokens
+ Pointers % pointers
+ NextToken % next token
+ PointerListener % listener
+ end
+
+ methods( Access = private )
+
+ function obj = PointerManager( figure )
+ %uix.PointerManager Create pointer manager
+ %
+ % m = uix.PointerManager(f) creates a pointer manager for the
+ % figure f.
+
+ obj.Figure = figure;
+ obj.Tokens = 0;
+ obj.Pointers = {figure.Pointer};
+ obj.NextToken = 1;
+ obj.PointerListener = event.proplistener( figure, ...
+ findprop( figure, 'Pointer' ), 'PostSet', ...
+ @obj.onPointerChanged );
+
+ end % constructor
+
+ end % structors
+
+ methods( Access = private )
+
+ function doSetPointer( obj, token, pointer )
+ %doSetPointer Set pointer
+ %
+ % m.doSetPointer(t,p) sets the pointer to p with the token t.
+
+ % Remove old entry
+ tf = obj.Tokens == token;
+ obj.Tokens(tf) = [];
+ obj.Pointers(tf) = [];
+
+ % Add new entry
+ obj.Tokens(end+1) = token;
+ obj.Pointers{end+1} = pointer;
+
+ % Set pointer
+ obj.PointerListener.Enabled = false;
+ obj.Figure.Pointer = pointer;
+ obj.PointerListener.Enabled = true;
+
+ end % doSetPointer
+
+ function doUnsetPointer( obj, token )
+ %doUnsetPointer Unset pointer
+ %
+ % m.doUnsetPointer(s) unsets the pointer with the token t.
+
+ % Remove old entry
+ tf = obj.Tokens == token;
+ obj.Tokens(tf) = [];
+ obj.Pointers(tf) = [];
+
+ % Update pointer
+ obj.PointerListener.Enabled = false;
+ obj.Figure.Pointer = obj.Pointers{end};
+ obj.PointerListener.Enabled = true;
+
+ end % doUnsetPointer
+
+ end % private methods
+
+ methods
+
+ function onPointerChanged( obj, ~, ~ )
+ %onPointerChanged Event handler
+
+ % Log as unknown setter
+ obj.doSetPointer( 0, obj.Figure.Pointer )
+
+ end % onPointerChanged
+
+ end % event handlers
+
+ methods( Static )
+
+ function token = setPointer( figure, pointer )
+ %setPointer Set pointer
+ %
+ % t = uix.PointerManager.setPointer(f,p) sets the pointer of
+ % the figure f to p. The returned token t can be used
+ % subsequently to unset the pointer.
+
+ % Get pointer manager
+ obj = uix.PointerManager.getInstance( figure );
+
+ % Retrieve token
+ token = obj.NextToken;
+
+ % Set
+ obj.doSetPointer( token, pointer )
+
+ % Increment token
+ obj.NextToken = token + 1;
+
+ end % setPointer
+
+ function unsetPointer( figure, token )
+ %unsetPointer Unset pointer
+ %
+ % uix.PointerManager.unsetPointer(f,t) unsets the pointer of
+ % the figure f using the token t.
+
+ % Check ID
+ validateattributes( token, {'numeric'}, {'scalar','integer','>',0} )
+
+ % Get pointer manager
+ obj = uix.PointerManager.getInstance( figure );
+
+ % Unset
+ obj.doUnsetPointer( token )
+
+ end % unsetPointer
+
+ function obj = getInstance( figure )
+ %getInstance Get pointer manager
+ %
+ % m = uix.PointerManager.getInstance(f) gets the pointer
+ % manager for the figure f.
+
+ % Get pointer manager
+ name = 'UIxPointerManager';
+ if isprop( figure, name ) % existing, retrieve
+ obj = figure.( name );
+ else % new, create and store
+ obj = uix.PointerManager( figure );
+ p = addprop( figure, name );
+ p.Hidden = true;
+ figure.( name ) = obj;
+ end
+
+ end % getInstance
+
+ end % static methods
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NoEdge_NotSelected.png b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NoEdge_NotSelected.png
new file mode 100644
index 00000000..30d4bb42
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NoEdge_NotSelected.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NoEdge_Selected.png b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NoEdge_Selected.png
new file mode 100644
index 00000000..c0c8b56d
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NoEdge_Selected.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NotSelected_NoEdge.png b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NotSelected_NoEdge.png
new file mode 100644
index 00000000..30bf1da2
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NotSelected_NoEdge.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NotSelected_NotSelected.png b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NotSelected_NotSelected.png
new file mode 100644
index 00000000..c6aca7c4
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NotSelected_NotSelected.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NotSelected_Selected.png b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NotSelected_Selected.png
new file mode 100644
index 00000000..e96782b3
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NotSelected_Selected.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_Selected_NoEdge.png b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_Selected_NoEdge.png
new file mode 100644
index 00000000..f23a1b09
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_Selected_NoEdge.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_Selected_NotSelected.png b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_Selected_NotSelected.png
new file mode 100644
index 00000000..4758ca3f
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_Selected_NotSelected.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/ScrollingPanel.m b/studio_functions/GUI Layout Toolbox/layout/+uix/ScrollingPanel.m
new file mode 100644
index 00000000..b2834cca
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/ScrollingPanel.m
@@ -0,0 +1,698 @@
+classdef ScrollingPanel < uix.Container & uix.mixin.Panel
+ %uix.ScrollingPanel Scrolling panel
+ %
+ % p = uix.ScrollingPanel(p1,v1,p2,v2,...) constructs a scrolling panel
+ % and sets parameter p1 to value v1, etc.
+ %
+ % A scrolling panel is a standard container (uicontainer) that shows
+ % one its contents and hides the others.
+ %
+ % See also: uix.Panel, uix.BoxPanel, uix.TabPanel, uicontainer
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Dependent )
+ Heights % heights of contents, in pixels and/or weights
+ MinimumHeights % minimum heights of contents, in pixels
+ VerticalOffsets % vertical offsets of contents, in pixels
+ VerticalSteps % vertical slider steps, in pixels
+ Widths % widths of contents, in pixels and/or weights
+ MinimumWidths % minimum widths of contents, in pixels
+ HorizontalOffsets % horizontal offsets of contents, in pixels
+ HorizontalSteps % horizontal slider steps, in pixels
+ MouseWheelEnabled % mouse wheel scrolling enabled [on|off]
+ end
+
+ properties( Access = protected )
+ Heights_ = zeros( [0 1] ) % backing for Heights
+ MinimumHeights_ = zeros( [0 1] ) % backing for MinimumHeights
+ Widths_ = zeros( [0 1] ) % backing for Widths
+ MinimumWidths_ = zeros( [0 1] ) % backing for MinimumWidths
+ HorizontalSliders = matlab.ui.control.UIControl.empty( [0 1] ) % sliders
+ VerticalSliders = matlab.ui.control.UIControl.empty( [0 1] ) % sliders
+ BlankingPlates = matlab.ui.control.UIControl.empty( [0 1] ) % blanking plates
+ HorizontalSteps_ = zeros( [0 1] ) % steps
+ VerticalSteps_ = zeros( [0 1] ) % steps
+ end
+
+ properties( Access = private )
+ MouseWheelListener = [] % mouse listener
+ MouseWheelEnabled_ = 'on' % backing for MouseWheelEnabled
+ ScrollingListener = [] % slider listener
+ ScrolledListener = [] % slider listener
+ BackgroundColorListener % property listener
+ end
+
+ properties( Constant, Access = protected )
+ SliderSize = 20 % slider size, in pixels
+ SliderStep = 10 % slider step, in pixels
+ end
+
+ events( NotifyAccess = private )
+ Scrolling
+ Scrolled
+ end
+
+ methods
+
+ function obj = ScrollingPanel( varargin )
+ %uix.ScrollingPanel Scrolling panel constructor
+ %
+ % p = uix.ScrollingPanel() constructs a scrolling panel.
+ %
+ % p = uix.ScrollingPanel(p1,v1,p2,v2,...) sets parameter p1 to
+ % value v1, etc.
+
+ % Create listeners
+ backgroundColorListener = event.proplistener( obj, ...
+ findprop( obj, 'BackgroundColor' ), 'PostSet', ...
+ @obj.onBackgroundColorChanged );
+
+ % Store properties
+ obj.BackgroundColorListener = backgroundColorListener;
+
+ % Set properties
+ try
+ uix.set( obj, varargin{:} )
+ catch e
+ delete( obj )
+ e.throwAsCaller()
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = get.Heights( obj )
+
+ value = obj.Heights_;
+
+ end % get.Heights
+
+ function set.Heights( obj, value )
+
+ % For those who can't tell a column from a row...
+ if isrow( value )
+ value = transpose( value );
+ end
+
+ % Check
+ assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ...
+ 'Property ''Heights'' must be of type double.' )
+ assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ...
+ ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ...
+ 'Elements of property ''Heights'' must be real and finite.' )
+ assert( isequal( size( value ), size( obj.Contents_ ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Size of property ''Heights'' must match size of contents.' )
+
+ % Set
+ obj.Heights_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.Heights
+
+ function value = get.MinimumHeights( obj )
+
+ value = obj.MinimumHeights_;
+
+ end % get.MinimumHeights
+
+ function set.MinimumHeights( obj, value )
+
+ % For those who can't tell a column from a row...
+ if isrow( value )
+ value = transpose( value );
+ end
+
+ % Check
+ assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ...
+ 'Property ''MinimumHeights'' must be of type double.' )
+ assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ...
+ all( value >= 0 ), 'uix:InvalidPropertyValue', ...
+ 'Elements of property ''MinimumHeights'' must be non-negative.' )
+ assert( isequal( size( value ), size( obj.Heights_ ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Size of property ''MinimumHeights'' must match size of contents.' )
+
+ % Set
+ obj.MinimumHeights_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.MinimumHeights
+
+ function value = get.VerticalOffsets( obj )
+
+ sliders = obj.VerticalSliders;
+ if isempty( sliders )
+ value = zeros( size( sliders ) );
+ else
+ value = -vertcat( sliders.Value ) - 1;
+ value(value<0) = 0;
+ end
+
+ end % get.VerticalOffsets
+
+ function set.VerticalOffsets( obj, value )
+
+ % Check
+ assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ...
+ 'Property ''VerticalOffsets'' must be of type double.' )
+ assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ...
+ ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ...
+ 'Elements of property ''VerticalOffsets'' must be real and finite.' )
+ assert( isequal( size( value ), size( obj.Contents_ ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Size of property ''VerticalOffsets'' must match size of contents.' )
+
+ % Set
+ sliders = obj.VerticalSliders;
+ for ii = 1:numel( sliders )
+ sliders(ii).Value = -value(ii) - 1;
+ end
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.VerticalOffsets
+
+ function value = get.VerticalSteps( obj )
+
+ value = obj.VerticalSteps_;
+
+ end % get.VerticalSteps
+
+ function set.VerticalSteps( obj, value )
+
+ % For those who can't tell a column from a row...
+ if isrow( value )
+ value = transpose( value );
+ end
+
+ % Check
+ assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ...
+ 'Property ''VerticalSteps'' must be of type double.' )
+ assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ...
+ ~any( isnan( value ) ) && all( value > 0 ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Elements of property ''VerticalSteps'' must be real, finite and positive.' )
+ assert( isequal( size( value ), size( obj.Contents_ ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Size of property ''VerticalSteps'' must match size of contents.' )
+
+ % Set
+ obj.VerticalSteps_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.VerticalSteps
+
+ function value = get.Widths( obj )
+
+ value = obj.Widths_;
+
+ end % get.Widths
+
+ function set.Widths( obj, value )
+
+ % For those who can't tell a column from a row...
+ if isrow( value )
+ value = transpose( value );
+ end
+
+ % Check
+ assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ...
+ 'Property ''Widths'' must be of type double.' )
+ assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ...
+ ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ...
+ 'Elements of property ''Widths'' must be real and finite.' )
+ assert( isequal( size( value ), size( obj.Contents_ ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Size of property ''Widths'' must match size of contents.' )
+
+ % Set
+ obj.Widths_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.Widths
+
+ function value = get.MinimumWidths( obj )
+
+ value = obj.MinimumWidths_;
+
+ end % get.MinimumWidths
+
+ function set.MinimumWidths( obj, value )
+
+ % For those who can't tell a column from a row...
+ if isrow( value )
+ value = transpose( value );
+ end
+
+ % Check
+ assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ...
+ 'Property ''MinimumWidths'' must be of type double.' )
+ assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ...
+ all( value >= 0 ), 'uix:InvalidPropertyValue', ...
+ 'Elements of property ''MinimumWidths'' must be non-negative.' )
+ assert( isequal( size( value ), size( obj.Widths_ ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Size of property ''MinimumWidths'' must match size of contents.' )
+
+ % Set
+ obj.MinimumWidths_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.MinimumWidths
+
+ function value = get.HorizontalOffsets( obj )
+
+ sliders = obj.HorizontalSliders;
+ if isempty( sliders )
+ value = zeros( size( sliders ) );
+ else
+ value = vertcat( sliders.Value );
+ value(value<0) = 0;
+ end
+
+ end % get.HorizontalOffsets
+
+ function set.HorizontalOffsets( obj, value )
+
+ % Check
+ assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ...
+ 'Property ''HorizontalOffsets'' must be of type double.' )
+ assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ...
+ ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ...
+ 'Elements of property ''HorizontalOffsets'' must be real and finite.' )
+ assert( isequal( size( value ), size( obj.Contents_ ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Size of property ''HorizontalOffsets'' must match size of contents.' )
+
+ % Set
+ sliders = obj.HorizontalSliders;
+ for ii = 1:numel( sliders )
+ sliders(ii).Value = value(ii);
+ end
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.HorizontalOffsets
+
+ function value = get.HorizontalSteps( obj )
+
+ value = obj.HorizontalSteps_;
+
+ end % get.HorizontalSteps
+
+ function set.HorizontalSteps( obj, value )
+
+ % For those who can't tell a column from a row...
+ if isrow( value )
+ value = transpose( value );
+ end
+
+ % Check
+ assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ...
+ 'Property ''HorizontalSteps'' must be of type double.' )
+ assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ...
+ ~any( isnan( value ) ) && all( value > 0 ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Elements of property ''HorizontalSteps'' must be real, finite and positive.' )
+ assert( isequal( size( value ), size( obj.Contents_ ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Size of property ''HorizontalSteps'' must match size of contents.' )
+
+ % Set
+ obj.HorizontalSteps_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.HorizontalSteps
+
+ function value = get.MouseWheelEnabled( obj )
+
+ value = obj.MouseWheelEnabled_;
+
+ end % get.MouseWheelEnabled
+
+ function set.MouseWheelEnabled( obj, value )
+
+ assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ...
+ 'uix:InvalidArgument', ...
+ 'Property ''MouseWheelEnabled'' must ''on'' or ''off''.' )
+ listener = obj.MouseWheelListener;
+ if ~isempty( listener )
+ listener.Enabled = strcmp( value, 'on' );
+ end
+ obj.MouseWheelEnabled_ = value;
+
+ end % set.MouseWheelEnabled
+
+ end % accessors
+
+ methods( Access = protected )
+
+ function redraw( obj )
+ %redraw Redraw
+
+ % Return if no contents
+ selection = obj.Selection_;
+ if selection == 0, return, end
+
+ % Retrieve width and height of selected contents
+ contentsWidth = obj.Widths_(selection);
+ minimumWidth = obj.MinimumWidths_(selection);
+ contentsHeight = obj.Heights_(selection);
+ minimumHeight = obj.MinimumHeights_(selection);
+
+ % Retrieve selected contents and corresponding decorations
+ child = obj.Contents_(selection);
+ vSlider = obj.VerticalSliders(selection);
+ hSlider = obj.HorizontalSliders(selection);
+ plate = obj.BlankingPlates(selection);
+
+ % Compute dimensions
+ bounds = hgconvertunits( ancestor( obj, 'figure' ), ...
+ [0 0 1 1], 'normalized', 'pixels', obj );
+ width = bounds(3);
+ height = bounds(4);
+ sliderSize = obj.SliderSize; % slider size
+ vSliderWidth = sliderSize * ...
+ (contentsHeight > height | ...
+ minimumHeight > height); % first pass
+ hSliderHeight = sliderSize * ...
+ (contentsWidth > width - vSliderWidth | ...
+ minimumWidth > width - vSliderWidth);
+ vSliderWidth = sliderSize * ...
+ (contentsHeight > height - hSliderHeight | ...
+ minimumHeight > height - hSliderHeight); % second pass
+ vSliderWidth = min( vSliderWidth, width ); % limit
+ hSliderHeight = min( hSliderHeight, height ); % limit
+ vSliderHeight = height - hSliderHeight;
+ hSliderWidth = width - vSliderWidth;
+ widths = uix.calcPixelSizes( width, ...
+ [contentsWidth;vSliderWidth], ...
+ [minimumWidth;vSliderWidth], 0, 0 );
+ contentsWidth = widths(1); % to be offset
+ heights = uix.calcPixelSizes( height, ...
+ [contentsHeight;hSliderHeight], ...
+ [minimumHeight;hSliderHeight], 0, 0 );
+ contentsHeight = heights(1); % to be offset
+
+ % Compute positions
+ contentsPosition = [1 1+hSliderHeight+vSliderHeight-contentsHeight contentsWidth contentsHeight];
+ vSliderPosition = [1+hSliderWidth 1+hSliderHeight vSliderWidth vSliderHeight];
+ hSliderPosition = [1 1 hSliderWidth hSliderHeight];
+ platePosition = [1+hSliderWidth 1 vSliderWidth hSliderHeight];
+
+ % Compute and set vertical slider properties
+ if vSliderWidth == 0 || vSliderHeight == 0 || vSliderHeight <= vSliderWidth
+ % Slider is invisible or incorrectly oriented
+ set( vSlider, 'Style', 'text', 'Enable', 'inactive', ...
+ 'Position', vSliderPosition, ...
+ 'Min', 0, 'Max', 1, 'Value', 1 )
+ else
+ % Compute properties
+ vSliderMin = 0;
+ vSliderMax = contentsHeight - vSliderHeight;
+ vSliderValue = -vSlider.Value; % negative sign convention
+ vSliderValue = max( vSliderValue, vSliderMin ); % limit
+ vSliderValue = min( vSliderValue, vSliderMax ); % limit
+ vStep = obj.VerticalSteps_(selection);
+ vSliderStep(1) = min( vStep / vSliderMax, 1 );
+ vSliderStep(2) = max( vSliderHeight / vSliderMax, vSliderStep(1) );
+ contentsPosition(2) = contentsPosition(2) + vSliderValue;
+ % Set properties
+ set( vSlider, 'Style', 'slider', 'Enable', 'on', ...
+ 'Position', vSliderPosition, ...
+ 'Min', -vSliderMax, 'Max', -vSliderMin, ...
+ 'Value', -vSliderValue, 'SliderStep', vSliderStep )
+ end
+
+ % Compute and set horizontal slider properties
+ if hSliderHeight == 0 || hSliderWidth == 0 || hSliderWidth <= hSliderHeight
+ % Slider is invisible or incorrectly oriented
+ set( hSlider, 'Style', 'text', 'Enable', 'inactive', ...
+ 'Position', hSliderPosition, ...
+ 'Min', -1, 'Max', 0, 'Value', -1 )
+ else
+ % Compute properties
+ hSliderMin = 0;
+ hSliderMax = contentsWidth - hSliderWidth;
+ hSliderValue = hSlider.Value; % positive sign convention
+ hSliderValue = max( hSliderValue, hSliderMin ); % limit
+ hSliderValue = min( hSliderValue, hSliderMax ); % limit
+ hStep = obj.HorizontalSteps_(selection);
+ hSliderStep(1) = min( hStep / hSliderMax, 1 );
+ hSliderStep(2) = max( hSliderWidth / hSliderMax, hSliderStep(1) );
+ contentsPosition(1) = contentsPosition(1) - hSliderValue;
+ % Set properties
+ set( hSlider, 'Style', 'slider', 'Enable', 'on', ...
+ 'Position', hSliderPosition, ...
+ 'Min', hSliderMin, 'Max', hSliderMax, ...
+ 'Value', hSliderValue, 'SliderStep', hSliderStep )
+ end
+
+ % Set contents and blanking plate positions
+ uix.setPosition( child, contentsPosition, 'pixels' )
+ set( plate, 'Position', platePosition )
+
+ end % redraw
+
+ function addChild( obj, child )
+ %addChild Add child
+ %
+ % c.addChild(d) adds the child d to the container c.
+
+ % Create decorations
+ verticalSlider = matlab.ui.control.UIControl( ...
+ 'Internal', true, 'Parent', obj, ...
+ 'Units', 'pixels', 'Style', 'slider', ...
+ 'BackgroundColor', obj.BackgroundColor );
+ horizontalSlider = matlab.ui.control.UIControl( ...
+ 'Internal', true, 'Parent', obj, ...
+ 'Units', 'pixels', 'Style', 'slider', ...
+ 'BackgroundColor', obj.BackgroundColor );
+ blankingPlate = matlab.ui.control.UIControl( ...
+ 'Internal', true, 'Parent', obj, ...
+ 'Units', 'pixels', 'Style', 'text', 'Enable', 'inactive', ...
+ 'BackgroundColor', obj.BackgroundColor );
+
+ % Add to sizes
+ obj.Widths_(end+1,:) = -1;
+ obj.MinimumWidths_(end+1,:) = 1;
+ obj.Heights_(end+1,:) = -1;
+ obj.MinimumHeights_(end+1,:) = 1;
+ obj.VerticalSliders(end+1,:) = verticalSlider;
+ obj.HorizontalSliders(end+1,:) = horizontalSlider;
+ obj.BlankingPlates(end+1,:) = blankingPlate;
+ obj.VerticalSteps_(end+1,:) = obj.SliderStep;
+ obj.HorizontalSteps_(end+1,:) = obj.SliderStep;
+ obj.updateSliderListeners()
+
+ % Call superclass method
+ addChild@uix.mixin.Panel( obj, child )
+
+ end % addChild
+
+ function removeChild( obj, child )
+ %removeChild Remove child
+ %
+ % c.removeChild(d) removes the child d from the container c.
+
+ % Identify child
+ tf = obj.Contents_ == child;
+
+ % Destroy decorations
+ delete( obj.VerticalSliders(tf,:) )
+ delete( obj.HorizontalSliders(tf,:) )
+ delete( obj.BlankingPlates(tf,:) )
+
+ % Remove from sizes
+ obj.Widths_(tf,:) = [];
+ obj.MinimumWidths_(tf,:) = [];
+ obj.Heights_(tf,:) = [];
+ obj.MinimumHeights_(tf,:) = [];
+ obj.VerticalSliders(tf,:) = [];
+ obj.HorizontalSliders(tf,:) = [];
+ obj.BlankingPlates(tf,:) = [];
+ obj.VerticalSteps_(tf,:) = [];
+ obj.HorizontalSteps_(tf,:) = [];
+ obj.updateSliderListeners()
+
+ % Call superclass method
+ removeChild@uix.mixin.Panel( obj, child )
+
+ end % removeChild
+
+ function reparent( obj, ~, newFigure )
+ %reparent Reparent container
+ %
+ % c.reparent(a,b) reparents the container c from the figure a
+ % to the figure b.
+
+ if isempty( newFigure )
+ obj.MouseWheelListener = [];
+ else
+ listener = event.listener( newFigure, ...
+ 'WindowScrollWheel', @obj.onMouseScrolled );
+ listener.Enabled = strcmp( obj.MouseWheelEnabled_, 'on' );
+ obj.MouseWheelListener = listener;
+ end
+
+ end % reparent
+
+ function reorder( obj, indices )
+ %reorder Reorder contents
+ %
+ % c.reorder(i) reorders the container contents using indices
+ % i, c.Contents = c.Contents(i).
+
+ % Reorder
+ obj.Widths_ = obj.Widths_(indices,:);
+ obj.MinimumWidths_ = obj.MinimumWidths_(indices,:);
+ obj.Heights_ = obj.Heights_(indices,:);
+ obj.MinimumHeights_ = obj.MinimumWidths_(indices,:);
+ obj.VerticalSliders = obj.VerticalSliders(indices,:);
+ obj.HorizontalSliders = obj.HorizontalSliders(indices,:);
+ obj.BlankingPlates = obj.BlankingPlates(indices,:);
+ obj.VerticalSteps_ = obj.VerticalSteps_(indices,:);
+ obj.HorizontalSteps_ = obj.HorizontalSteps_(indices,:);
+
+ % Call superclass method
+ reorder@uix.mixin.Panel( obj, indices )
+
+ end % reorder
+
+ function showSelection( obj )
+ %showSelection Show selected child, hide the others
+ %
+ % c.showSelection() shows the selected child of the container
+ % c, and hides the others.
+
+ % Call superclass method
+ showSelection@uix.mixin.Panel( obj )
+
+ % Show and hide sliders based on selection
+ selection = obj.Selection_;
+ for ii = 1:numel( obj.Contents_ )
+ if ii == selection
+ obj.VerticalSliders(ii).Visible = 'on';
+ obj.HorizontalSliders(ii).Visible = 'on';
+ obj.BlankingPlates(ii).Visible = 'on';
+ else
+ obj.VerticalSliders(ii).Visible = 'off';
+ obj.HorizontalSliders(ii).Visible = 'off';
+ obj.BlankingPlates(ii).Visible = 'off';
+ end
+ end
+
+ end % showSelection
+
+ end % template methods
+
+ methods( Access = private )
+
+ function onSliderScrolling( obj, ~, ~ )
+ %onSliderScrolling Event handler
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ % Raise event
+ notify( obj, 'Scrolling' )
+
+ end % onSliderScrolling
+
+ function onSliderScrolled( obj, ~, ~ )
+ %onSliderScrolled Event handler
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ % Raise event
+ notify( obj, 'Scrolled' )
+
+ end % onSliderScrolled
+
+ function onMouseScrolled( obj, ~, eventData )
+ %onMouseScrolled Event handler
+
+ sel = obj.Selection_;
+ if sel == 0
+ return
+ else
+ % Get pointer position and panel bounds
+ pp = getpixelposition( obj, true );
+ f = ancestor( obj, 'figure' );
+ cpu = f.CurrentPoint; % figure Units
+ cpwhu = [cpu 0 0]; % [x y] to [x y w h] for hgconvertunits
+ cpwh = hgconvertunits( f, cpwhu, f.Units, 'pixels', obj ); % pixels
+ cp = cpwh(1:2); % [x y w h] to [x y]
+
+ % Check that pointer is over panel
+ if cp(1) < pp(1) || cp(1) > pp(1) + pp(3) || ...
+ cp(2) < pp(2) || cp(2) > pp(2) + pp(4), return, end
+ % Scroll
+ if strcmp( obj.VerticalSliders(sel).Enable, 'on' ) % scroll vertically
+ delta = eventData.VerticalScrollCount * ...
+ eventData.VerticalScrollAmount * obj.VerticalSteps(sel);
+ obj.VerticalOffsets(sel) = obj.VerticalOffsets(sel) + delta;
+ elseif strcmp( obj.HorizontalSliders(sel).Enable, 'on' ) % scroll horizontally
+ delta = eventData.VerticalScrollCount * ...
+ eventData.VerticalScrollAmount * obj.HorizontalSteps(sel);
+ obj.HorizontalOffsets(sel) = obj.HorizontalOffsets(sel) + delta;
+ end
+ % Raise event
+ notify( obj, 'Scrolled' )
+ end
+
+ end % onMouseScrolled
+
+ function onBackgroundColorChanged( obj, ~, ~ )
+ %onBackgroundColorChanged Handler for BackgroundColor changes
+
+ set( obj.HorizontalSliders, 'BackgroundColor', obj.BackgroundColor )
+ set( obj.VerticalSliders, 'BackgroundColor', obj.BackgroundColor )
+ set( obj.BlankingPlates, 'BackgroundColor', obj.BackgroundColor )
+
+ end % onBackgroundColorChanged
+
+ end % event handlers
+
+ methods( Access = private )
+
+ function updateSliderListeners( obj )
+ %updateSliderListeners Update listeners to slider events
+
+ if isempty( obj.VerticalSliders )
+ obj.ScrollingListener = [];
+ obj.ScrolledListener = [];
+ else
+ obj.ScrollingListener = event.listener( ...
+ [obj.VerticalSliders; obj.HorizontalSliders], ...
+ 'ContinuousValueChange', @obj.onSliderScrolling );
+ obj.ScrolledListener = event.listener( ...
+ [obj.VerticalSliders; obj.HorizontalSliders], ...
+ 'Action', @obj.onSliderScrolled );
+ end
+
+ end % updateSliderListeners
+
+ end % helpers
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/SelectionData.m b/studio_functions/GUI Layout Toolbox/layout/+uix/SelectionData.m
new file mode 100644
index 00000000..d5ad69a5
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/SelectionData.m
@@ -0,0 +1,30 @@
+classdef( Hidden, Sealed ) SelectionData < event.EventData
+ %uix.SelectionData Event data for selection event
+ %
+ % e = uix.SelectionData(o,n) creates event data including the old
+ % value o and the new value n.
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( SetAccess = private )
+ OldValue % old value
+ NewValue % newValue
+ end
+
+ methods
+
+ function obj = SelectionData( oldValue, newValue )
+ %uix.SelectionData Event data for selection event
+ %
+ % e = uix.SelectionData(o,n) creates event data including the
+ % old value o and the new value n.
+
+ % Set properties
+ obj.OldValue = oldValue;
+ obj.NewValue = newValue;
+
+ end % constructor
+
+ end % structors
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/TabPanel.m b/studio_functions/GUI Layout Toolbox/layout/+uix/TabPanel.m
new file mode 100644
index 00000000..2bc579f8
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/TabPanel.m
@@ -0,0 +1,946 @@
+classdef TabPanel < uix.Container & uix.mixin.Panel
+ %uix.TabPanel Tab panel
+ %
+ % p = uix.TabPanel(p1,v1,p2,v2,...) constructs a tab panel and sets
+ % parameter p1 to value v1, etc.
+ %
+ % A tab panel shows one of its contents and hides the others according
+ % to which tab is selected.
+ %
+ % From R2014b, MATLAB provides uitabgroup and uitab as standard
+ % components. Consider using uitabgroup and uitab for new code if
+ % these meet your requirements.
+ %
+ % See also: uitabgroup, uitab, uix.CardPanel
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Access = public, Dependent, AbortSet )
+ FontAngle % font angle
+ FontName % font name
+ FontSize % font size
+ FontWeight % font weight
+ FontUnits % font weight
+ ForegroundColor % tab text color [RGB]
+ HighlightColor % border highlight color [RGB]
+ ShadowColor % border shadow color [RGB]
+ end
+
+ properties
+ SelectionChangedFcn = '' % selection change callback
+ end
+
+ properties( Access = public, Dependent, AbortSet )
+ TabEnables % tab enable states
+ TabLocation % tab location [top|bottom]
+ TabTitles % tab titles
+ TabContextMenus % tab context menus
+ TabWidth % tab width
+ end
+
+ properties( Access = private )
+ FontAngle_ = get( 0, 'DefaultUicontrolFontAngle' ) % backing for FontAngle
+ FontName_ = get( 0, 'DefaultUicontrolFontName' ) % backing for FontName
+ FontSize_ = get( 0, 'DefaultUicontrolFontSize' ) % backing for FontSize
+ FontWeight_ = get( 0, 'DefaultUicontrolFontWeight' ) % backing for FontWeight
+ FontUnits_ = get( 0, 'DefaultUicontrolFontUnits' ) % backing for FontUnits
+ ForegroundColor_ = get( 0, 'DefaultUicontrolForegroundColor' ) % backing for ForegroundColor
+ HighlightColor_ = [1 1 1] % backing for HighlightColor
+ ShadowColor_ = [0.7 0.7 0.7] % backing for ShadowColor
+ ParentBackgroundColor = get( 0, 'DefaultUicontrolForegroundColor' ) % default parent background color
+ Tabs = gobjects( [0 1] ) % tabs
+ TabListeners = event.listener.empty( [0 1] ) % tab listeners
+ TabLocation_ = 'top' % backing for TabPosition
+ TabHeight = -1 % cache of tab height (-1 denotes stale cache)
+ TabWidth_ = 50 % backing for TabWidth
+ Dividers % tab dividers
+ BackgroundColorListener % listener
+ SelectionChangedListener % listener
+ ParentListener % listener
+ ParentBackgroundColorListener % listener
+ end
+
+ properties( Access = private, Constant )
+ FontNames = listfonts() % all available font names
+ DividerMask = uix.TabPanel.getDividerMask() % divider image data
+ DividerWidth = 8 % divider width
+ TabMinimumHeight = 9 % tab minimum height
+ Tint = 0.85 % tint factor for unselected tabs
+ end
+
+ methods
+
+ function obj = TabPanel( varargin )
+ %uix.TabPanel Tab panel constructor
+ %
+ % p = uix.TabPanel() constructs a tab panel.
+ %
+ % p = uix.TabPanel(p1,v1,p2,v2,...) sets parameter p1 to value
+ % v1, etc.
+
+ % Create dividers
+ dividers = matlab.ui.control.UIControl( 'Internal', true, ...
+ 'Parent', obj, 'Units', 'pixels', 'Style', 'checkbox',...
+ 'Tag', 'TabPanelDividers' );
+
+ % Create listeners
+ backgroundColorListener = event.proplistener( obj, ...
+ findprop( obj, 'BackgroundColor' ), 'PostSet', ...
+ @obj.onBackgroundColorChanged );
+ selectionChangedListener = event.listener( obj, ...
+ 'SelectionChanged', @obj.onSelectionChanged );
+ parentListener = event.proplistener( obj, ...
+ findprop( obj, 'Parent' ), 'PostSet', ...
+ @obj.onParentChanged );
+
+ % Store properties
+ obj.Dividers = dividers;
+ obj.BackgroundColorListener = backgroundColorListener;
+ obj.SelectionChangedListener = selectionChangedListener;
+ obj.ParentListener = parentListener;
+
+ % Set properties
+ try
+ uix.set( obj, varargin{:} )
+ catch e
+ delete( obj )
+ e.throwAsCaller()
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = get.FontAngle( obj )
+
+ value = obj.FontAngle_;
+
+ end % get.FontAngle
+
+ function set.FontAngle( obj, value )
+
+ % Check
+ assert( ischar( value ) && any( strcmp( value, {'normal','italic','oblique'} ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''FontAngle'' must be ''normal'', ''italic'' or ''oblique''.' )
+
+ % Set
+ obj.FontAngle_ = value;
+
+ % Update existing tabs
+ tabs = obj.Tabs;
+ n = numel( tabs );
+ for ii = 1:n
+ tab = tabs(ii);
+ tab.FontAngle = value;
+ end
+
+ % Mark as dirty
+ obj.TabHeight = -1;
+ obj.Dirty = true;
+
+ end % set.FontAngle
+
+ function value = get.FontName( obj )
+
+ value = obj.FontName_;
+
+ end % get.FontName
+
+ function set.FontName( obj, value )
+
+ % Check
+ assert( ischar( value ) && any( strcmp( value, obj.FontNames ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''FontName'' must be a valid font name.' )
+
+ % Set
+ obj.FontName_ = value;
+
+ % Update existing tabs
+ tabs = obj.Tabs;
+ n = numel( tabs );
+ for ii = 1:n
+ tab = tabs(ii);
+ tab.FontName = value;
+ end
+
+ % Mark as dirty
+ obj.TabHeight = -1;
+ obj.Dirty = true;
+
+ end % set.FontName
+
+ function value = get.FontSize( obj )
+
+ value = obj.FontSize_;
+
+ end % get.FontSize
+
+ function set.FontSize( obj, value )
+
+ % Check
+ assert( isa( value, 'double' ) && isscalar( value ) && ...
+ isreal( value ) && ~isinf( value ) && ...
+ ~isnan( value ) && value > 0, ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''FontSize'' must be a positive scalar.' )
+
+ % Set
+ obj.FontSize_ = value;
+
+ % Update existing tabs
+ tabs = obj.Tabs;
+ n = numel( tabs );
+ for ii = 1:n
+ tab = tabs(ii);
+ tab.FontSize = value;
+ end
+
+ % Mark as dirty
+ obj.TabHeight = -1;
+ obj.Dirty = true;
+
+ end % set.FontSize
+
+ function value = get.FontWeight( obj )
+
+ value = obj.FontWeight_;
+
+ end % get.FontWeight
+
+ function set.FontWeight( obj, value )
+
+ % Check
+ assert( ischar( value ) && any( strcmp( value, {'normal','bold'} ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''FontWeight'' must be ''normal'' or ''bold''.' )
+
+ % Set
+ obj.FontWeight_ = value;
+
+ % Update existing tabs
+ tabs = obj.Tabs;
+ n = numel( tabs );
+ for ii = 1:n
+ tab = tabs(ii);
+ tab.FontWeight = value;
+ end
+
+ % Mark as dirty
+ obj.TabHeight = -1;
+ obj.Dirty = true;
+
+ end % set.FontWeight
+
+ function value = get.FontUnits( obj )
+
+ value = obj.FontUnits_;
+
+ end % get.FontUnits
+
+ function set.FontUnits( obj, value )
+
+ % Check
+ assert( ischar( value ) && ...
+ any( strcmp( value, {'inches','centimeters','points','pixels'} ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''FontUnits'' must be ''inches'', ''centimeters'', ''points'' or ''pixels''.' )
+
+ % Compute size in new units
+ oldUnits = obj.FontUnits_;
+ oldSize = obj.FontSize_;
+ newUnits = value;
+ newSize = oldSize * convert( oldUnits ) / convert( newUnits );
+
+ % Set size and units
+ obj.FontSize_ = newSize;
+ obj.FontUnits_ = newUnits;
+
+ % Update existing tabs
+ tabs = obj.Tabs;
+ n = numel( tabs );
+ for ii = 1:n
+ tab = tabs(ii);
+ tab.FontUnits = newUnits;
+ end
+
+ % Mark as dirty
+ obj.TabHeight = -1;
+ obj.Dirty = true;
+
+ function factor = convert( units )
+ %convert Compute conversion factor to points
+ %
+ % f = convert(u) computes the conversion factor from units
+ % u to points. For example, convert('inches') since 1
+ % inch equals 72 points.
+
+ persistent SCREEN_PIXELS_PER_INCH
+ if isequal( SCREEN_PIXELS_PER_INCH, [] ) % uninitialized
+ SCREEN_PIXELS_PER_INCH = get( 0, 'ScreenPixelsPerInch' );
+ end
+
+ switch units
+ case 'inches'
+ factor = 72;
+ case 'centimeters'
+ factor = 72 / 2.54;
+ case 'points'
+ factor = 1;
+ case 'pixels'
+ factor = 72 / SCREEN_PIXELS_PER_INCH;
+ end
+
+ end % convert
+
+ end % set.FontUnits
+
+ function value = get.ForegroundColor( obj )
+
+ value = obj.ForegroundColor_;
+
+ end % get.ForegroundColor
+
+ function set.ForegroundColor( obj, value )
+
+ % Check
+ assert( isnumeric( value ) && isequal( size( value ), [1 3] ) && ...
+ all( isreal( value ) ) && all( value >= 0 ) && all( value <= 1 ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''ForegroundColor'' must be an RGB triple.' )
+
+ % Set
+ obj.ForegroundColor_ = value;
+
+ % Update existing tabs
+ tabs = obj.Tabs;
+ n = numel( tabs );
+ for ii = 1:n
+ tab = tabs(ii);
+ tab.ForegroundColor = value;
+ end
+
+ end % set.ForegroundColor
+
+ function value = get.HighlightColor( obj )
+
+ value = obj.HighlightColor_;
+
+ end % get.HighlightColor
+
+ function set.HighlightColor( obj, value )
+
+ % Check
+ assert( isnumeric( value ) && isequal( size( value ), [1 3] ) && ...
+ all( isreal( value ) ) && all( value >= 0 ) && all( value <= 1 ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''HighlightColor'' must be an RGB triple.' )
+
+ % Set
+ obj.HighlightColor_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.HighlightColor
+
+ function set.SelectionChangedFcn( obj, value )
+
+ % Check
+ if ischar( value ) % string
+ % OK
+ elseif isa( value, 'function_handle' ) && ...
+ isequal( size( value ), [1 1] ) % function handle
+ % OK
+ elseif iscell( value ) && ndims( value ) == 2 && ...
+ size( value, 1 ) == 1 && size( value, 2 ) > 0 && ...
+ isa( value{1}, 'function_handle' ) && ...
+ isequal( size( value{1} ), [1 1] ) %#ok % cell callback
+ % OK
+ else
+ error( 'uix:InvalidPropertyValue', ...
+ 'Property ''SelectionChangedFcn'' must be a valid callback.' )
+ end
+
+ % Set
+ obj.SelectionChangedFcn = value;
+
+ end % set.SelectionChangedFcn
+
+ function value = get.ShadowColor( obj )
+
+ value = obj.ShadowColor_;
+
+ end % get.ShadowColor
+
+ function set.ShadowColor( obj, value )
+
+ % Check
+ assert( isnumeric( value ) && isequal( size( value ), [1 3] ) && ...
+ all( isreal( value ) ) && all( value >= 0 ) && all( value <= 1 ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''ShadowColor'' must be an RGB triple.' )
+
+ % Set
+ obj.ShadowColor_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.ShadowColor
+
+ function value = get.TabEnables( obj )
+
+ value = get( obj.Tabs, {'Enable'} );
+ value(strcmp( value, 'inactive' )) = {'on'};
+
+ end % get.TabEnables
+
+ function set.TabEnables( obj, value )
+
+ % For those who can't tell a column from a row...
+ if isrow( value )
+ value = transpose( value );
+ end
+
+ % Retrieve tabs
+ tabs = obj.Tabs;
+ tabListeners = obj.TabListeners;
+
+ % Check
+ assert( iscellstr( value ) && ...
+ isequal( size( value ), size( tabs ) ) && ...
+ all( strcmp( value, 'on' ) | strcmp( value, 'off' ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''TabEnables'' should be a cell array of strings ''on'' or ''off'', one per tab.' )
+
+ % Set
+ tf = strcmp( value, 'on' );
+ value(tf) = {'inactive'};
+ for ii = 1:numel( tabs )
+ tabs(ii).Enable = value{ii};
+ tabListeners(ii).Enabled = tf(ii);
+ end
+
+ % Show selected child
+ obj.showSelection()
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.TabEnables
+
+ function value = get.TabLocation( obj )
+
+ value = obj.TabLocation_;
+
+ end % get.TabLocation
+
+ function set.TabLocation( obj, value )
+
+ % Check
+ assert( ischar( value ) && ...
+ any( strcmp( value, {'top','bottom'} ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''TabLocation'' should be ''top'' or ''bottom''.' )
+
+ % Set
+ obj.TabLocation_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.TabLocation
+
+ function value = get.TabTitles( obj )
+
+ value = get( obj.Tabs, {'String'} );
+
+ end % get.TabTitles
+
+ function set.TabTitles( obj, value )
+
+ % For those who can't tell a column from a row...
+ if isrow( value )
+ value = transpose( value );
+ end
+
+ % Retrieve tabs
+ tabs = obj.Tabs;
+
+ % Check
+ assert( iscellstr( value ) && ...
+ isequal( size( value ), size( tabs ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''TabTitles'' should be a cell array of strings, one per tab.' )
+
+ % Set
+ n = numel( tabs );
+ for ii = 1:n
+ tabs(ii).String = value{ii};
+ end
+
+ % Mark as dirty
+ obj.TabHeight = -1;
+ obj.Dirty = true;
+
+ end % set.TabTitles
+
+ function value = get.TabContextMenus( obj )
+
+ tabs = obj.Tabs;
+ n = numel( tabs );
+ value = cell( [n 1] );
+ for ii = 1:n
+ value{ii} = tabs(ii).UIContextMenu;
+ end
+
+ end % get.TabContextMenus
+
+ function set.TabContextMenus( obj, value )
+
+ tabs = obj.Tabs;
+ n = numel( tabs );
+ for ii = 1:n
+ tabs(ii).UIContextMenu = value{ii};
+ end
+
+ end % set.TabContextMenus
+
+ function value = get.TabWidth( obj )
+
+ value = obj.TabWidth_;
+
+ end % get.TabWidth
+
+ function set.TabWidth( obj, value )
+
+ % Check
+ assert( isa( value, 'double' ) && isscalar( value ) && ...
+ isreal( value ) && ~isinf( value ) && ...
+ ~isnan( value ) && value ~= 0, ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''TabWidth'' must be a non-zero scalar.' )
+
+ % Set
+ obj.TabWidth_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.TabWidth
+
+ end % accessors
+
+ methods( Access = protected )
+
+ function redraw( obj )
+
+ % Compute positions
+ bounds = hgconvertunits( ancestor( obj, 'figure' ), ...
+ [0 0 1 1], 'normalized', 'pixels', obj );
+ w = ceil( bounds(1) + bounds(3) ) - floor( bounds(1) ); % width
+ h = ceil( bounds(2) + bounds(4) ) - floor( bounds(2) ); % height
+ p = obj.Padding_; % padding
+ tabs = obj.Tabs;
+ n = numel( tabs ); % number of tabs
+ tH = obj.TabHeight; % tab height
+ if tH == -1 % cache stale, refresh
+ if n > 0
+ cTabExtents = get( tabs, {'Extent'} );
+ tabExtents = vertcat( cTabExtents{:} );
+ tH = max( tabExtents(:,4) );
+ end
+ tH = max( tH, obj.TabMinimumHeight ); % apply minimum
+ tH = ceil( tH ); % round up
+ obj.TabHeight = tH; % store
+ end
+ cH = max( [h - 2 * p - tH, 1] ); % contents height
+ switch obj.TabLocation_
+ case 'top'
+ cY = 1 + p; % contents y
+ tY = cY + cH + p; % tab y
+ case 'bottom'
+ tY = 1; % tab y
+ cY = tY + tH + p; % contents y
+ end
+ cX = 1 + p; % contents x
+ cW = max( [w - 2 * p, 1] ); % contents width
+ tW = obj.TabWidth_; % tab width
+ dW = obj.DividerWidth; % tab divider width
+ if tW < 0 && n > 0 % relative
+ tW = max( ( w - (n+1) * dW ) / n, 1 );
+ end
+ tW = ceil( tW ); % round up
+ for ii = 1:n
+ tabs(ii).Position = [1 + (ii-1) * tW + ii * dW, tY, tW, tH];
+ end
+ obj.Dividers.Position = [0 tY w+1 tH];
+ contentsPosition = [cX cY cW cH];
+
+ % Redraw tabs
+ obj.redrawTabs()
+
+ % Redraw contents
+ selection = obj.Selection_;
+ if selection ~= 0 && strcmp( obj.TabEnables{selection}, 'on' )
+ uix.setPosition( obj.Contents_(selection), contentsPosition, 'pixels' )
+ end
+
+ end % redraw
+
+ function addChild( obj, child )
+ %addChild Add child
+ %
+ % c.addChild(d) adds the child d to the container c.
+
+ % Create new tab
+ n = numel( obj.Tabs );
+ tab = matlab.ui.control.UIControl( 'Internal', true, ...
+ 'Parent', obj, 'Style', 'text', 'Enable', 'inactive', ...
+ 'Units', 'pixels', 'FontUnits', obj.FontUnits_, ...
+ 'FontSize', obj.FontSize_, 'FontName', obj.FontName_, ...
+ 'FontAngle', obj.FontAngle_, 'FontWeight', obj.FontWeight_, ...
+ 'ForegroundColor', obj.ForegroundColor_, ...
+ 'String', sprintf( 'Page %d', n + 1 ) );
+ tabListener = event.listener( tab, 'ButtonDown', @obj.onTabClicked );
+ obj.Tabs(n+1,:) = tab;
+ obj.TabListeners(n+1,:) = tabListener;
+
+ % Mark as dirty
+ obj.TabHeight = -1;
+
+ % Check for bug
+ if verLessThan( 'MATLAB', '8.5' ) && strcmp( child.Visible, 'off' )
+ obj.G1218142 = true;
+ end
+
+ % Select new content
+ oldSelection = obj.Selection_;
+ if numel( obj.Contents_ ) == 0
+ newSelection = 1;
+ obj.Selection_ = newSelection;
+ else
+ newSelection = oldSelection;
+ end
+
+ % Call superclass method
+ addChild@uix.mixin.Container( obj, child )
+
+ % Show selected child
+ obj.showSelection()
+
+ % Notify selection change
+ if oldSelection ~= newSelection
+ obj.notify( 'SelectionChanged', ...
+ uix.SelectionData( oldSelection, newSelection ) )
+ end
+
+ end % addChild
+
+ function removeChild( obj, child )
+ %removeChild Remove child
+ %
+ % c.removeChild(d) removes the child d from the container c.
+
+ % Find index of removed child
+ contents = obj.Contents_;
+ index = find( contents == child );
+
+ % Remove tab
+ delete( obj.Tabs(index) )
+ obj.Tabs(index,:) = [];
+ obj.TabListeners(index,:) = [];
+
+ % Call superclass method
+ removeChild@uix.mixin.Panel( obj, child )
+
+ end % removeChild
+
+ function reorder( obj, indices )
+ %reorder Reorder contents
+ %
+ % c.reorder(i) reorders the container contents using indices
+ % i, c.Contents = c.Contents(i).
+
+ % Reorder
+ obj.Tabs = obj.Tabs(indices,:);
+ obj.TabListeners = obj.TabListeners(indices,:);
+
+ % Call superclass method
+ reorder@uix.mixin.Panel( obj, indices )
+
+ end % reorder
+
+ function reparent( obj, oldFigure, newFigure )
+ %reparent Reparent container
+ %
+ % c.reparent(a,b) reparents the container c from the figure a
+ % to the figure b.
+
+ if ~isequal( oldFigure, newFigure )
+ contextMenus = obj.TabContextMenus;
+ for ii = 1:numel( contextMenus )
+ contextMenu = contextMenus{ii};
+ if ~isempty( contextMenu )
+ contextMenu.Parent = newFigure;
+ end
+ end
+ end
+
+ % Call superclass method
+ reparent@uix.mixin.Panel( obj, oldFigure, newFigure )
+
+ end % reparent
+
+ function showSelection( obj )
+ %showSelection Show selected child, hide the others
+ %
+ % c.showSelection() shows the selected child of the container
+ % c, and hides the others.
+
+ % Call superclass method
+ showSelection@uix.mixin.Panel( obj )
+
+ % If not enabled, hide selected contents too
+ selection = obj.Selection_;
+ if selection ~= 0 && strcmp( obj.TabEnables{selection}, 'off' )
+ child = obj.Contents_(selection);
+ child.Visible = 'off';
+ if isa( child, 'matlab.graphics.axis.Axes' )
+ child.ContentsVisible = 'off';
+ end
+ % As a remedy for g1100294, move off-screen too
+ margin = 1000;
+ if isa( child, 'matlab.graphics.axis.Axes' ) ...
+ && strcmp(child.ActivePositionProperty, 'outerposition' )
+ child.OuterPosition(1) = -child.OuterPosition(3)-margin;
+ else
+ child.Position(1) = -child.Position(3)-margin;
+ end
+ end
+
+ end % showSelection
+
+ end % template methods
+
+ methods( Access = private )
+
+ function redrawTabs( obj )
+ %redrawTabs Redraw tabs
+ %
+ % p.redrawTabs() redraws the tabs.
+
+ % Get relevant properties
+ selection = obj.Selection_;
+ tabs = obj.Tabs;
+ t = numel( tabs );
+ dividers = obj.Dividers;
+
+ % Handle no tabs as a special case
+ if t == 0
+ dividers.Visible = 'off'; % hide
+ return
+ end
+
+ % Repaint tabs
+ backgroundColor = obj.BackgroundColor;
+ for ii = 1:t
+ tab = tabs(ii);
+ if ii == selection
+ tab.BackgroundColor = backgroundColor;
+ else
+ tab.BackgroundColor = obj.Tint * backgroundColor;
+ end
+ end
+
+ % Repaint dividers
+ d = t + 1;
+ dividerNames = repmat( 'F', [d 2] ); % initialize
+ dividerNames(1,1) = 'E'; % end
+ dividerNames(end,2) = 'E'; % end
+ if selection ~= 0
+ dividerNames(selection,2) = 'T'; % selected
+ dividerNames(selection+1,1) = 'T'; % selected
+ end
+ tH = obj.TabHeight;
+ assert( tH >= obj.TabMinimumHeight, 'uix:InvalidState', ...
+ 'Cannot redraw tabs with invalid TabHeight.' )
+ tW = obj.Tabs(1).Position(3);
+ dW = obj.DividerWidth;
+ allCData = zeros( [tH 0 3] ); % initialize
+ map = [obj.ShadowColor; obj.BackgroundColor; ...
+ obj.Tint * obj.BackgroundColor; obj.HighlightColor;...
+ obj.ParentBackgroundColor];
+ for ii = 1:d
+ % Select mask
+ iMask = obj.DividerMask.( dividerNames(ii,:) );
+ % Resize
+ iData = repmat( iMask(5,:), [tH 1] );
+ iData(1:4,:) = iMask(1:4,:);
+ iData(end-3:end,:) = iMask(end-3:end,:);
+ % Convert to RGB
+ cData = ind2rgb( iData+1, map );
+ % Orient
+ switch obj.TabLocation_
+ case 'bottom'
+ cData = flipud( cData );
+ end
+ % Insert
+ allCData(1:tH,(ii-1)*(dW+tW)+(1:dW),:) = cData; % center
+ if ii > 1 % extend left under transparent uicontrol edge
+ allCData(1:tH,(ii-1)*(dW+tW),:) = cData(:,1,:);
+ end
+ if ii < d % extend right under transparent uicontrol edge
+ allCData(1:tH,(ii-1)*(dW+tW)+dW+1,:) = cData(:,end,:);
+ end
+ end
+ dividers.CData = allCData; % paint
+ dividers.BackgroundColor = obj.ParentBackgroundColor;
+ dividers.Visible = 'on'; % show
+
+ end % redrawTabs
+
+ end % helper methods
+
+ methods( Access = private )
+
+ function onTabClicked( obj, source, ~ )
+
+ % Update selection
+ oldSelection = obj.Selection_;
+ newSelection = find( source == obj.Tabs );
+ if oldSelection == newSelection, return, end % abort set
+ obj.Selection_ = newSelection;
+
+ % Show selected child
+ obj.showSelection()
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ % Notify selection change
+ obj.notify( 'SelectionChanged', ...
+ uix.SelectionData( oldSelection, newSelection ) )
+
+ end % onTabClicked
+
+ function onBackgroundColorChanged( obj, ~, ~ )
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % onBackgroundColorChanged
+
+ function onSelectionChanged( obj, source, eventData )
+
+ % Call callback
+ callback = obj.SelectionChangedFcn;
+ if ischar( callback ) && isequal( callback, '' )
+ % do nothing
+ elseif ischar( callback )
+ feval( callback, source, eventData )
+ elseif isa( callback, 'function_handle' )
+ callback( source, eventData )
+ elseif iscell( callback )
+ feval( callback{1}, source, eventData, callback{2:end} )
+ end
+
+ end % onSelectionChanged
+
+ function onParentChanged( obj, ~, ~ )
+
+ % Update ParentBackgroundColor and ParentBackgroundColor
+ if isprop( obj.Parent, 'BackgroundColor' )
+ prop = 'BackgroundColor';
+ elseif isprop( obj.Parent, 'Color' )
+ prop = 'Color';
+ else
+ prop = [];
+ end
+
+ if ~isempty( prop )
+ obj.ParentBackgroundColorListener = event.proplistener( obj.Parent, ...
+ findprop( obj.Parent, prop ), 'PostSet', ...
+ @( src, evt ) obj.updateParentBackgroundColor( prop ) );
+ else
+ obj.ParentBackgroundColorListener = [];
+ end
+
+ obj.updateParentBackgroundColor( prop );
+
+ end % onParentChanged
+
+ function updateParentBackgroundColor( obj, prop )
+
+ if isempty( prop )
+ obj.ParentBackgroundColor = obj.BackgroundColor;
+ else
+ obj.ParentBackgroundColor = obj.Parent.(prop);
+ end
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end
+
+ end % event handlers
+
+ methods( Access = private, Static )
+
+ function mask = getDividerMask()
+ %getDividerMask Get divider image data
+ %
+ % m = uix.TabPanel.getDividerMask() returns the image masks
+ % for tab panel dividers. Mask entries are 0 (shadow), 1
+ % (background), 2 (tint) and 3 (highlight).
+
+ mask.EF = indexColor( uix.loadIcon( 'tab_NoEdge_NotSelected.png' ) );
+ mask.ET = indexColor( uix.loadIcon( 'tab_NoEdge_Selected.png' ) );
+ mask.FE = indexColor( uix.loadIcon( 'tab_NotSelected_NoEdge.png' ) );
+ mask.FF = indexColor( uix.loadIcon( 'tab_NotSelected_NotSelected.png' ) );
+ mask.FT = indexColor( uix.loadIcon( 'tab_NotSelected_Selected.png' ) );
+ mask.TE = indexColor( uix.loadIcon( 'tab_Selected_NoEdge.png' ) );
+ mask.TF = indexColor( uix.loadIcon( 'tab_Selected_NotSelected.png' ) );
+
+ function mask = indexColor( rgbMap )
+ %indexColor Returns a map of index given an RGB map
+ %
+ % mask = indexColor( rgbMap ) returns a mask of color
+ % index based on the supplied rgbMap.
+ % black : 0
+ % red : 1
+ % yellow : 2
+ % white : 3
+ % blue : 4
+ mask = nan( size( rgbMap, 1 ),size( rgbMap, 2 ) );
+ % Black
+ colorIndex = isColor( rgbMap, [0 0 0] );
+ mask(colorIndex) = 0;
+ % Red
+ colorIndex = isColor( rgbMap, [1 0 0] );
+ mask(colorIndex) = 1;
+ % Yellow
+ colorIndex = isColor( rgbMap, [1 1 0] );
+ mask(colorIndex) = 2;
+ % White
+ colorIndex = isColor( rgbMap, [1 1 1] );
+ mask(colorIndex) = 3;
+ % Blue
+ colorIndex = isColor( rgbMap, [0 0 1] );
+ mask(colorIndex) = 4;
+ % Nested
+ function boolMap = isColor( map, color )
+ %isColor Return a map of boolean where map is equal to color
+ boolMap = all( bsxfun( @eq, map, permute( color, [1 3 2] ) ), 3 );
+ end
+ end
+
+ end % getDividerMask
+
+ end % static helper methods
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Text.m b/studio_functions/GUI Layout Toolbox/layout/+uix/Text.m
new file mode 100644
index 00000000..30f7a23a
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/Text.m
@@ -0,0 +1,545 @@
+classdef ( Hidden ) Text < matlab.mixin.SetGet
+ %uix.Text Text control
+ %
+ % t = uix.Text(p1,v1,p2,v2,...) constructs a text control and sets
+ % parameter p1 to value v1, etc.
+ %
+ % A text control adds functionality to a uicontrol of Style text:
+ % * Set VerticalAlignment to 'top', 'middle' or 'bottom'
+ % * Fire a Callback when the user clicks on the text
+ %
+ % See also: uicontrol
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Dependent )
+ BackgroundColor
+ end
+
+ properties( Dependent, SetAccess = private )
+ BeingDeleted
+ end
+
+ properties( Dependent )
+ Callback
+ DeleteFcn
+ Enable
+ end
+
+ properties( Dependent, SetAccess = private )
+ Extent
+ end
+
+ properties( Dependent )
+ FontAngle
+ FontName
+ FontSize
+ FontUnits
+ FontWeight
+ ForegroundColor
+ HandleVisibility
+ HorizontalAlignment
+ Parent
+ Position
+ String
+ Tag
+ TooltipString
+ end
+
+ properties( Dependent, SetAccess = private )
+ Type
+ end
+
+ properties( Dependent )
+ UIContextMenu
+ Units
+ UserData
+ VerticalAlignment
+ Visible
+ end
+
+ properties( Access = private )
+ Container % container
+ Checkbox % checkbox, used for label
+ Screen % text, used for covering checkbox
+ VerticalAlignment_ = 'top' % backing for VerticalAlignment
+ Dirty = false % flag
+ FigureObserver % observer
+ FigureListener % listener
+ end
+
+ properties( Constant, Access = private )
+ Margin = checkBoxLabelOffset() % checkbox size
+ end
+
+ methods
+
+ function obj = Text( varargin )
+ %uix.Text Text control
+ %
+ % t = uix.Text(p1,v1,p2,v2,...) constructs a text control and
+ % sets parameter p1 to value v1, etc.
+
+ % Create graphics
+ container = uicontainer( 'Parent', [], ...
+ 'Units', get( 0, 'DefaultUicontrolUnits' ), ...
+ 'Position', get( 0, 'DefaultUicontrolPosition' ), ...
+ 'SizeChangedFcn', @obj.onResized );
+ checkbox = uicontrol( 'Parent', container, ...
+ 'HandleVisibility', 'off', ...
+ 'Style', 'checkbox', 'Units', 'pixels', ...
+ 'HorizontalAlignment', 'center', ...
+ 'Enable', 'inactive' );
+ screen = uicontrol( 'Parent', container, ...
+ 'HandleVisibility', 'off', ...
+ 'Style', 'text', 'Units', 'pixels' );
+
+ % Create observers and listeners
+ figureObserver = uix.FigureObserver( container );
+ figureListener = event.listener( figureObserver, ...
+ 'FigureChanged', @obj.onFigureChanged );
+
+ % Store properties
+ obj.Container = container;
+ obj.Checkbox = checkbox;
+ obj.Screen = screen;
+ obj.FigureObserver = figureObserver;
+ obj.FigureListener = figureListener;
+
+ % Set properties
+ try
+ uix.set( obj, varargin{:} )
+ catch e
+ delete( obj )
+ e.throwAsCaller()
+ end
+
+ end % constructor
+
+ function delete( obj )
+ %delete Destructor
+
+ delete( obj.Container )
+
+ end % destructor
+
+ end % structors
+
+ methods
+
+ function value = get.BackgroundColor( obj )
+
+ value = obj.Checkbox.BackgroundColor;
+
+ end % get.BackgroundColor
+
+ function set.BackgroundColor( obj, value )
+
+ obj.Container.BackgroundColor = value;
+ obj.Checkbox.BackgroundColor = value;
+ obj.Screen.BackgroundColor = value;
+
+ end % set.BackgroundColor
+
+ function value = get.BeingDeleted( obj )
+
+ value = obj.Checkbox.BeingDeleted;
+
+ end % get.BeingDeleted
+
+ function value = get.Callback( obj )
+
+ value = obj.Checkbox.Callback;
+
+ end % get.Callback
+
+ function set.Callback( obj, value )
+
+ obj.Checkbox.Callback = value;
+
+ end % set.Callback
+
+ function value = get.DeleteFcn( obj )
+
+ value = obj.Checkbox.DeleteFcn;
+
+ end % get.DeleteFcn
+
+ function set.DeleteFcn( obj, value )
+
+ obj.Checkbox.DeleteFcn = value;
+
+ end % set.DeleteFcn
+
+ function value = get.Enable( obj )
+
+ value = obj.Checkbox.Enable;
+
+ end % get.Enable
+
+ function set.Enable( obj, value )
+
+ obj.Checkbox.Enable = value;
+
+ end % set.Enable
+
+ function value = get.Extent( obj )
+
+ value = obj.Checkbox.Extent;
+
+ end % get.Extent
+
+ function value = get.FontAngle( obj )
+
+ value = obj.Checkbox.FontAngle;
+
+ end % get.FontAngle
+
+ function set.FontAngle( obj, value )
+
+ % Set
+ obj.Checkbox.FontAngle = value;
+
+ % Mark as dirty
+ obj.setDirty()
+
+ end % set.FontAngle
+
+ function value = get.FontName( obj )
+
+ value = obj.Checkbox.FontName;
+
+ end % get.FontName
+
+ function set.FontName( obj, value )
+
+ % Set
+ obj.Checkbox.FontName = value;
+
+ % Mark as dirty
+ obj.setDirty()
+
+ end % set.FontName
+
+ function value = get.FontSize( obj )
+
+ value = obj.Checkbox.FontSize;
+
+ end % get.FontSize
+
+ function set.FontSize( obj, value )
+
+ % Set
+ obj.Checkbox.FontSize = value;
+
+ % Mark as dirty
+ obj.setDirty()
+
+ end % set.FontSize
+
+ function value = get.FontUnits( obj )
+
+ value = obj.Checkbox.FontUnits;
+
+ end % get.FontUnits
+
+ function set.FontUnits( obj, value )
+
+ obj.Checkbox.FontUnits = value;
+
+ end % set.FontUnits
+
+ function value = get.FontWeight( obj )
+
+ value = obj.Checkbox.FontWeight;
+
+ end % get.FontWeight
+
+ function set.FontWeight( obj, value )
+
+ % Set
+ obj.Checkbox.FontWeight = value;
+
+ % Mark as dirty
+ obj.setDirty()
+
+ end % set.FontWeight
+
+ function value = get.ForegroundColor( obj )
+
+ value = obj.Checkbox.ForegroundColor;
+
+ end % get.ForegroundColor
+
+ function set.ForegroundColor( obj, value )
+
+ obj.Checkbox.ForegroundColor = value;
+
+ end % set.ForegroundColor
+
+ function value = get.HandleVisibility( obj )
+
+ value = obj.Container.HandleVisibility;
+
+ end % get.HandleVisibility
+
+ function set.HandleVisibility( obj, value )
+
+ obj.Container.HandleVisibility = value;
+
+ end % set.HandleVisibility
+
+ function value = get.HorizontalAlignment( obj )
+
+ value = obj.Checkbox.HorizontalAlignment;
+
+ end % get.HorizontalAlignment
+
+ function set.HorizontalAlignment( obj, value )
+
+ % Set
+ obj.Checkbox.HorizontalAlignment = value;
+
+ % Mark as dirty
+ obj.setDirty()
+
+ end % set.HorizontalAlignment
+
+ function value = get.Parent( obj )
+
+ value = obj.Container.Parent;
+
+ end % get.Parent
+
+ function set.Parent( obj, value )
+
+ obj.Container.Parent = value;
+
+ end % set.Parent
+
+ function value = get.Position( obj )
+
+ value = obj.Container.Position;
+
+ end % get.Position
+
+ function set.Position( obj, value )
+
+ obj.Container.Position = value;
+
+ end % set.Position
+
+ function value = get.String( obj )
+
+ value = obj.Checkbox.String;
+
+ end % get.String
+
+ function set.String( obj, value )
+
+ % Set
+ obj.Checkbox.String = value;
+
+ % Mark as dirty
+ obj.setDirty()
+
+ end % set.String
+
+ function value = get.Tag( obj )
+
+ value = obj.Checkbox.Tag;
+
+ end % get.Tag
+
+ function set.Tag( obj, value )
+
+ obj.Checkbox.Tag = value;
+
+ end % set.Tag
+
+ function value = get.TooltipString( obj )
+
+ value = obj.Checkbox.TooltipString;
+
+ end % get.TooltipString
+
+ function set.TooltipString( obj, value )
+
+ obj.Checkbox.TooltipString = value;
+
+ end % set.TooltipString
+
+ function value = get.Type( obj )
+
+ value = obj.Checkbox.Type;
+
+ end % get.Type
+
+ function value = get.UIContextMenu( obj )
+
+ value = obj.Checkbox.UIContextMenu;
+
+ end % get.UIContextMenu
+
+ function set.UIContextMenu( obj, value )
+
+ obj.Checkbox.UIContextMenu = value;
+
+ end % set.UIContextMenu
+
+ function value = get.Units( obj )
+
+ value = obj.Container.Units;
+
+ end % get.Units
+
+ function set.Units( obj, value )
+
+ obj.Container.Units = value;
+
+ end % set.Units
+
+ function value = get.UserData( obj )
+
+ value = obj.Checkbox.UserData;
+
+ end % get.UserData
+
+ function set.UserData( obj, value )
+
+ obj.Checkbox.UserData = value;
+
+ end % set.UserData
+
+ function value = get.VerticalAlignment( obj )
+
+ value = obj.VerticalAlignment_;
+
+ end % get.VerticalAlignment
+
+ function set.VerticalAlignment( obj, value )
+
+ % Check
+ assert( ischar( value ) && ...
+ any( strcmp( value, {'top','middle','bottom'} ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Property ''VerticalAlignment'' must be ''top'', ''middle'' or ''bottom''.' )
+
+ % Set
+ obj.VerticalAlignment_ = value;
+
+ % Mark as dirty
+ obj.setDirty()
+
+ end % set.VerticalAlignment
+
+ function value = get.Visible( obj )
+
+ value = obj.Container.Visible;
+
+ end % get.Visible
+
+ function set.Visible( obj, value )
+
+ obj.Container.Visible = value;
+
+ end % set.Visible
+
+ end % accessors
+
+ methods( Access = private )
+
+ function onResized( obj, ~, ~ )
+ %onResized Event handler
+
+ % Rooted, so redraw
+ obj.redraw()
+
+ end % onResized
+
+ function onFigureChanged( obj, ~, eventData )
+
+ % If rooted, redraw
+ if isempty( eventData.OldFigure ) && ...
+ ~isempty( eventData.NewFigure ) && obj.Dirty
+ obj.redraw()
+ end
+
+ end % onFigureChanged
+
+ end % event handlers
+
+ methods( Access = private )
+
+ function setDirty( obj )
+ %setDirty Mark as dirty
+ %
+ % t.setDirty() marks the text control t as dirty. If the text
+ % control is rooted then it is redrawn immediately. If not
+ % then the redraw is queued for when it is next rooted.
+
+ if isempty( obj.FigureObserver.Figure )
+ obj.Dirty = true; % set flag
+ else
+ obj.Dirty = false; % unset flag
+ obj.redraw() % redraw
+ end
+
+ end % setDirty
+
+ function redraw( obj )
+ %redraw Redraw
+ %
+ % t.redraw() redraws the text control t. Note that this
+ % requires the text control to be rooted. Methods should
+ % request redraws using setDirty, rather than calling redraw
+ % directly.
+
+ c = obj.Container;
+ b = obj.Checkbox;
+ s = obj.Screen;
+ bo = hgconvertunits( ancestor( obj, 'figure' ), ...
+ [0 0 1 1], 'normalized', 'pixels', c ); % bounds
+ m = obj.Margin;
+ e = b.Extent;
+ switch b.HorizontalAlignment
+ case 'left'
+ x = 1 - m;
+ case 'center'
+ x = 1 + bo(3)/2 - e(3)/2 - m;
+ case 'right'
+ x = 1 + bo(3) - e(3) - m;
+ end
+ w = e(3) + m;
+ switch obj.VerticalAlignment_
+ case 'top'
+ y = 1 + bo(4) - e(4);
+ case 'middle'
+ y = 1 + bo(4)/2 - e(4)/2;
+ case 'bottom'
+ y = 1;
+ end
+ h = e(4);
+ b.Position = [x y w h];
+ s.Position = [x y m h];
+
+ end % redraw
+
+ end % helpers
+
+end % classdef
+
+function o = checkBoxLabelOffset()
+%checkBoxLabelOffset Horizontal offset to checkbox label
+
+if ismac
+ o = 20;
+else
+ if verLessThan( 'MATLAB', '8.6' ) % R2015b
+ o = 18;
+ else
+ o = 16;
+ end
+end
+
+end % margin
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/VBox.m b/studio_functions/GUI Layout Toolbox/layout/+uix/VBox.m
new file mode 100644
index 00000000..aee41605
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/VBox.m
@@ -0,0 +1,189 @@
+classdef VBox < uix.Box
+ %uix.VBox Vertical box
+ %
+ % b = uix.VBox(p1,v1,p2,v2,...) constructs a vertical box and sets
+ % parameter p1 to value v1, etc.
+ %
+ % A vertical box lays out contents from top to bottom.
+ %
+ % See also: uix.HBox, uix.Grid, uix.VButtonBox, uix.VBoxFlex
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Access = public, Dependent, AbortSet )
+ Heights % heights of contents, in pixels and/or weights
+ MinimumHeights % minimum heights of contents, in pixels
+ end
+
+ properties( Access = protected )
+ Heights_ = zeros( [0 1] ) % backing for Heights
+ MinimumHeights_ = zeros( [0 1] ) % backing for MinimumHeights
+ end
+
+ methods
+
+ function obj = VBox( varargin )
+ %uix.VBox Vertical box constructor
+ %
+ % b = uix.VBox() constructs a horizontal box.
+ %
+ % b = uix.VBox(p1,v1,p2,v2,...) sets parameter p1 to value v1,
+ % etc.
+
+ % Set properties
+ try
+ uix.set( obj, varargin{:} )
+ catch e
+ delete( obj )
+ e.throwAsCaller()
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = get.Heights( obj )
+
+ value = obj.Heights_;
+
+ end % get.Heights
+
+ function set.Heights( obj, value )
+
+ % For those who can't tell a column from a row...
+ if isrow( value )
+ value = transpose( value );
+ end
+
+ % Check
+ assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ...
+ 'Property ''Heights'' must be of type double.' )
+ assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ...
+ ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ...
+ 'Elements of property ''Heights'' must be real and finite.' )
+ assert( isequal( size( value ), size( obj.Contents_ ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Size of property ''Heights'' must match size of contents.' )
+
+ % Set
+ obj.Heights_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.Heights
+
+ function value = get.MinimumHeights( obj )
+
+ value = obj.MinimumHeights_;
+
+ end % get.MinimumHeights
+
+ function set.MinimumHeights( obj, value )
+
+ % For those who can't tell a column from a row...
+ if isrow( value )
+ value = transpose( value );
+ end
+
+ % Check
+ assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ...
+ 'Property ''MinimumHeights'' must be of type double.' )
+ assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ...
+ all( value >= 0 ), 'uix:InvalidPropertyValue', ...
+ 'Elements of property ''MinimumHeights'' must be non-negative.' )
+ assert( isequal( size( value ), size( obj.Heights_ ) ), ...
+ 'uix:InvalidPropertyValue', ...
+ 'Size of property ''MinimumHeights'' must match size of contents.' )
+
+ % Set
+ obj.MinimumHeights_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.MinimumHeights
+
+ end % accessors
+
+ methods( Access = protected )
+
+ function redraw( obj )
+ %redraw Redraw
+ %
+ % c.redraw() redraws the container c.
+
+ % Compute positions
+ bounds = hgconvertunits( ancestor( obj, 'figure' ), ...
+ [0 0 1 1], 'normalized', 'pixels', obj );
+ heights = obj.Heights_;
+ minimumHeights = obj.MinimumHeights_;
+ padding = obj.Padding_;
+ spacing = obj.Spacing_;
+ r = numel( heights );
+ xPositions = [padding + 1, max( bounds(3) - 2 * padding, 1 )];
+ xPositions = repmat( xPositions, [r 1] );
+ ySizes = uix.calcPixelSizes( bounds(4), heights, ...
+ minimumHeights, padding, spacing );
+ yPositions = [bounds(4) - cumsum( ySizes ) - padding - ...
+ spacing * transpose( 0:r-1 ) + 1, ySizes];
+ positions = [xPositions(:,1), yPositions(:,1), ...
+ xPositions(:,2), yPositions(:,2)];
+
+ % Set positions
+ children = obj.Contents_;
+ for ii = 1:numel( children )
+ uix.setPosition( children(ii), positions(ii,:), 'pixels' )
+ end
+
+ end % redraw
+
+ function addChild( obj, child )
+ %addChild Add child
+ %
+ % c.addChild(d) adds the child d to the container c.
+
+ % Add to sizes
+ obj.Heights_(end+1,:) = -1;
+ obj.MinimumHeights_(end+1,:) = 1;
+
+ % Call superclass method
+ addChild@uix.Box( obj, child )
+
+ end % addChild
+
+ function removeChild( obj, child )
+ %removeChild Remove child
+ %
+ % c.removeChild(d) removes the child d from the container c.
+
+ % Remove from sizes
+ tf = obj.Contents_ == child;
+ obj.Heights_(tf,:) = [];
+ obj.MinimumHeights_(tf,:) = [];
+
+ % Call superclass method
+ removeChild@uix.Box( obj, child )
+
+ end % removeChild
+
+ function reorder( obj, indices )
+ %reorder Reorder contents
+ %
+ % c.reorder(i) reorders the container contents using indices
+ % i, c.Contents = c.Contents(i).
+
+ % Reorder
+ obj.Heights_ = obj.Heights_(indices,:);
+ obj.MinimumHeights_ = obj.MinimumHeights_(indices,:);
+
+ % Call superclass method
+ reorder@uix.Box( obj, indices )
+
+ end % reorder
+
+ end % template methods
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/VBoxFlex.m b/studio_functions/GUI Layout Toolbox/layout/+uix/VBoxFlex.m
new file mode 100644
index 00000000..10275490
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/VBoxFlex.m
@@ -0,0 +1,351 @@
+classdef VBoxFlex < uix.VBox & uix.mixin.Flex
+ %uix.VBoxFlex Flexible vertical box
+ %
+ % b = uix.VBoxFlex(p1,v1,p2,v2,...) constructs a flexible vertical box
+ % and sets parameter p1 to value v1, etc.
+ %
+ % A vertical box lays out contents from top to bottom. Users can
+ % resize contents by dragging the dividers.
+ %
+ % See also: uix.HBoxFlex, uix.GridFlex, uix.VBox, uix.VButtonBox
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ properties( Access = public, Dependent, AbortSet )
+ DividerMarkings % divider markings [on|off]
+ end
+
+ properties( Access = private )
+ RowDividers = uix.Divider.empty( [0 1] ) % row dividers
+ FrontDivider % front divider
+ DividerMarkings_ = 'on' % backing for DividerMarkings
+ MousePressListener = event.listener.empty( [0 0] ) % mouse press listener
+ MouseReleaseListener = event.listener.empty( [0 0] ) % mouse release listener
+ MouseMotionListener = event.listener.empty( [0 0] ) % mouse motion listener
+ ActiveDivider = 0 % active divider index
+ ActiveDividerPosition = [NaN NaN NaN NaN] % active divider position
+ MousePressLocation = [NaN NaN] % mouse press location
+ BackgroundColorListener % background color listener
+ end
+
+ methods
+
+ function obj = VBoxFlex( varargin )
+ %uix.VBoxFlex Flexible vertical box constructor
+ %
+ % b = uix.VBoxFlex() constructs a flexible vertical box.
+ %
+ % b = uix.VBoxFlex(p1,v1,p2,v2,...) sets parameter p1 to value
+ % v1, etc.
+
+ % Create front divider
+ frontDivider = uix.Divider( 'Parent', obj, ...
+ 'Orientation', 'horizontal', ...
+ 'BackgroundColor', obj.BackgroundColor * 0.75, ...
+ 'Visible', 'off' );
+
+ % Create listeners
+ backgroundColorListener = event.proplistener( obj, ...
+ findprop( obj, 'BackgroundColor' ), 'PostSet', ...
+ @obj.onBackgroundColorChanged );
+
+ % Store properties
+ obj.FrontDivider = frontDivider;
+ obj.BackgroundColorListener = backgroundColorListener;
+
+ % Set Spacing property to 5 (may be overwritten by uix.set)
+ obj.Spacing = 5;
+
+ % Set properties
+ try
+ uix.set( obj, varargin{:} )
+ catch e
+ delete( obj )
+ e.throwAsCaller()
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods
+
+ function value = get.DividerMarkings( obj )
+
+ value = obj.DividerMarkings_;
+
+ end % get.DividerMarkings
+
+ function set.DividerMarkings( obj, value )
+
+ % Check
+ assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ...
+ 'uix:InvalidArgument', ...
+ 'Property ''DividerMarkings'' must be ''on'' or ''off'.' )
+
+ % Set
+ obj.DividerMarkings_ = value;
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % set.DividerMarkings
+
+ end % accessors
+
+ methods( Access = protected )
+
+ function onMousePress( obj, source, eventData )
+ %onMousePress Handler for WindowMousePress events
+
+ % Check whether mouse is over a divider
+ loc = find( obj.RowDividers.isMouseOver( eventData ) );
+ if isempty( loc ), return, end
+
+ % Capture state at button down
+ divider = obj.RowDividers(loc);
+ obj.ActiveDivider = loc;
+ obj.ActiveDividerPosition = divider.Position;
+ root = groot();
+ obj.MousePressLocation = root.PointerLocation;
+
+ % Make sure the pointer is appropriate
+ obj.updateMousePointer( source, eventData );
+
+ % Activate divider
+ frontDivider = obj.FrontDivider;
+ frontDivider.Position = divider.Position;
+ divider.Visible = 'off';
+ frontDivider.Parent = [];
+ frontDivider.Parent = obj;
+ frontDivider.Visible = 'on';
+
+ end % onMousePress
+
+ function onMouseRelease( obj, ~, ~ )
+ %onMousePress Handler for WindowMouseRelease events
+
+ % Compute new positions
+ loc = obj.ActiveDivider;
+ if loc > 0
+ root = groot();
+ delta = root.PointerLocation(2) - obj.MousePressLocation(2);
+ ih = loc;
+ jh = loc + 1;
+ ic = loc;
+ jc = loc + 1;
+ divider = obj.RowDividers(loc);
+ contents = obj.Contents_;
+ ip = uix.getPosition( contents(ic), 'pixels' );
+ jp = uix.getPosition( contents(jc), 'pixels' );
+ oldPixelHeights = [ip(4); jp(4)];
+ minimumHeights = obj.MinimumHeights_(ih:jh,:);
+ if delta < 0 % limit to minimum distance from lower neighbor
+ delta = max( delta, minimumHeights(2) - oldPixelHeights(2) );
+ else % limit to minimum distance from upper neighbor
+ delta = min( delta, oldPixelHeights(1) - minimumHeights(1) );
+ end
+ oldHeights = obj.Heights_(loc:loc+1);
+ newPixelHeights = oldPixelHeights - delta * [1;-1];
+ if oldHeights(1) < 0 && oldHeights(2) < 0 % weight, weight
+ newHeights = oldHeights .* newPixelHeights ./ oldPixelHeights;
+ elseif oldHeights(1) < 0 && oldHeights(2) >= 0 % weight, pixels
+ newHeights = [oldHeights(1) * newPixelHeights(1) / ...
+ oldPixelHeights(1); newPixelHeights(2)];
+ elseif oldHeights(1) >= 0 && oldHeights(2) < 0 % pixels, weight
+ newHeights = [newPixelHeights(1); oldHeights(2) * ...
+ newPixelHeights(2) / oldPixelHeights(2)];
+ else % sizes(1) >= 0 && sizes(2) >= 0 % pixels, pixels
+ newHeights = newPixelHeights;
+ end
+ obj.Heights_(loc:loc+1) = newHeights;
+ else
+ return
+ end
+
+ % Deactivate divider
+ obj.FrontDivider.Visible = 'off';
+ divider.Visible = 'on';
+
+ % Reset state at button down
+ obj.ActiveDivider = 0;
+ obj.ActiveDividerPosition = [NaN NaN NaN NaN];
+ obj.MousePressLocation = [NaN NaN];
+
+ % Mark as dirty
+ obj.Dirty = true;
+
+ end % onMouseRelease
+
+ function onMouseMotion( obj, source, eventData )
+ %onMouseMotion Handler for WindowMouseMotion events
+
+ loc = obj.ActiveDivider;
+ if loc == 0 % hovering, update pointer
+ obj.updateMousePointer( source, eventData );
+ else % dragging row divider
+ root = groot();
+ delta = root.PointerLocation(2) - obj.MousePressLocation(2);
+ ih = loc;
+ jh = loc + 1;
+ ic = loc;
+ jc = loc + 1;
+ contents = obj.Contents_;
+ ip = uix.getPosition( contents(ic), 'pixels' );
+ jp = uix.getPosition( contents(jc), 'pixels' );
+ oldPixelHeights = [ip(4); jp(4)];
+ minimumHeights = obj.MinimumHeights_(ih:jh,:);
+ if delta < 0 % limit to minimum distance from lower neighbor
+ delta = max( delta, minimumHeights(2) - oldPixelHeights(2) );
+ else % limit to minimum distance from upper neighbor
+ delta = min( delta, oldPixelHeights(1) - minimumHeights(1) );
+ end
+ obj.FrontDivider.Position = ...
+ obj.ActiveDividerPosition + [0 delta 0 0];
+ end
+
+ end % onMouseMotion
+
+ function onBackgroundColorChanged( obj, ~, ~ )
+ %onBackgroundColorChanged Handler for BackgroundColor changes
+
+ backgroundColor = obj.BackgroundColor;
+ highlightColor = min( [backgroundColor / 0.75; 1 1 1] );
+ shadowColor = max( [backgroundColor * 0.75; 0 0 0] );
+ rowDividers = obj.RowDividers;
+ for ii = 1:numel( rowDividers )
+ rowDivider = rowDividers(ii);
+ rowDivider.BackgroundColor = backgroundColor;
+ rowDivider.HighlightColor = highlightColor;
+ rowDivider.ShadowColor = shadowColor;
+ end
+ frontDivider = obj.FrontDivider;
+ frontDivider.BackgroundColor = shadowColor;
+
+ end % onBackgroundColorChanged
+
+ end % event handlers
+
+ methods( Access = protected )
+
+ function redraw( obj )
+ %redraw Redraw contents
+ %
+ % c.redraw() redraws the container c.
+
+ % Call superclass method
+ redraw@uix.VBox( obj )
+
+ % Create or destroy row dividers
+ q = numel( obj.RowDividers ); % current number of dividers
+ r = max( [numel( obj.Heights_ )-1 0] ); % required number of dividers
+ if q < r % create
+ for ii = q+1:r
+ divider = uix.Divider( 'Parent', obj, ...
+ 'Orientation', 'horizontal', ...
+ 'BackgroundColor', obj.BackgroundColor );
+ obj.RowDividers(ii,:) = divider;
+ end
+ elseif q > r % destroy
+ % Destroy dividers
+ delete( obj.RowDividers(r+1:q,:) )
+ obj.RowDividers(r+1:q,:) = [];
+ % Update pointer
+ if r == 0 && strcmp( obj.Pointer, 'top' )
+ obj.unsetPointer()
+ end
+ end
+
+ % Compute container bounds
+ bounds = hgconvertunits( ancestor( obj, 'figure' ), ...
+ [0 0 1 1], 'normalized', 'pixels', obj );
+
+ % Retrieve size properties
+ heights = obj.Heights_;
+ minimumHeights = obj.MinimumHeights_;
+ padding = obj.Padding_;
+ spacing = obj.Spacing_;
+
+ % Compute row divider positions
+ xRowPositions = [padding + 1, max( bounds(3) - 2 * padding, 1 )];
+ xRowPositions = repmat( xRowPositions, [r 1] );
+ yRowSizes = uix.calcPixelSizes( bounds(4), heights, ...
+ minimumHeights, padding, spacing );
+ yRowPositions = [bounds(4) - cumsum( yRowSizes(1:r,:) ) - padding - ...
+ spacing * transpose( 1:r ) + 1, repmat( spacing, [r 1] )];
+ rowPositions = [xRowPositions(:,1), yRowPositions(:,1), ...
+ xRowPositions(:,2), yRowPositions(:,2)];
+
+ % Position row dividers
+ for ii = 1:r
+ rowDivider = obj.RowDividers(ii);
+ rowDivider.Position = rowPositions(ii,:);
+ switch obj.DividerMarkings_
+ case 'on'
+ rowDivider.Markings = rowPositions(ii,3)/2;
+ case 'off'
+ rowDivider.Markings = zeros( [0 1] );
+ end
+ end
+
+ end % redraw
+
+ function reparent( obj, oldFigure, newFigure )
+ %reparent Reparent container
+ %
+ % c.reparent(a,b) reparents the container c from the figure a
+ % to the figure b.
+
+ % Update listeners
+ if isempty( newFigure )
+ mousePressListener = event.listener.empty( [0 0] );
+ mouseReleaseListener = event.listener.empty( [0 0] );
+ mouseMotionListener = event.listener.empty( [0 0] );
+ else
+ mousePressListener = event.listener( newFigure, ...
+ 'WindowMousePress', @obj.onMousePress );
+ mouseReleaseListener = event.listener( newFigure, ...
+ 'WindowMouseRelease', @obj.onMouseRelease );
+ mouseMotionListener = event.listener( newFigure, ...
+ 'WindowMouseMotion', @obj.onMouseMotion );
+ end
+ obj.MousePressListener = mousePressListener;
+ obj.MouseReleaseListener = mouseReleaseListener;
+ obj.MouseMotionListener = mouseMotionListener;
+
+ % Call superclass method
+ reparent@uix.VBox( obj, oldFigure, newFigure )
+
+ % Update pointer
+ if ~isempty( oldFigure ) && ~strcmp( obj.Pointer, 'unset' )
+ obj.unsetPointer()
+ end
+
+ end % reparent
+
+ end % template methods
+
+ methods( Access = protected )
+
+ function updateMousePointer ( obj, source, eventData )
+
+ oldPointer = obj.Pointer;
+ if any( obj.RowDividers.isMouseOver( eventData ) )
+ newPointer = 'top';
+ else
+ newPointer = 'unset';
+ end
+ switch newPointer
+ case oldPointer % no change
+ % do nothing
+ case 'unset' % change, unset
+ obj.unsetPointer()
+ otherwise % change, set
+ obj.setPointer( source, newPointer )
+ end
+
+ end % updateMousePointer
+
+ end % helpers methods
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/VButtonBox.m b/studio_functions/GUI Layout Toolbox/layout/+uix/VButtonBox.m
new file mode 100644
index 00000000..1f32d500
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/VButtonBox.m
@@ -0,0 +1,93 @@
+classdef VButtonBox < uix.ButtonBox
+ %uix.VButtonBox Vertical button box
+ %
+ % b = uix.VButtonBox(p1,v1,p2,v2,...) constructs a vertical button box
+ % and sets parameter p1 to value v1, etc.
+ %
+ % A vertical button box lays out equally sized buttons from top to
+ % bottom.
+ %
+ % See also: uix.HButtonBox
+
+ % Copyright 2009-2020 The MathWorks, Inc.
+
+ methods
+
+ function obj = VButtonBox( varargin )
+ %uix.VButtonBox Vertical button box constructor
+ %
+ % b = uix.VButtonBox() constructs a vertical button box.
+ %
+ % b = uix.VButtonBox(p1,v1,p2,v2,...) sets parameter p1 to
+ % value v1, etc.
+
+ % Set properties
+ try
+ uix.set( obj, varargin{:} )
+ catch e
+ delete( obj )
+ e.throwAsCaller()
+ end
+
+ end % constructor
+
+ end % structors
+
+ methods( Access = protected )
+
+ function redraw( obj )
+
+ % Compute positions
+ bounds = hgconvertunits( ancestor( obj, 'figure' ), ...
+ [0 0 1 1], 'normalized', 'pixels', obj );
+ buttonSize = obj.ButtonSize_;
+ padding = obj.Padding_;
+ spacing = obj.Spacing_;
+ r = numel( obj.Contents_ );
+ if 2 * padding + buttonSize(1) > bounds(3)
+ xSizes = repmat( uix.calcPixelSizes( bounds(3), -1, 1, ...
+ padding, spacing ), [r 1] ); % shrink to fit
+ else
+ xSizes = repmat( buttonSize(1), [r 1] );
+ end
+ switch obj.HorizontalAlignment
+ case 'left'
+ xPositions = [repmat( padding, [r 1] ) + 1, xSizes];
+ case 'center'
+ xPositions = [(bounds(3) - xSizes) / 2 + 1, xSizes];
+ case 'right'
+ xPositions = [bounds(3) - xSizes - padding + 1, xSizes];
+ end
+ if 2 * padding + (r-1) * spacing + r * buttonSize(2) > bounds(4)
+ ySizes = uix.calcPixelSizes( bounds(4), -ones( [r 1] ), ...
+ ones( [r 1] ), padding, spacing ); % shrink to fit
+ else
+ ySizes = repmat( buttonSize(2), [r 1] );
+ end
+ switch obj.VerticalAlignment
+ case 'top'
+ yPositions = [bounds(4) - padding - cumsum( ySizes ) - ...
+ spacing * transpose( 0:r-1 ) + 1, ySizes];
+ case 'middle'
+ yPositions = [bounds(4) / 2 + sum( ySizes ) / 2 + ...
+ spacing * (r-1) / 2 - cumsum( ySizes ) - ...
+ spacing * transpose( 0:r-1 ) + 1, ySizes];
+ case 'bottom'
+ yPositions = [sum( ySizes ) + spacing * (r-1) - ...
+ cumsum( ySizes ) - spacing * transpose( 0:r-1 ) + ...
+ padding + 1, ySizes];
+ end
+ positions = [xPositions(:,1), yPositions(:,1), ...
+ xPositions(:,2), yPositions(:,2)];
+
+ % Set positions
+ children = obj.Contents_;
+ for ii = 1:numel( children )
+ uix.setPosition( children(ii), positions(ii,:), 'pixels' )
+ end
+
+ end % redraw
+
+ end % template methods
+
+end % classdef
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/calcPixelSizes.m b/studio_functions/GUI Layout Toolbox/layout/+uix/calcPixelSizes.m
new file mode 100644
index 00000000..24b35e7b
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/calcPixelSizes.m
@@ -0,0 +1,46 @@
+function pSizes = calcPixelSizes( pTotal, mSizes, pMinima, pPadding, pSpacing )
+%calcPixelSizes Calculate child sizes in pixels
+%
+% pSizes = uix.calcPixelSizes(total,mSizes,minSizes,padding,spacing)
+% computes child sizes (in pixels) given total available size (in pixels),
+% child sizes (in pixels and/or relative), minimum child sizes (in
+% pixels), padding (in pixels) and spacing (in pixels).
+%
+% Notes:
+% * All children are at least as large as the minimum specified size
+% * Relative sizes are respected for children larger than then minimum
+% specified size
+% * Children may extend beyond the total available size if the minimum
+% sizes, padding and spacing are too large
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+% Initialize
+pSizes = NaN( size( mSizes ) ); % output
+n = numel( mSizes ); % need this later
+
+% Apply absolute sizes
+a = mSizes >= 0; % absolute
+pSizes(a) = max( mSizes(a), pMinima(a) );
+
+while true
+
+ u = isnan( pSizes ); % unsolved
+ pUnsolvedTotal = pTotal - max( (n-1), 0 ) * pSpacing ...
+ - 2 * sign( n ) * pPadding - sum( pSizes(~u) );
+ pUnsolvedSizes = mSizes(u) / sum( mSizes(u) ) * pUnsolvedTotal;
+ pUnsolvedMinima = pMinima(u);
+ s = pUnsolvedSizes < pUnsolvedMinima; % small
+ if any( s )
+ pUnsolvedSizes(s) = pUnsolvedMinima(s);
+ pUnsolvedSizes(~s) = NaN;
+ pSizes(u) = pUnsolvedSizes;
+ % repeat
+ else
+ pSizes(u) = pUnsolvedSizes;
+ break % done
+ end
+
+end
+
+end % calcPixelSizes
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/getPosition.m b/studio_functions/GUI Layout Toolbox/layout/+uix/getPosition.m
new file mode 100644
index 00000000..bd9cb608
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/getPosition.m
@@ -0,0 +1,42 @@
+function p = getPosition( o, u )
+%getPosition Get position of graphics object
+%
+% p = getPosition(o,u) sets the position of a graphics object o with units
+% u.
+%
+% In contrast to getting the Position property directly, this function
+% honors the ActivePositionProperty of axes.
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+% Get position
+if ~isempty( findprop( o, 'ActivePositionProperty' ) )
+ switch o.ActivePositionProperty
+ case 'position'
+ q = o.Position;
+ case 'outerposition'
+ q = o.OuterPosition;
+ otherwise
+ error( 'uix:InvalidState', ...
+ 'Unknown value ''%s'' for property ''ActivePositionProperty'' of %s.', ...
+ o.ActivePositionProperty, class( o ) )
+ end
+else
+ q = o.Position;
+end
+
+% Get units
+if ~isempty( findprop( o, 'Units' ) )
+ v = o.Units;
+else
+ v = 'pixels';
+end
+
+% Convert
+if strcmp( u, v ) % trivial
+ p = q;
+else % conversion required
+ p = hgconvertunits( ancestor( o, 'figure' ), q, v, u, o.Parent );
+end
+
+end % getPosition
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/loadIcon.m b/studio_functions/GUI Layout Toolbox/layout/+uix/loadIcon.m
new file mode 100644
index 00000000..607c1d24
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/loadIcon.m
@@ -0,0 +1,101 @@
+function cdata = loadIcon( filename, bgcol )
+%loadIcon Load an icon and set the transparent color
+%
+% cdata = uix.loadIcon(filename) loads the icon from the specified
+% filename. For PNG files with transparency, the transparent pixels are
+% set to NaN. For other files, pixels that are pure green are set to
+% transparent (i.e., "green screen"). The resulting cdata is an RGB
+% double array.
+%
+% cdata = uix.loadIcon(filename,bgcol) tries to merge the color data with
+% the specified background colour bgcol. Fully transparent pixels are
+% still set to NaN, but partially transparent pixels are merged with the
+% background.
+%
+% See also: imread
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+% Check inputs
+narginchk( 1, 2 )
+if nargin < 2
+ bgcol = get( 0, 'DefaultUIControlBackgroundColor' );
+end
+
+% First try normally
+thisDir = fileparts( mfilename( 'fullpath' ) );
+iconDir = fullfile( thisDir, 'Resources' );
+if exist( filename, 'file' )
+ [cdata, map, alpha] = imread( filename );
+elseif exist( fullfile( iconDir, filename ), 'file' )
+ [cdata, map, alpha] = imread( fullfile( iconDir, filename ) );
+else
+ error( 'uix:FileNotFound', 'Cannot open file ''%s''.', filename )
+end
+
+% Convert indexed images to RGB
+if ~isempty( map )
+ cdata = ind2rgb( cdata, map );
+end
+
+% Convert to double before applying transparency
+cdata = convertToDouble( cdata );
+
+% Handle transparency
+[rows, cols, ~] = size( cdata );
+if ~isempty( alpha )
+
+ % Transparency specified
+ alpha = convertToDouble( alpha );
+ f = find( alpha==0 );
+ if ~isempty( f )
+ cdata(f) = NaN;
+ cdata(f + rows*cols) = NaN;
+ cdata(f + 2*rows*cols) = NaN;
+ end
+ % Now blend partial alphas
+ f = find( alpha(:)>0 & alpha(:)<1 );
+ if ~isempty(f)
+ cdata(f) = cdata(f).*alpha(f) + bgcol(1)*(1-alpha(f));
+ cdata(f + rows*cols) = cdata(f + rows*cols).*alpha(f) + bgcol(2)*(1-alpha(f));
+ cdata(f + 2*rows*cols) = cdata(f + 2*rows*cols).*alpha(f) + bgcol(3)*(1-alpha(f));
+ end
+
+else
+
+ % Do a "green screen", treating anything pure-green as transparent
+ f = find( cdata(:,:,1)==0 & cdata(:,:,2)==1 & cdata(:,:,3)==0 );
+ cdata(f) = NaN;
+ cdata(f + rows*cols) = NaN;
+ cdata(f + 2*rows*cols) = NaN;
+
+end
+
+end % uix.loadIcon
+
+% -------------------------------------------------------------------------
+
+function cdata = convertToDouble( cdata )
+%convertToDouble Convert image data to double in the range [0,1]
+%
+% cdata = convertToDouble(cData)
+
+switch lower( class( cdata ) )
+ case 'double'
+ % do nothing
+ case 'single'
+ cdata = double( cdata );
+ case 'uint8'
+ cdata = double( cdata ) / 255;
+ case 'uint16'
+ cdata = double( cdata ) / 65535;
+ case 'int8'
+ cdata = ( double( cdata ) + 128 ) / 255;
+ case 'int16'
+ cdata = ( double( cdata ) + 32768 ) / 65535;
+ otherwise
+ error( 'uix:InvalidArgument', ...
+ 'Image data of type ''%s'' is not supported.', class( cdata ) )
+end
+
+end % convertToDouble
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/set.m b/studio_functions/GUI Layout Toolbox/layout/+uix/set.m
new file mode 100644
index 00000000..9c54979c
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/set.m
@@ -0,0 +1,16 @@
+function set( obj, varargin )
+%uix.set Set property values
+%
+% uix.set(o,p1,v1,p2,v2,...) sets property p1 of the object o to value v1,
+% property p2 to value v2, etc.
+%
+% In contrast to builtin set, querying possible values is not supported.
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+if nargin == 1, return, end
+assert( rem( nargin, 2 ) == 1, 'uix:InvalidArgument', ...
+ 'Parameters and values must be provided in pairs.' )
+set( obj, varargin{:} )
+
+end % set
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/setPosition.m b/studio_functions/GUI Layout Toolbox/layout/+uix/setPosition.m
new file mode 100644
index 00000000..e493bf77
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/setPosition.m
@@ -0,0 +1,36 @@
+function setPosition( o, p, u )
+%setPosition Set position of graphics object
+%
+% setPosition(o,p,u) sets the position of a graphics object o to value p
+% with units u.
+%
+% In contrast to setting the Position property directly, this function
+% honors the ActivePositionProperty of axes.
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+% Set units
+if ~isempty( findprop( o, 'Units' ) )
+ o.Units = u;
+else
+ assert( strcmp( u, 'pixels' ), 'uix:InvalidOperation', ...
+ 'Objects without property ''Units'' have units of ''pixels''.' )
+end
+
+% Set position
+if ~isempty( findprop( o, 'ActivePositionProperty' ) )
+ switch o.ActivePositionProperty
+ case 'position'
+ o.Position = p;
+ case 'outerposition'
+ o.OuterPosition = p;
+ otherwise
+ error( 'uix:InvalidState', ...
+ 'Unknown value ''%s'' for property ''ActivePositionProperty'' of %s.', ...
+ o.ActivePositionProperty, class( o ) )
+ end
+else
+ o.Position = p;
+end
+
+end % setPosition
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/tracking.m b/studio_functions/GUI Layout Toolbox/layout/+uix/tracking.m
new file mode 100644
index 00000000..84eaee14
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/+uix/tracking.m
@@ -0,0 +1,228 @@
+function varargout = tracking( varargin )
+%tracking Track anonymized usage data
+%
+% tracking(p,v,id) tracks usage to the property p for the product version
+% v and identifier id. No personally identifiable information is tracked.
+%
+% r = tracking(...) returns the server response r, for debugging purposes.
+%
+% tracking('on') turns tracking on. tracking('off') turns tracking off.
+% tracking('query') returns the tracking state.
+
+% tracking('spoof') sets the tracking settings -- domain, language,
+% client, MATLAB version, operating system version -- to spoof values.
+% tracking('reset') sets the tracking settings to normal values.
+%
+% [t,s] = tracking('query') returns the tracking state t and settings s.
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+persistent STATE USERNAME DOMAIN LANGUAGE CLIENT MATLAB OS
+if isempty( STATE )
+ STATE = getpref( 'Tracking', 'State', 'on' );
+ if strcmp( STATE, 'snooze' ) % deprecated
+ setpref( 'Tracking', 'State', 'on' )
+ STATE = 'on';
+ end
+ if ispref( 'Tracking', 'Date' ) % deprecated
+ rmpref( 'Tracking', 'Date' )
+ end
+ USERNAME = getenv( 'USERNAME' );
+ reset()
+end % initialize
+
+switch nargin
+ case 1
+ switch varargin{1}
+ case {'on','off'}
+ STATE = varargin{1};
+ setpref( 'Tracking', 'State', varargin{1} ) % persist
+ case 'spoof'
+ spoof()
+ case 'reset'
+ reset()
+ case 'query'
+ varargout{1} = STATE;
+ varargout{2} = query();
+ otherwise
+ error( 'tracking:InvalidArgument', ...
+ 'Valid options are ''on'', ''off'' and ''query''.' )
+ end
+ case 3
+ switch nargout
+ case 0
+ if strcmp( STATE, 'off' ), return, end
+ uri = 'https://www.google-analytics.com/collect';
+ track( uri, varargin{:} );
+ case 1
+ uri = 'https://www.google-analytics.com/debug/collect';
+ varargout{1} = track( uri, varargin{:} );
+ otherwise
+ nargoutchk( 0, 1 )
+ end
+ otherwise
+ narginchk( 3, 3 )
+end % switch
+
+ function reset()
+ %reset Set normal settings
+
+ DOMAIN = lower( getenv( 'USERDOMAIN' ) );
+ LANGUAGE = char( java.util.Locale.getDefault() );
+ CLIENT = getpref( 'Tracking', 'Client', uuid() );
+ MATLAB = matlab();
+ OS = os();
+
+ end % reset
+
+ function spoof()
+ %spoof Set spoof settings
+
+ DOMAIN = randomDomain();
+ LANGUAGE = randomLanguage();
+ CLIENT = randomClient();
+ MATLAB = randomMatlab();
+ OS = randomOs();
+
+ end % spoof
+
+ function s = query()
+ %query Return settings
+
+ s.Username = USERNAME;
+ s.Domain = DOMAIN;
+ s.Language = LANGUAGE;
+ s.Client = CLIENT;
+ s.Matlab = MATLAB;
+ s.Os = OS;
+
+ end % query
+
+ function varargout = track( uri, p, v, s )
+ %track Do tracking
+
+ a = sprintf( '%s/%s (%s)', MATLAB, v, OS );
+ if isdeployed()
+ ds = 'deployed';
+ elseif strcmp( DOMAIN, 'mathworks' )
+ ds = DOMAIN;
+ else
+ ds = 'unknown';
+ end
+ pv = {'v', '1', 'tid', p, 'ua', escape( a ), 'ul', LANGUAGE, ...
+ 'cid', CLIENT, 'ht', 'pageview', ...
+ 'dp', sprintf( '/%s', s ), 'ds', ds};
+ [varargout{1:nargout}] = urlread( uri, 'Post', pv );
+
+ end % track
+
+end % tracking
+
+function s = randomDomain()
+%randomDomain Random domain string
+
+switch randi( 4 )
+ case 1
+ s = 'mathworks';
+ otherwise
+ s = hash( uuid() );
+end
+
+end % randomDomain
+
+function s = randomLanguage()
+%randomLanguage Random language string
+
+lo = java.util.Locale.getAvailableLocales();
+s = char( lo(randi( numel( lo ) )) );
+
+end % randomLanguage
+
+function s = randomClient()
+%randomClient Random client identifier
+
+s = uuid();
+
+end % randomClient
+
+function s = matlab()
+%matlab MATLAB version string
+
+v = ver( 'MATLAB' );
+s = v.Release;
+s(s=='('|s==')') = [];
+
+end % matlab
+
+function s = randomMatlab()
+%randomMatlab Random MATLAB version string
+
+releases = {'R2014b' 'R2015a' 'R2015b' 'R2016a' 'R2016b'};
+s = releases{randi( numel( releases ) )};
+
+end % randomMatlab
+
+function s = os()
+%os Operating system string
+
+if ispc()
+ s = sprintf( 'Windows NT %s', ...
+ char( java.lang.System.getProperty( 'os.version' ) ) );
+elseif isunix()
+ s = 'Linux x86_64';
+elseif ismac()
+ s = sprintf( 'Macintosh; Intel OS X %s', ...
+ strrep( char( java.lang.System.getProperty( 'os.version' ) ), ' ', '_' ) );
+else
+ s = 'unknown';
+end
+
+end % os
+
+function s = randomOs()
+%randomOs Random operating system string
+
+switch randi( 3 )
+ case 1
+ versions = [5.1 5.2 6 6.1 6.2 6.3 10];
+ s = sprintf( 'Windows NT %.1f', ...
+ versions(randi( numel( versions ) )) );
+ case 2
+ s = 'Linux x86_64';
+ case 3
+ s = sprintf( 'Macintosh; Intel OS X 10_%d', ...
+ randi( [10 12] ) );
+end
+
+end % randomOs
+
+function s = escape( s )
+%escape Escape string
+
+s = char( java.net.URLEncoder.encode( s, 'UTF-8' ) );
+
+end % escape
+
+function h = hash( s )
+%hash Hash string
+%
+% See also: rptgen.hash
+
+persistent MD5
+if isempty( MD5 )
+ MD5 = java.security.MessageDigest.getInstance( 'MD5' );
+end
+
+MD5.update( uint8( s(:) ) );
+h = typecast( MD5.digest, 'uint8' );
+h = dec2hex( h )';
+h = lower( h(:) )';
+
+end % hash
+
+function s = uuid()
+%uuid Unique identifier
+
+s = char( java.util.UUID.randomUUID() );
+
+end % uuid
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layout/Contents.m b/studio_functions/GUI Layout Toolbox/layout/Contents.m
new file mode 100644
index 00000000..42a7f207
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/Contents.m
@@ -0,0 +1,27 @@
+% GUI Layout Toolbox
+% Version 2.3.5 (R2020b) 31-October-2020
+%
+% Panels
+% uix.Panel - arrange a single element inside a standard panel
+% uix.CardPanel - show one element from a list
+% uix.BoxPanel - arrange a single element inside a panel with a boxed title
+% uix.TabPanel - arrange elements in a panel with tabs for selecting which is visible
+% uix.ScrollingPanel - arrange a single element inside a scrollable panel
+%
+% Boxes
+% uix.HBox - arrange elements horizontally in a single row
+% uix.VBox - arrange elements vertically in a single column
+% uix.HBoxFlex - arrange elements horizontally with draggable dividers
+% uix.VBoxFlex - arrange elements vertically with draggable dividers
+% uix.HButtonBox - arrange buttons horizontally in a single row
+% uix.VButtonBox - arrange buttons vertically in a single column
+%
+% Grids
+% uix.Grid - arrange elements in a two-dimensional grid
+% uix.GridFlex - arrange elements in a two-dimensional grid with draggable dividers
+%
+% Other
+% uix.Empty - create an empty space
+% uix.tracking - track anonymized usage data
+
+% Copyright 2009-2020 The MathWorks, Inc.
diff --git a/studio_functions/GUI Layout Toolbox/layout/layoutRoot.m b/studio_functions/GUI Layout Toolbox/layout/layoutRoot.m
new file mode 100644
index 00000000..f9726478
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layout/layoutRoot.m
@@ -0,0 +1,17 @@
+function folder = layoutRoot()
+%layoutRoot Folder containing the GUI Layout Toolbox
+%
+% folder = layoutRoot() returns the full path to the folder containing
+% the GUI Layout Toolbox.
+%
+% Examples:
+% >> folder = layoutRoot()
+% folder = 'C:\tools\layouts2\layout'
+%
+% See also: layoutVersion
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+folder = fileparts( mfilename( 'fullpath' ) );
+
+end % layoutRoot
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/AxesExample.html b/studio_functions/GUI Layout Toolbox/layoutdoc/AxesExample.html
new file mode 100644
index 00000000..9190c604
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/AxesExample.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/AxesLegendsColorbars.html b/studio_functions/GUI Layout Toolbox/layoutdoc/AxesLegendsColorbars.html
new file mode 100644
index 00000000..3b8e3b36
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/AxesLegendsColorbars.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/BoxPanelFancyStuff.html b/studio_functions/GUI Layout Toolbox/layoutdoc/BoxPanelFancyStuff.html
new file mode 100644
index 00000000..ade0fa6a
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/BoxPanelFancyStuff.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Compiling.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Compiling.html
new file mode 100644
index 00000000..5e762277
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Compiling.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/ExampleApp.html b/studio_functions/GUI Layout Toolbox/layoutdoc/ExampleApp.html
new file mode 100644
index 00000000..4dfbaa5f
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/ExampleApp.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples.html
new file mode 100644
index 00000000..51160f2d
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples.html
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Examples
+
+
+
+
+
+
+
+
+ Examples
+
+ The following examples are provided as part of this documentation. Click
+ the name of any example to go to the corresponding page.
+
+ Basics
+
+ Layout hierarchy
+ Using layouts inside layouts to produce more complex designs
+
+
+ Using axes
+
+ Positioning axes
+ Using the different axes position properties.
+
+ Axes legends and colorbars
+ How to work with axes that may also have legends and/or colorbars.
+
+
+ Using panels
+
+ Context help
+ Adding context-sensitive help using panels.
+
+ Minimize and maximize
+ Creating a user interface with panels that can be minimized and
+ maximized.
+
+ Dock and undock
+ Creating a user interface with panels that can be undocked into
+ separate windows.
+
+
+ Visible
+
+ Show and hide
+ Showing and hiding a layout and its contents.
+
+
+ Applications
+
+ Building a complete application
+ Using layouts together to produce a complete application.
+
+
+
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/axesexample.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/axesexample.m
new file mode 100644
index 00000000..aaf49542
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/axesexample.m
@@ -0,0 +1,41 @@
+%% Axes inside layouts
+% This example demonstrates how axes are affected by being placed into
+% layouts. The layouts take into account the "ActivePositionProperty" in
+% order to determine whether to set the "Position" or "OuterPosition"
+% (default) property of the axes.
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+%% Open the window
+% Open a new figure window and remove the toolbar and menus
+window = figure( 'Name', 'Axes inside layouts', ...
+ 'MenuBar', 'none', ...
+ 'Toolbar', 'none', ...
+ 'NumberTitle', 'off' );
+
+%% Create the layout
+% The layout involves two axes side by side. This is done using a
+% flexible horizontal box. The left-hand axes is left with the
+% ActivePositionProperty set to "outerposition", but the right-hand axes is
+% switched to use "Position"
+hbox = uix.HBoxFlex('Parent', window, 'Spacing', 3);
+axes1 = axes( 'Parent', hbox, ...
+ 'ActivePositionProperty', 'outerposition' );
+axes2 = axes( 'Parent', hbox, ...
+ 'ActivePositionProperty', 'Position' );
+set( hbox, 'Widths', [-2 -1] );
+
+%% Fill the axes
+% Using "OuterPosition" (left-hand axes) is the normal mode and looks good
+% for virtually any plot type. Using "Position" is only really useful for
+% 2D plots with the axes turned off, such as images
+x = membrane( 1, 15 );
+surf( axes1, x );
+lighting( axes1, 'gouraud' );
+shading( axes1, 'interp' );
+l = light( 'Parent', axes1 );
+camlight( l, 'head' );
+axis( axes1, 'tight' );
+
+imagesc( x, 'Parent', axes2 );
+set( axes2, 'xticklabel', [], 'yticklabel', [] );
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/callbackexample.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/callbackexample.m
new file mode 100644
index 00000000..415aa47b
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/callbackexample.m
@@ -0,0 +1,47 @@
+function callbackexample()
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+% Create application data
+colorNames = {
+ 'Red'
+ 'Orange'
+ 'Yellow'
+ 'Green'
+ 'Blue'
+ 'Indigo'
+ 'Violet'
+ };
+colorValues = [
+ 1.0 0.2 0.2
+ 1.0 0.6 0.2
+ 1.0 1.0 0.4
+ 0.6 1.0 0.6
+ 0.2 0.4 1.0
+ 0.4 0.1 0.6
+ 0.7 0.5 1.0
+ ];
+
+% Layout the interface
+f = figure();
+p = uix.Panel( 'Parent', f, 'Title', 'A Panel', 'TitlePosition', 'CenterTop');
+b = uix.HBoxFlex( 'Parent', p, 'Spacing', 5, 'Padding', 5 );
+hList = uicontrol( 'Style', 'listbox', 'Parent', b, ...
+ 'String', colorNames, ...
+ 'Back', 'w' );
+hButton = uicontrol( 'Parent', b, ...
+ 'Background', colorValues(1,:), ...
+ 'String', colorNames{1} );
+set( b, 'Widths', [-1 -3] );
+
+% Add user interactions
+set( hList, 'Callback', @onChangeColor );
+
+
+ function onChangeColor( source, ~ )
+ idx = get( source, 'Value' );
+ set( hButton, 'Background', colorValues(idx,:), 'String', colorNames{idx} )
+ end % onChangeColor
+
+
+end % main
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/colorbarexample.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/colorbarexample.m
new file mode 100644
index 00000000..d873c690
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/colorbarexample.m
@@ -0,0 +1,29 @@
+%% Axes with colorbars inside layouts
+% This example demonstrates how to correctly layout axes that have
+% associated legends or colorbars by grouping them together using a
+% uicontainer.
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+%% Open the window
+% Open a new figure window and remove the toolbar and menus
+window = figure( 'Name', 'Axes legend and colorbars', ...
+ 'MenuBar', 'none', ...
+ 'Toolbar', 'none', ...
+ 'NumberTitle', 'off' );
+
+%% Create the layout
+% The layout involves two axes side by side. Each axes is placed into a
+% uicontainer so that the legend and colorbar are "grouped" with the axes.
+hbox = uix.VBoxFlex('Parent', window, 'Spacing', 3);
+axes1 = axes( 'Parent', uicontainer('Parent', hbox) );
+axes2 = axes( 'Parent', uicontainer('Parent', hbox) );
+
+%% Add decorations
+% Give the first axes a colorbar and the second axes a legend.
+surf( axes1, membrane( 1, 15 ) );
+colorbar( axes1 );
+
+theta = 0:360;
+plot( axes2, theta, sind(theta), theta, cosd(theta) );
+legend( axes2, 'sin', 'cos', 'Location', 'NorthWestOutside' );
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/demoBrowser.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/demoBrowser.m
new file mode 100644
index 00000000..3d2b17da
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/demoBrowser.m
@@ -0,0 +1,209 @@
+function demoBrowser()
+%demoBrowser: an example of using layouts to build a user interface
+%
+% demoBrowser() opens a simple GUI that allows several of MATLAB's
+% built-in demos to be viewed. It aims to demonstrate how multiple
+% layouts can be used to create a good-looking user interface that
+% retains the correct proportions when resized. It also shows how to
+% hook-up callbacks to interpret user interaction.
+%
+% See also: Layouts
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+% Data is shared between all child functions by declaring the variables
+% here (they become global to the function). We keep things tidy by putting
+% all GUI stuff in one structure and all data stuff in another. As the app
+% grows, we might consider making these objects rather than structures.
+data = createData();
+gui = createInterface( data.DemoNames );
+
+% Now update the GUI with the current data
+updateInterface();
+redrawDemo();
+
+% Explicitly call the demo display so that it gets included if we deploy
+displayEndOfDemoMessage('')
+
+%-------------------------------------------------------------------------%
+ function data = createData()
+ % Create the shared data-structure for this application
+ demoList = {
+ 'Complex surface' 'cplxdemo'
+ 'Cruller' 'cruller'
+ 'Earth' 'earthmap'
+ 'Four linked tori' 'tori4'
+ 'Klein bottle' 'xpklein'
+ 'Klein bottle (1)' 'klein1'
+ 'Knot' 'knot'
+ 'Logo' 'logo'
+ 'Spherical Surface Harmonic' 'spharm2'
+ 'Werner Boy''s Surface' 'wernerboy'
+ };
+ selectedDemo = 8;
+ data = struct( ...
+ 'DemoNames', {demoList(:,1)'}, ...
+ 'DemoFunctions', {demoList(:,2)'}, ...
+ 'SelectedDemo', selectedDemo );
+ end % createData
+
+%-------------------------------------------------------------------------%
+ function gui = createInterface( demoList )
+ % Create the user interface for the application and return a
+ % structure of handles for global use.
+ gui = struct();
+ % Open a window and add some menus
+ gui.Window = figure( ...
+ 'Name', 'Gallery browser', ...
+ 'NumberTitle', 'off', ...
+ 'MenuBar', 'none', ...
+ 'Toolbar', 'none', ...
+ 'HandleVisibility', 'off' );
+
+ % + File menu
+ gui.FileMenu = uimenu( gui.Window, 'Label', 'File' );
+ uimenu( gui.FileMenu, 'Label', 'Exit', 'Callback', @onExit );
+
+ % + View menu
+ gui.ViewMenu = uimenu( gui.Window, 'Label', 'View' );
+ for ii=1:numel( demoList )
+ uimenu( gui.ViewMenu, 'Label', demoList{ii}, 'Callback', @onMenuSelection );
+ end
+
+ % + Help menu
+ helpMenu = uimenu( gui.Window, 'Label', 'Help' );
+ uimenu( helpMenu, 'Label', 'Documentation', 'Callback', @onHelp );
+
+
+ % Arrange the main interface
+ mainLayout = uix.HBoxFlex( 'Parent', gui.Window, 'Spacing', 3 );
+
+ % + Create the panels
+ controlPanel = uix.BoxPanel( ...
+ 'Parent', mainLayout, ...
+ 'Title', 'Select a demo:' );
+ gui.ViewPanel = uix.BoxPanel( ...
+ 'Parent', mainLayout, ...
+ 'Title', 'Viewing: ???', ...
+ 'HelpFcn', @onDemoHelp );
+ gui.ViewContainer = uicontainer( ...
+ 'Parent', gui.ViewPanel );
+
+ % + Adjust the main layout
+ set( mainLayout, 'Widths', [-1,-2] );
+
+
+ % + Create the controls
+ controlLayout = uix.VBox( 'Parent', controlPanel, ...
+ 'Padding', 3, 'Spacing', 3 );
+ gui.ListBox = uicontrol( 'Style', 'list', ...
+ 'BackgroundColor', 'w', ...
+ 'Parent', controlLayout, ...
+ 'String', demoList(:), ...
+ 'Value', 1, ...
+ 'Callback', @onListSelection);
+ gui.HelpButton = uicontrol( 'Style', 'PushButton', ...
+ 'Parent', controlLayout, ...
+ 'String', 'Help for ', ...
+ 'Callback', @onDemoHelp );
+ set( controlLayout, 'Heights', [-1 28] ); % Make the list fill the space
+
+ % + Create the view
+ p = gui.ViewContainer;
+ gui.ViewAxes = axes( 'Parent', p );
+
+
+ end % createInterface
+
+%-------------------------------------------------------------------------%
+ function updateInterface()
+ % Update various parts of the interface in response to the demo
+ % being changed.
+
+ % Update the list and menu to show the current demo
+ set( gui.ListBox, 'Value', data.SelectedDemo );
+ % Update the help button label
+ demoName = data.DemoNames{ data.SelectedDemo };
+ set( gui.HelpButton, 'String', ['Help for ',demoName] );
+ % Update the view panel title
+ set( gui.ViewPanel, 'Title', sprintf( 'Viewing: %s', demoName ) );
+ % Untick all menus
+ menus = get( gui.ViewMenu, 'Children' );
+ set( menus, 'Checked', 'off' );
+ % Use the name to work out which menu item should be ticked
+ whichMenu = strcmpi( demoName, get( menus, 'Label' ) );
+ set( menus(whichMenu), 'Checked', 'on' );
+ end % updateInterface
+
+%-------------------------------------------------------------------------%
+ function redrawDemo()
+ % Draw a demo into the axes provided
+
+ % We first clear the existing axes ready to build a new one
+ if ishandle( gui.ViewAxes )
+ delete( gui.ViewAxes );
+ end
+
+ % Some demos create their own figure. Others don't.
+ fcnName = data.DemoFunctions{data.SelectedDemo};
+ switch upper( fcnName )
+ case 'LOGO'
+ % These demos open their own windows
+ evalin( 'base', fcnName );
+ gui.ViewAxes = gca();
+ fig = gcf();
+ set( fig, 'Visible', 'off' );
+
+ otherwise
+ % These demos need a window opening
+ fig = figure( 'Visible', 'off' );
+ evalin( 'base', fcnName );
+ gui.ViewAxes = gca();
+ end
+ % Now copy the axes from the demo into our window and restore its
+ % state.
+ cmap = colormap( gui.ViewAxes );
+ set( gui.ViewAxes, 'Parent', gui.ViewContainer );
+ colormap( gui.ViewAxes, cmap );
+ rotate3d( gui.ViewAxes, 'on' );
+ % Get rid of the demo figure
+ close( fig );
+ end % redrawDemo
+
+%-------------------------------------------------------------------------%
+ function onListSelection( src, ~ )
+ % User selected a demo from the list - update "data" and refresh
+ data.SelectedDemo = get( src, 'Value' );
+ updateInterface();
+ redrawDemo();
+ end % onListSelection
+
+%-------------------------------------------------------------------------%
+ function onMenuSelection( src, ~ )
+ % User selected a demo from the menu - work out which one
+ demoName = get( src, 'Label' );
+ data.SelectedDemo = find( strcmpi( demoName, data.DemoNames ), 1, 'first' );
+ updateInterface();
+ redrawDemo();
+ end % onMenuSelection
+
+
+%-------------------------------------------------------------------------%
+ function onHelp( ~, ~ )
+ % User has asked for the documentation
+ doc layout
+ end % onHelp
+
+%-------------------------------------------------------------------------%
+ function onDemoHelp( ~, ~ )
+ % User wnats documentation for the current demo
+ showdemo( data.DemoFunctions{data.SelectedDemo} );
+ end % onDemoHelp
+
+%-------------------------------------------------------------------------%
+ function onExit( ~, ~ )
+ % User wants to quit out of the application
+ delete( gui.Window );
+ end % onExit
+
+end % EOF
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/displayEndOfDemoMessage.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/displayEndOfDemoMessage.m
new file mode 100644
index 00000000..cd1ef215
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/displayEndOfDemoMessage.m
@@ -0,0 +1,4 @@
+function displayEndOfDemoMessage(filename)
+% Dummy function - do nothing.
+
+% Copyright 2009-2020 The MathWorks, Inc.
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/dockexample.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/dockexample.m
new file mode 100644
index 00000000..a03aef78
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/dockexample.m
@@ -0,0 +1,74 @@
+function dockexample()
+%DOCKEXAMPLE: An example of using the panelbox dock/undock functionality
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+% Create the window and main layout
+fig = figure( 'Name', 'Dockable GUI example', ...'
+ 'NumberTitle', 'off', ...
+ 'Toolbar', 'none', ...
+ 'MenuBar', 'none', ...
+ 'CloseRequestFcn', @nCloseAll );
+box = uix.HBox( 'Parent', fig );
+
+% Add three panels to the box
+panel{1} = uix.BoxPanel( 'Title', 'Panel 1', 'Parent', box );
+panel{2} = uix.BoxPanel( 'Title', 'Panel 2', 'Parent', box );
+panel{3} = uix.BoxPanel( 'Title', 'Panel 3', 'Parent', box );
+
+% Add some contents
+uicontrol( 'Style', 'PushButton', 'String', 'Button 1', 'Parent', panel{1} );
+uicontrol( 'Style', 'PushButton', 'String', 'Button 2', 'Parent', panel{2} );
+box1 = uix.VBox( 'Parent', panel{3} );
+box2 = uix.HBox( 'Parent', box1 );
+uicontrol( 'Style', 'PushButton', 'String', 'Button 3', 'Parent', box1 );
+uicontrol( 'Style', 'PushButton', 'String', 'Button 4', 'Parent', box2 );
+uicontrol( 'Style', 'PushButton', 'String', 'Button 5', 'Parent', box2 );
+
+% Set the dock/undock callback
+set( panel{1}, 'DockFcn', {@nDock, 1} );
+set( panel{2}, 'DockFcn', {@nDock, 2} );
+set( panel{3}, 'DockFcn', {@nDock, 3} );
+
+%-------------------------------------------------------------------------%
+ function nDock( eventSource, eventData, whichpanel ) %#ok
+ % Set the flag
+ panel{whichpanel}.Docked = ~panel{whichpanel}.Docked;
+ if panel{whichpanel}.Docked
+ % Put it back into the layout
+ newfig = get( panel{whichpanel}, 'Parent' );
+ set( panel{whichpanel}, 'Parent', box );
+ delete( newfig );
+ else
+ % Take it out of the layout
+ pos = getpixelposition( panel{whichpanel} );
+ newfig = figure( ...
+ 'Name', get( panel{whichpanel}, 'Title' ), ...
+ 'NumberTitle', 'off', ...
+ 'MenuBar', 'none', ...
+ 'Toolbar', 'none', ...
+ 'CloseRequestFcn', {@nDock, whichpanel} );
+ figpos = get( newfig, 'Position' );
+ set( newfig, 'Position', [figpos(1,1:2), pos(1,3:4)] );
+ set( panel{whichpanel}, 'Parent', newfig, ...
+ 'Units', 'Normalized', ...
+ 'Position', [0 0 1 1] );
+ end
+ end % nDock
+
+%-------------------------------------------------------------------------%
+ function nCloseAll( ~, ~ )
+ % User wished to close the application, so we need to tidy up
+
+ % Delete all windows, including undocked ones. We can do this by
+ % getting the window for each panel in turn and deleting it.
+ for ii=1:numel( panel )
+ if isvalid( panel{ii} ) && ~strcmpi( panel{ii}.BeingDeleted, 'on' )
+ figh = ancestor( panel{ii}, 'figure' );
+ delete( figh );
+ end
+ end
+
+ end % nCloseAll
+
+end % Main function
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/gridflexpositioning.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/gridflexpositioning.m
new file mode 100644
index 00000000..d3d90b3f
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/gridflexpositioning.m
@@ -0,0 +1,25 @@
+% Copyright 2009-2020 The MathWorks, Inc.
+
+f = figure();
+
+% Box Panel
+p = uix.BoxPanel( 'Parent', f, 'Title', 'A BoxPanel', 'Padding', 5 );
+
+% HBox
+b = uix.HBox( 'Parent', p, 'Spacing', 5, 'Padding', 5 );
+
+% uicontrol
+uicontrol( 'Style', 'listbox', 'Parent', b, 'String', {'Item 1','Item 2'} );
+
+% Grid Flex
+g = uix.GridFlex( 'Parent', b, 'Spacing', 5 );
+uicontrol( 'Parent', g, 'Background', 'r' );
+uicontrol( 'Parent', g, 'Background', 'b' );
+uicontrol( 'Parent', g, 'Background', 'g' );
+uix.Empty( 'Parent', g );
+uicontrol( 'Parent', g, 'Background', 'c' );
+uicontrol( 'Parent', g, 'Background', 'y' );
+set( g, 'Widths', [-1 100 -2], 'Heights', [-1 -2] );
+
+% set HBox elements sizes
+set( b, 'Widths', [100 -1] );
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/guideApp.fig b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/guideApp.fig
new file mode 100644
index 00000000..1f1ceca0
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/guideApp.fig differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/guideApp.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/guideApp.m
new file mode 100644
index 00000000..30978d30
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/guideApp.m
@@ -0,0 +1,106 @@
+function varargout = guideApp(varargin)
+% GUIDEAPP MATLAB code for guideApp.fig
+% GUIDEAPP, by itself, creates a new GUIDEAPP or raises the existing
+% singleton*.
+%
+% H = GUIDEAPP returns the handle to a new GUIDEAPP or the handle to
+% the existing singleton*.
+%
+% GUIDEAPP('CALLBACK',hObject,eventData,handles,...) calls the local
+% function named CALLBACK in GUIDEAPP.M with the given input arguments.
+%
+% GUIDEAPP('Property','Value',...) creates a new GUIDEAPP or raises the
+% existing singleton*. Starting from the left, property value pairs are
+% applied to the GUI before guideApp_OpeningFcn gets called. An
+% unrecognized property name or invalid value makes property application
+% stop. All inputs are passed to guideApp_OpeningFcn via varargin.
+%
+% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
+% instance to run (singleton)".
+%
+% See also: GUIDE, GUIDATA, GUIHANDLES
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+% Edit the above text to modify the response to help guideApp
+
+% Last Modified by GUIDE v2.5 21-Jul-2010 07:36:25
+
+% Begin initialization code - DO NOT EDIT
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @guideApp_OpeningFcn, ...
+ 'gui_OutputFcn', @guideApp_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+% End initialization code - DO NOT EDIT
+
+
+% --- Executes just before guideApp is made visible.
+function guideApp_OpeningFcn(hObject, eventdata, handles, varargin)
+% This function has no output args, see OutputFcn.
+% hObject handle to figure
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+% varargin command line arguments to guideApp (see VARARGIN)
+
+% Choose default command line output for guideApp
+handles.output = hObject;
+
+% Update handles structure
+guidata(hObject, handles);
+
+% Put a layout in the panel
+g = uix.GridFlex( 'Parent', handles.uipanel1, ...
+ 'Units', 'Normalized', 'Position', [0 0 1 1], ...
+ 'Spacing', 5 );
+uix.BoxPanel( 'Parent', g, 'Title', 'Panel 1' );
+uix.BoxPanel( 'Parent', g, 'Title', 'Panel 2' );
+uix.BoxPanel( 'Parent', g, 'Title', 'Panel 3' );
+uix.BoxPanel( 'Parent', g, 'Title', 'Panel 4' );
+g.Heights = [-1 -1];
+
+% UIWAIT makes guideApp wait for user response (see UIRESUME)
+% uiwait(handles.figure1);
+
+
+% --- Outputs from this function are returned to the command line.
+function varargout = guideApp_OutputFcn(hObject, eventdata, handles)
+% varargout cell array for returning output args (see VARARGOUT);
+% hObject handle to figure
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Get default command line output from handles structure
+varargout{1} = handles.output;
+
+
+% --- Executes on button press in pushbutton1.
+function pushbutton1_Callback(hObject, eventdata, handles)
+% hObject handle to pushbutton1 (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+
+% --- Executes on button press in pushbutton2.
+function pushbutton2_Callback(hObject, eventdata, handles)
+% hObject handle to pushbutton2 (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+
+% --- Executes on button press in pushbutton3.
+function pushbutton3_Callback(hObject, eventdata, handles)
+% hObject handle to pushbutton3 (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/hierarchyexample.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/hierarchyexample.m
new file mode 100644
index 00000000..08c39689
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/hierarchyexample.m
@@ -0,0 +1,33 @@
+%% A Hierarchy of Layouts Example
+% This example shows how to use layouts within other layouts to achieve
+% more complex user interface designs with the right mix of variable and
+% fixed sized components.
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+%% Open the window
+% Open a new figure window and remove the toolbar and menus
+window = figure( 'Name', 'A Layout Hierarchy Example', ...
+ 'MenuBar', 'none', ...
+ 'Toolbar', 'none', ...
+ 'NumberTitle', 'off', ...
+ 'Position', 200*ones(1,4) );
+
+%% Create the first layout (vertical box)
+% Inside this vertical box we place the axes
+vbox = uix.VBox( 'Parent', window );
+axes( 'Parent', vbox );
+
+%% Create the second layout (horizontal box)
+% Inside this horizontal box we place two buttons
+hbox = uix.HButtonBox( 'Parent', vbox, 'Padding', 5 );
+uicontrol( 'Parent', hbox, ...
+ 'String', 'Button 1' );
+uicontrol( 'Parent', hbox, ...
+ 'String', 'Button 2' );
+
+%% Set the sizes
+% We want the axes to grow with the window so set the first size to be -1
+% (which means variable size with wieght 1) and the buttons to stay fixed
+% height so set the second size to 35 (fixed height of 35 pixels)
+set( vbox, 'Heights', [-1 35] )
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/minimizeexample.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/minimizeexample.m
new file mode 100644
index 00000000..3eef1661
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/minimizeexample.m
@@ -0,0 +1,54 @@
+function minimizeexample()
+%MINIMIZEEXAMPLE: An example of using the panelbox minimize/maximize
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+width = 200;
+pheightmin = 20;
+pheightmax = 100;
+
+% Create the window and main layout
+fig = figure( 'Name', 'Collapsable GUI', ...'
+ 'NumberTitle', 'off', ...
+ 'Toolbar', 'none', ...
+ 'MenuBar', 'none' );
+box = uix.VBox( 'Parent', fig );
+
+panel{1} = uix.BoxPanel( 'Title', 'Panel 1', 'Parent', box );
+panel{2} = uix.BoxPanel( 'Title', 'Panel 2', 'Parent', box );
+panel{3} = uix.BoxPanel( 'Title', 'Panel 3', 'Parent', box );
+set( box, 'Heights', pheightmax*ones(1,3) );
+
+% Add some contents
+uicontrol( 'Style', 'PushButton', 'String', 'Button 1', 'Parent', panel{1} );
+uicontrol( 'Style', 'PushButton', 'String', 'Button 2', 'Parent', panel{2} );
+uicontrol( 'Style', 'PushButton', 'String', 'Button 3', 'Parent', panel{3} );
+
+% Resize the window
+pos = get( fig, 'Position' );
+set( fig, 'Position', [pos(1,1:2),width,sum(box.Heights)] );
+
+% Hook up the minimize callback
+set( panel{1}, 'MinimizeFcn', {@nMinimize, 1} );
+set( panel{2}, 'MinimizeFcn', {@nMinimize, 2} );
+set( panel{3}, 'MinimizeFcn', {@nMinimize, 3} );
+
+%-------------------------------------------------------------------------%
+ function nMinimize( eventSource, eventData, whichpanel ) %#ok
+ % A panel has been maximized/minimized
+ s = get( box, 'Heights' );
+ pos = get( fig, 'Position' );
+ panel{whichpanel}.Minimized = ~panel{whichpanel}.Minimized;
+ if panel{whichpanel}.Minimized
+ s(whichpanel) = pheightmin;
+ else
+ s(whichpanel) = pheightmax;
+ end
+ set( box, 'Heights', s );
+
+ % Resize the figure, keeping the top stationary
+ delta_height = pos(1,4) - sum( box.Heights );
+ set( fig, 'Position', pos(1,:) + [0 delta_height 0 -delta_height] );
+ end % nMinimize
+
+end % EOF
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/paneltabexample.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/paneltabexample.m
new file mode 100644
index 00000000..f9bb3938
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/paneltabexample.m
@@ -0,0 +1,59 @@
+%% A TabPanel Example
+% This example shows how to use tabs within a layout. It also shows how to
+% use the TabPanel Callback property to update other GUI elements when the
+% visible tab is changed.
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+%% Open the window
+% Open a new figure window and remove the toolbar and menus
+window = figure( 'Name', 'A TabPanel example', ...
+ 'MenuBar', 'none', ...
+ 'Toolbar', 'none', ...
+ 'NumberTitle', 'off' );
+
+%% Create the layout
+% The layout involves two panels side by side. This is done using a
+% flexible horizontal box. The left-hand side is filled with a standard
+% panel and the right-hand side with some tabs.
+hbox = uix.HBoxFlex('Parent', window, 'Spacing', 3);
+panel = uix.Panel( ...
+ 'Parent', hbox, ...
+ 'Padding', 5, ...
+ 'Title', 'Left' );
+tabpanel = uix.TabPanel( 'Parent', ...
+ hbox, ...
+ 'Padding', 0);
+
+%% Add a list on the left
+% Note that we link the callbacks from the list to the tab selection and
+% the tab callback to the list such that they are kept in sync.
+panellist = uicontrol( 'Style', 'list', ...
+ 'Parent', panel, ...
+ 'String', {'1', '2', '3'}, ...
+ 'BackgroundColor', 'w', ...
+ 'Callback', @(a,b) set( tabpanel, 'Selection', get( a, 'Value' ) ) );
+set( tabpanel, 'SelectionChangedFcn', @(a,b) set( panellist, 'Value', b.NewValue ) );
+
+%% Create some contents
+% Each tab is filled with a list box showing some numbers
+htab1 = uix.Panel( 'Parent', tabpanel, 'Padding', 5, 'Title', '1');
+uicontrol( 'Style', 'listbox', 'Parent', htab1, ...
+ 'String', {'1', '1', '1'}, ...
+ 'BackgroundColor', 'w' );
+
+htab2 = uix.Panel( 'Parent', tabpanel, 'Padding', 5, 'Title', '2');
+uicontrol( 'Style', 'listbox', 'Parent', htab2, ...
+ 'String', {'2', '2', '2'}, ...
+ 'BackgroundColor', 'w' );
+
+htab3 = uix.Panel( 'Parent', tabpanel, 'Padding', 5, 'Title', '3');
+uicontrol( 'Style', 'listbox', 'Parent', htab3, ...
+ 'String', {'3', '3', '3'}, ...
+ 'BackgroundColor', 'w' );
+
+%% Update the tab titles
+tabpanel.TabTitles = {'1', '2', '3'};
+
+%% Show the first tab
+tabpanel.Selection = 1;
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/visibleexample.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/visibleexample.m
new file mode 100644
index 00000000..49cb0985
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/visibleexample.m
@@ -0,0 +1,30 @@
+%% Showing/hiding a panel
+%
+% This example opens a simple user-interface with a panel full of
+% buttons. We can then show/hide the entire panel in one go. Note
+% that the previous state of the buttons is preserved.
+
+% Copyright 2009-2020 The MathWorks, Inc.
+
+%% Open a window and add a panel
+fig = figure( 'Name', 'Visible example', ...
+ 'Position', [100 100 150 250], ...
+ 'MenuBar', 'none', ...
+ 'ToolBar', 'none', ...
+ 'NumberTitle', 'off' );
+panel = uix.BoxPanel( 'Parent', fig, 'Title', 'Panel' );
+
+%% Put some buttons inside the panel
+box = uix.VButtonBox( 'Parent', panel );
+uicontrol( 'Parent', box, 'String', 'Button 1' );
+uicontrol( 'Parent', box, 'String', 'Button 2' );
+uicontrol( 'Parent', box, 'String', 'Button 3', 'Visible', 'off' );
+uicontrol( 'Parent', box, 'String', 'Button 4' );
+uicontrol( 'Parent', box, 'String', 'Button 5', 'Visible', 'off' );
+uicontrol( 'Parent', box, 'String', 'Button 6' );
+
+%% Try disabling the panel
+set( panel, 'Visible', 'off' );
+
+%% Try enabling the panel
+set( panel, 'Visible', 'on' );
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference.html
new file mode 100644
index 00000000..93363cab
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference.html
@@ -0,0 +1,190 @@
+
+
+
+
+
+
+
+ Function reference
+
+
+
+
+
+
+
+
+ Function reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_1.html
new file mode 100644
index 00000000..aceb184d
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_1.html
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+ uix.Panel
+
+
+
+
+
+
+
+
+
+ 1.1: uix.Panel
+
+
+
+
+ Arrange a single element inside a standard panel
+
+ obj
= uix.Panel(
)
+ creates a standard uipanel
object but with automatic management
+ of the contained widget or layout. The properties available are largely
+ the same as the builtin uipanel
object. Where more than one child is
+ added, the currently visible child is determined using the Selection property.
+
+ obj
= uix.Panel(
prop
,
value
,
...
)
+ also sets one or more property values.
+
+
+
+
+ uix.Panel properties
+ Property Value Description BackgroundColor
colorspec
Color to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b'). BeingDeleted
on | off Deletion status. BorderType
none | etchedin | etchedout | beveledin | beveledout | line Type of border around the uipanel area. BorderWidth
positive integer Width of the panel border. Contents
empty GraphicsPlaceholder array | array of graphics objects Children within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself. DeleteFcn
function_handle
Function to call when the layout is being deleted. FontAngle
normal | italic | oblique Title font angle. FontName
string Title font name (e.g. Arial, Helvetica etc). FontSize
positive integer Title font size. FontUnits
inches | centimeters | normalized | points | pixels Title font units for measuring size. FontWeight
light | normal | demi | bold Title font weight. ForegroundColor
colorspec
Title font color and/or color of 2-D border line. HighlightColor
colorspec
3-D frame highlight color. Padding
positive integer Number of pixels of extra space around the outside of the layout. Parent
empty GraphicsPlaceholder array | figure | container Parent of the layout. Position
[x y w h] Position (x,y) and size (w,h) within figure or container. Selection
positive integer or empty Which child is visible. ShadowColor
colorspec
3-D frame shadow color. Tag
string Tag to associate with layout. Title
string Title string. TitlePosition
lefttop | centertop | righttop | leftbottom | centerbottom | rightbottom Location of title string in relation to the panel. Type
string Type of graphics object. Units
inches | centimeters | normalized | points | pixels | characters Position units. Visible
on | off Visibility.
+
+ For example:
+ f = figure
();
+p = uix.Panel
( 'Parent'
, f, 'Title'
, 'A Panel'
, 'Padding'
, 5 );
+uicontrol
( 'Parent'
, p, 'Background'
, 'r'
)
+
+
+
+
+ f = figure
();
+p = uix.Panel
( 'Parent'
, f, 'Title'
, 'A Panel'
, 'TitlePosition'
, 'CenterTop');
+b = uix.HBox
( 'Parent'
, p, 'Spacing'
, 5, 'Padding'
, 5 );
+uicontrol
( 'Style', 'listbox', 'Parent'
, b, 'String'
, {'Item 1'
,'Item 2'
} );
+uicontrol
( 'Parent'
, b, 'Background'
, 'b'
);
+set
( b, 'Widths'
, [100 -1] );
+
+
+
+
+
+ See also:
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_2.html
new file mode 100644
index 00000000..57991f02
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_2.html
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+ uix.CardPanel
+
+
+
+
+
+
+
+
+
+ 1.2: uix.CardPanel
+
+
+
+
+ Show one element (card) from a list
+
+ obj
= uix.CardPanel(
)
+ creates a new card panel which allows
+ selection between the different child objects contained, making the
+ selected child fill the space available and all other children
+ invisible. This is commonly used for creating wizards or quick
+ switching between different views of a single data-set.
+
+ obj
= uix.CardPanel(
prop
,
value
,
...
)
+ also sets one or more property values.
+
+
+
+
+ uix.CardPanel properties
+ Property Value Description BackgroundColor
colorspec
Color to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b'). BeingDeleted
on | off Deletion status. Contents
empty GraphicsPlaceholder array | array of graphics objects Children within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself. DeleteFcn
function_handle
Function to call when the layout is being deleted. Padding
positive integer Number of pixels of extra space around the outside of the layout. Parent
empty GraphicsPlaceholder array | figure | container Parent of the layout. Position
[x y w h] Position (x,y) and size (w,h) within figure or container. Selection
positive integer or empty Which child is visible. Tag
string Tag to associate with layout. Type
string Type of graphics object. Units
inches | centimeters | normalized | points | pixels | characters Position units. Visible
on | off Visibility.
+
+ For example:
+ f = figure
();
+p = uix.CardPanel
( 'Parent'
, f, 'Padding'
, 5 );
+uicontrol
( 'Parent'
, p, 'Background'
, 'r'
);
+uicontrol
( 'Parent'
, p, 'Background'
, 'b'
);
+uicontrol
( 'Parent'
, p, 'Background'
, 'g'
);
+p.Selection = 2;
+
+
+
+
+
+ See also:
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_3.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_3.html
new file mode 100644
index 00000000..c803a727
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_3.html
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+ uix.BoxPanel
+
+
+
+
+
+
+
+
+
+ 1.3: uix.BoxPanel
+
+
+
+
+ Arrange a single element in a panel with boxed title
+
+ obj
= uix.BoxPanel(
)
+ creates a box-styled panel object with
+ automatic management of the contained widget or layout. The
+ properties available are largely the same as the builtin UIPANEL
+ object. Where more than one child is added, the currently visible
+ child is determined using the Selection property.
+
+ obj
= uix.BoxPanel(
prop
,
value
,
...
)
+ also sets one or more property values.
+
+
+
+
+ uix.BoxPanel properties
+ Property Value Description BackgroundColor
colorspec
Color to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b'). BeingDeleted
on | off Deletion status. BorderType
none | etchedin | etchedout | beveledin | beveledout | line Type of border around the title and content areas. Contents
empty GraphicsPlaceholder array | array of graphics objects Children within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself. CloseRequestFcn
function_handle
Function to call when the panel close icon is clicked. Note that if empty, no close button is shown. CloseTooltipString
string Custom tooltip string for close button. Note that if CloseRequestFcn is empty, no close button is shown. DeleteFcn
function_handle
Function to call when the layout is being deleted. Docked
logical Is this panel in a docked state. See advanced maneuvers with panels for details. DockFcn
function handle Function to call when panel is docked or undocked. Note that if empty, no dock button is shown. See advanced maneuvers with panels for details. DockTooltipString
string Custom tooltip string for dock button (when panel is undocked). Note that if DockFcn is empty, no dock button is shown. FontAngle
normal | italic | oblique Title font angle. FontName
string Title font name (e.g. Arial, Helvetica etc). FontSize
positive integer Title font size. FontUnits
inches | centimeters | normalized | points | pixels Title font units for measuring size. FontWeight
light | normal | demi | bold Title font weight. ForegroundColor
colorspec
Title font color and/or color of 2-D border line. HelpFcn
function handle Function to call when the help icon is clicked. Note that if empty, no help button is shown. See advanced maneuvers with panels for details. HelpTooltipString
string Custom tooltip string for help button. Note that if HelpFcn is empty, no help button is shown. HighlightColor
colorspec
3-D frame highlight color. MaximizeTooltipString
string Custom tooltip string for minimize button (when panel is minimized). Note that if MinimizeFcn is empty, no minimize button is shown. Minimized
logical Is this panel in a minimized state. See advanced maneuvers with panels for details. MinimizeFcn
function handle Function to call when panel is minimized or maximized. Note that if empty, no minimize button is shown. See advanced maneuvers with panels for details. MinimizeTooltipString
string Custom tooltip string for minimize button (when panel is maximized). Note that if MinimizeFcn is empty, no minimize button is shown. Padding
positive integer Number of pixels of extra space around the outside of the layout. Parent
empty GraphicsPlaceholder array | figure | container Parent of the layout. Position
[x y w h] Position (x,y) and size (w,h) within figure or container. Selection
positive integer or empty Which child is visible. ShadowColor
colorspec
3-D frame shadow color. Tag
string Tag to associate with layout. Title
string Title string. TitleColor
colorspec
color for the title bar background. Type
string Type of graphics object. UndockTooltipString
string Custom tooltip string for dock button (when panel is docked). Note that if DockFcn is empty, no dock button is shown. Units
inches | centimeters | normalized | points | pixels | characters Position units. Visible
on | off Visibility. See the visible example for more details.
+
+ For example:
+ f = figure
();
+p = uix.BoxPanel
( 'Parent'
, f, 'Title'
, 'A BoxPanel', 'Padding'
, 5 );
+uicontrol
( 'Parent'
, p, 'Background'
, 'r'
)
+
+
+
+
+ f = figure
();
+p = uix.BoxPanel
( 'Parent'
, f, 'Title'
, 'A BoxPanel', 'Padding'
, 5 );
+b = uix.HBox
( 'Parent'
, p, 'Spacing'
, 5, 'Padding'
, 5 );
+uicontrol
( 'Style', 'listbox', 'Parent'
, b, 'String'
, {'Item 1','Item 2'} );
+uicontrol
( 'Parent'
, b, 'Background'
, 'b'
);
+set
( b, 'Widths'
, [100 -1] );
+p.FontSize = 12;
+p.FontWeight = 'bold';
+p.HelpFcn = @(x,y) disp('Help me!');
+
+
+
+
+
+ See also:
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_4.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_4.html
new file mode 100644
index 00000000..272fc42f
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_4.html
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+ uix.TabPanel
+
+
+
+
+
+
+
+
+
+ 1.4: uix.TabPanel
+
+
+
+
+ Arrange elements in a panel with tabs for selecting which is visible
+
+ obj
= uix.TabPanel(
)
+ creates a panel with tabs along one edge
+ to allow selection between the different child objects contained.
+
+ obj
= uix.TabPanel(
prop
,
value
,
...
)
+ also sets one or more property values.
+
+
+
+
+ uix.TabPanel properties
+ Property Value Description BackgroundColor
colorspec
Color to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b'). BeingDeleted
on | off Deletion status. Contents
empty GraphicsPlaceholder array | array of graphics objects Children within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself. DeleteFcn
function_handle
Function to call when the layout is being deleted. FontAngle
normal | italic | oblique Title font angle. FontName
string Title font name (e.g. Arial, Helvetica etc). FontSize
positive integer Title font size. FontUnits
inches | centimeters | normalized | points | pixels Title font units for measuring size. FontWeight
light | normal | demi | bold Title font weight. ForegroundColor
colorspec
Title font color and/or color of 2-D border line. HighlightColor
colorspec
3-D frame highlight color. ShadowColor
colorspec
3-D frame shadow color. Padding
positive integer Number of pixels of extra space around the outside of the layout. Parent
empty GraphicsPlaceholder array | figure | container Parent of the layout. Position
[x y w h] Position (x,y) and size (w,h) within figure or container. Selection
positive integer or empty Which child is visible. SelectionChangedFcn
function_handle
Function to call when the selected tab is changed. The event-data supplied has fields OldValue
and NewValue
giving the previously selected and newly selected tab indices. TabContextMenus
cell array of context menus The context menu (or []) for each tab. TabEnables
cell array of on | off A list of the enabled state of each tab (default is all 'on'). TabTitles
cell array of strings A list of the names of the tabs with one entry per tab. TabWidth
positive integer Width of each tab in pixels (default 50). Tag
string Tag to associate with layout. Type
string Type of graphics object. Units
inches | centimeters | normalized | points | pixels | characters Position units. Visible
on | off Visibility.
+
+ For example:
+ f = figure
();
+p = uix.TabPanel
( 'Parent'
, f, 'Padding'
, 5 );
+uicontrol
( 'Parent'
, p, 'Background'
, 'r'
);
+uicontrol
( 'Parent'
, p, 'Background'
, 'b'
);
+uicontrol
( 'Parent'
, p, 'Background'
, 'g'
);
+p.TabTitles = {'Red'
, 'Blue'
, 'Green'
};
+p.Selection = 2;
+
+
+
+
+
+ See also:
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_5.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_5.html
new file mode 100644
index 00000000..2a5b9102
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_5.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ uix.ScrollingPanel
+
+
+
+
+
+
+
+
+
+ 1.5: uix.ScrollingPanel
+
+
+
+
+ Arrange a single element inside a panel and provide scrollbars if the panel is smaller than the element
+
+ obj
= uix.ScrollingPanel(
)
+ creates a new scrolling panel.
+
+ obj
= uix.ScrollingPanel(
prop
,
value
,
...
)
+ also sets one or more property values.
+
+
+
+
+ uix.ScrollingPanel properties
+ Property Value Description BackgroundColor
colorspec
Color to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b'). BeingDeleted
on | off Deletion status. Contents
empty GraphicsPlaceholder array | array of graphics objects Children within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself. DeleteFcn
function_handle
Function to call when the layout is being deleted. Heights
double vector Height of each of the children. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. The size of this vector must always match the size of Contents. HorizontalOffsets
double vector Horizontal offset of each of the children. Each value is limited to between 0 and the difference between the width of child and the width of the panel. The size of this vector must always match the size of Contents. HorizontalSteps
positive double vector Horizontal slider step for each of the children. The size of this vector must always match the size of Contents. MinimumHeights
double vector Minimum height in pixels of each of the children. The size of this vector must match the size of Contents. MinimumWidths
double vector Minimum width in pixels of each of the children. The size of this vector must match the size of Contents. MouseWheelEnabled
on | off Mouse wheel scrolling status (default 'on'). Padding
positive integer This property is not honored by this class. Parent
empty GraphicsPlaceholder array | figure | container Parent of the layout. Position
[x y w h] Position (x,y) and size (w,h) within figure or container. Selection
positive integer or empty Which child is visible. Tag
string Tag to associate with layout. Type
string Type of graphics object. Units
inches | centimeters | normalized | points | pixels | characters Position units. VerticalOffsets
double vector Vertical offset of each of the children. Each value is limited to between 0 and the difference between the height of child and the height of the panel. The size of this vector must always match the size of Contents. VerticalSteps
positive double vector Vertical slider step for each of the children. The size of this vector must always match the size of Contents. Visible
on | off Visibility. Widths
double vector Width of each of the children. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. The size of this vector must always match the size of Contents.
+
+ For example:
+ f = figure
( 'Name', 'uix.ScrollingPanel Help Example' );
+f.Position(3:4) = 400;
+p = uix.ScrollingPanel
( 'Parent', f );
+a = axes
( 'Parent', p );
+[x, y, z] = peaks
();
+surf( a, x, y, z )
+a.ActivePositionProperty = 'position';
+set
( p, 'Widths', 600, 'Heights', 600, 'HorizontalOffsets', 100, 'VerticalOffsets', 100 )
+
+
+
+
+
+ See also:
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_1.html
new file mode 100644
index 00000000..334aa25d
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_1.html
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+ uix.HBox
+
+
+
+
+
+
+
+
+
+ 2.1: uix.HBox
+
+
+
+
+
+
+
+ Arrange elements horizontally in a single row
+
+ obj
= uix.HBox(
)
+ creates a new horizontal box layout with all properties set to defaults.
+ The output is a new layout object that can be used as the parent for other user-interface components.
+
+ obj
= uix.HBox(
prop
,
value
,
...
)
+ also sets one or more property values.
+
+
+
+
+ uix.HBox properties
+ Property Value Description BackgroundColor
colorspec
Color to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b'). BeingDeleted
on | off Deletion status. Contents
empty GraphicsPlaceholder array | array of graphics objects Children within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself. DeleteFcn
function_handle
Function to call when the layout is being deleted. MinimumWidths
double vector Minimum width in pixels of each of the children. The size of this vector must match the size of Contents. Padding
positive integer Number of pixels of extra space around the outside of the layout. Parent
empty GraphicsPlaceholder array | figure | container Parent of the layout. Position
[x y w h] Position (x,y) and size (w,h) within figure or container. Spacing
positive integer Number of pixels of extra space to leave between elements in the layout. Tag
string Tag to associate with layout. Type
string Type of graphics object. Units
inches | centimeters | normalized | points | pixels | characters Position units. Visible
on | off Visibility. Widths
double vector Width of each of the children. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. The size of this vector must always match the size of Contents.
+
+ For example:
+ f = figure
();
+b = uix.HBox
( 'Parent'
, f );
+uicontrol
( 'Parent'
, b, 'Background'
, 'r'
)
+uicontrol
( 'Parent'
, b, 'Background'
, 'b'
)
+uicontrol
( 'Parent'
, b, 'Background'
, 'g'
)
+set
( b, 'Widths'
, [-1 100 -2], 'Spacing'
, 5 );
+
+
+
+
+ f = figure
();
+b1 = uix.VBox
( 'Parent'
, f );
+uicontrol
( 'Parent'
, b1, 'Background'
, 'r'
)
+b2 = uix.HBox
( 'Parent'
, b1, 'Padding'
, 5, 'Spacing'
, 5 );
+uicontrol
( 'Parent'
, b2, 'String'
, 'Button1'
)
+uicontrol
( 'Parent'
, b2, 'String'
, 'Button2'
)
+set
( b1, 'Widths'
, [30 -1] );
+
+
+
+
+
+ See also: uix.VBox
- for creating a vertical arrangementuix.HBoxFlex
- for creating a horizontal arrangement with draggable dividers
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_2.html
new file mode 100644
index 00000000..4c9f6724
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_2.html
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+ uix.VBox
+
+
+
+
+
+
+
+
+
+ 2.2: uix.VBox
+
+
+
+
+
+
+ Arrange elements vertically in a single column
+
+ obj
= uix.VBox(
)
+ creates a new vertical box layout with all properties set to defaults.
+ The output is a new layout object that can be used as the parent for other user-interface components.
+
+ obj
= uix.VBox(
prop
,
value
,
...
)
+ also sets one or more property values.
+
+
+
+
+ uix.VBox properties
+ Property Value Description BackgroundColor
colorspec
Color to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b'). BeingDeleted
on | off Deletion status. Contents
empty GraphicsPlaceholder array | array of graphics objects Children within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself. DeleteFcn
function_handle
Function to call when the layout is being deleted. Heights
double vector Height of each of the children. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. The size of this vector must always match the size of Contents. MinimumHeights
double vector Minimum height in pixels of each of the children. The size of this vector must match the size of Contents. Padding
positive integer Number of pixels of extra space around the outside of the layout. Parent
empty GraphicsPlaceholder array | figure | container Parent of the layout. Position
[x y w h] Position (x,y) and size (w,h) within figure or container. Spacing
positive integer Number of pixels of extra space to leave between elements in the layout. Tag
string Tag to associate with layout. Type
string Type of graphics object. Units
inches | centimeters | normalized | points | pixels | characters Position units. Visible
on | off Visibility.
+
+ For example:
+ f = figure
();
+b = uix.VBox
( 'Parent'
, f );
+uicontrol
( 'Parent'
, b, 'Background'
, 'r'
)
+uicontrol
( 'Parent'
, b, 'Background'
, 'b'
)
+uicontrol
( 'Parent'
, b, 'Background'
, 'g'
)
+set
( b, 'Heights'
, [-1 100 -2], 'Spacing'
, 5 );
+
+
+
+
+ f = figure
();
+b1 = uix.VBox
( 'Parent'
, f );
+uicontrol
( 'Parent'
, b1, 'Background'
, 'r'
)
+b2 = uix.HBox
( 'Parent'
, b1, 'Padding'
, 5, 'Spacing'
, 5 );
+uicontrol
( 'Parent'
, b2, 'String'
, 'Button1'
)
+uicontrol
( 'Parent'
, b2, 'String'
, 'Button2'
)
+set
( b1, 'Heights'
, [30 -1] );
+
+
+
+
+
+ See also: uix.HBox
- for creating a horizontal arrangementuix.VBoxFlex
- for creating a vertical arrangement with draggable dividers
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_3.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_3.html
new file mode 100644
index 00000000..8c933031
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_3.html
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+ uix.HBoxFlex
+
+
+
+
+
+
+
+
+
+ 2.3: uix.HBoxFlex
+
+
+
+
+
+
+
+
+ Arrange elements horizontally with draggable dividers
+
+ obj
= uix.HBoxFlex(
)
+ creates a new horizontal box layout with draggable dividers and with all properties set to defaults.
+ The output is a new layout object that can be used as the parent for other user-interface components.
+
+ obj
= uix.HBoxFlex(
prop
,
value
,
...
)
+ also sets one or more property values.
+
+
+
+
+ uix.HBoxFlex properties
+ Property Value Description BackgroundColor
colorspec
Color to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b'). BeingDeleted
on | off Deletion status. Contents
empty GraphicsPlaceholder array | array of graphics objects Children within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself. DeleteFcn
function_handle
Function to call when the layout is being deleted. DividerMarkings
on | off Show markings on the draggable dividers (default 'on'). MinimumWidths
double vector Minimum width in pixels of each of the children. The size of this vector must match the size of Contents. Padding
positive integer Number of pixels of extra space around the outside of the layout. Parent
empty GraphicsPlaceholder array | figure | container Parent of the layout. Position
[x y w h] Position (x,y) and size (w,h) within figure or container. Spacing
positive integer Number of pixels of extra space to leave between elements in the layout (default 5). Tag
string Tag to associate with layout. Type
string Type of graphics object. Units
inches | centimeters | normalized | points | pixels | characters Position units. Visible
on | off Visibility. Widths
double vector Width of each of the children. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. The size of this vector must always match the size of Contents.
+
+ For example:
+ f = figure
( 'Name'
, 'uix.HBoxFlex example'
);
+b = uix.HBoxFlex
( 'Parent'
, f );
+uicontrol
( 'Parent'
, b, 'Background'
, 'r'
)
+uicontrol
( 'Parent'
, b, 'Background'
, 'b'
)
+uicontrol
( 'Parent'
, b, 'Background'
, 'g'
)
+uicontrol
( 'Parent'
, b, 'Background'
, 'y'
)
+set
( b, 'Widths'
, [-1 100 -2 -1], 'Spacing'
, 5 );
+
+
+
+
+
+ See also: uix.HBox
- for creating a horizontal arrangementuix.VBoxFlex
- for creating a vertical arrangement with draggable dividers
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_4.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_4.html
new file mode 100644
index 00000000..99e656c6
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_4.html
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+ uix.VBoxFlex
+
+
+
+
+
+
+
+
+
+ 2.4: uix.VBoxFlex
+
+
+
+
+
+
+
+
+ Arrange elements vertically with draggable dividers
+
+ obj
= uix.VBoxFlex(
)
+ creates a new vertical box layout with draggable dividers and with all properties set to defaults.
+ The output is a new layout object that can be used as the parent for other user-interface components.
+
+ obj
= uix.VBoxFlex(
prop
,
value
,
...
)
+ also sets one or more property values from the list below.
+
+
+ uix.VBoxFlex properties
+ Property Value Description BackgroundColor
colorspec
Color to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b'). BeingDeleted
on | off Deletion status. Contents
empty GraphicsPlaceholder array | array of graphics objects Children within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself. DeleteFcn
function_handle
Function to call when the layout is being deleted. DividerMarkings
on | off Show markings on the draggable dividers (default 'on'). Heights
double vector Height of each of the children. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. The size of this vector must always match the size of Contents. MinimumHeights
double vector Minimum height in pixels of each of the children. The size of this vector must match the size of Contents. Padding
positive integer Number of pixels of extra space around the outside of the layout. Parent
empty GraphicsPlaceholder array | figure | container Parent of the layout. Position
[x y w h] Position (x,y) and size (w,h) within figure or container. Spacing
positive integer Number of pixels of extra space to leave between elements in the layout (default 5). Tag
string Tag to associate with layout. Type
string Type of graphics object. Units
inches | centimeters | normalized | points | pixels | characters Position units. Visible
on | off Visibility.
+
+
+ For example:
+ f = figure
( 'Name'
, 'uix.VBoxFlex example'
);
+b = uix.VBoxFlex
( 'Parent'
, f );
+uicontrol
( 'Parent'
, b, 'Background'
, 'r'
)
+uicontrol
( 'Parent'
, b, 'Background'
, 'b'
)
+uicontrol
( 'Parent'
, b, 'Background'
, 'g'
)
+uicontrol
( 'Parent'
, b, 'Background'
, 'y'
)
+set
( b, 'Heights'
, [-1 100 -2 -1], 'Spacing'
, 5 );
+
+
+
+
+
+ See also: uix.VBox
- for creating a vertical arrangementuix.HBoxFlex
- for creating a horizontal arrangement with draggable dividers
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_5.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_5.html
new file mode 100644
index 00000000..27c84dff
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_5.html
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+ uix.HButtonBox
+
+
+
+
+
+
+
+
+
+ 2.5: uix.HButtonBox
+
+
+
+
+
+
+
+ Arrange buttons horizontally in a single row
+
+ obj
= uix.HButtonBox(
)
+ is a type of HBox specialised for
+ arranging a row of buttons, check-boxes or similar graphical
+ elements. All buttons are given equal size and by default are
+ centered in the drawing area. The justification can be changed as
+ required.
+
+ obj
= uix.HButtonBox(
prop
,
value
,
...
)
+ also sets one or more property values.
+
+
+
+
+ uix.HButtonBox properties
+ Property Value Description BackgroundColor
colorspec
Color to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b'). BeingDeleted
on | off Deletion status. ButtonSize
[w h] The size for the buttons (all are given equal size). Contents
empty GraphicsPlaceholder array | array of graphics objects Children within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself. DeleteFcn
function_handle
Function to call when the layout is being deleted. HorizontalAlignment
left | center | right The horizontal position of the buttons. Padding
positive integer Number of pixels of extra space around the outside of the layout. Parent
empty GraphicsPlaceholder array | figure | container Parent of the layout. Position
[x y w h] Position (x,y) and size (w,h) within figure or container. Spacing
positive integer Number of pixels of extra space to leave between elements in the layout. Tag
string Tag to associate with layout. Type
string Type of graphics object. Units
inches | centimeters | normalized | points | pixels | characters Position units. VerticalAlignment
top | middle | bottom The vertical position of the buttons. Visible
on | off Visibility.
+
+ For example:
+ f = figure
();
+b = uix.HButtonBox
( 'Parent'
, f );
+uicontrol
( 'Parent'
, b, 'String'
, 'One' );
+uicontrol
( 'Parent'
, b, 'String'
, 'Two' );
+uicontrol
( 'Parent'
, b, 'String'
, 'Three' );
+set
( b, 'ButtonSize'
, [130 35], 'Spacing'
, 5 );
+
+
+
+
+
+ See also: uix.VButtonBox
- for creating a vertical arrangement of buttonsuix.HBox
- for creating a general horizontal arrangement
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_6.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_6.html
new file mode 100644
index 00000000..a9d9304c
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_6.html
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+ uix.VButtonBox
+
+
+
+
+
+
+
+
+
+ 2.6: uix.VButtonBox
+
+
+
+
+
+
+
+ Arrange buttons vertically in a single column
+
+ obj
= uix.VButtonBox(
)
+ is a type of VBox specialised for
+ arranging a column of buttons, check-boxes or similar graphical
+ elements. All buttons are given equal size and by default are
+ centered in the drawing area. The justification can be changed as
+ required.
+
+ obj
= uix.VButtonBox(
prop
,
value
,
...
)
+ also sets one or more property values.
+
+
+
+
+ uix.VButtonBox properties
+ Property Value Description BackgroundColor
colorspec
Color to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b'). BeingDeleted
on | off Deletion status. ButtonSize
[w h] The size for the buttons (all are given equal size). Contents
empty GraphicsPlaceholder array | array of graphics objects Children within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself. DeleteFcn
function_handle
Function to call when the layout is being deleted. HorizontalAlignment
left | center | right The horizontal position of the buttons. Padding
positive integer Number of pixels of extra space around the outside of the layout. Parent
empty GraphicsPlaceholder array | figure | container Parent of the layout. Position
[x y w h] Position (x,y) and size (w,h) within figure or container. Spacing
positive integer Number of pixels of extra space to leave between elements in the layout. Tag
string Tag to associate with layout. Type
string Type of graphics object. Units
inches | centimeters | normalized | points | pixels | characters Position units. VerticalAlignment
top | middle | bottom The vertical position of the buttons. Visible
on | off Visibility.
+
+ For example:
+ f = figure
();
+b = uix.VButtonBox
( 'Parent'
, f );
+uicontrol
( 'Parent'
, b, 'String'
, 'One' );
+uicontrol
( 'Parent'
, b, 'String'
, 'Two' );
+uicontrol
( 'Parent'
, b, 'String'
, 'Three' );
+set
( b, 'ButtonSize'
, [130 35], 'Spacing'
, 5 );
+
+
+
+
+
+ See also: uix.HButtonBox
- for creating a horizontal arrangement of buttonsuix.VBox
- for creating a general vertical arrangement
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference3_1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference3_1.html
new file mode 100644
index 00000000..24a71509
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference3_1.html
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+ uix.Grid
+
+
+
+
+
+
+
+
+
+ 3.1: uix.Grid
+
+
+
+
+ Arrange elements in a two dimensional grid
+
+ obj
= uix.Grid(
)
+ creates a new new grid layout with all properties set to defaults. The number of rows and
+ columns to use is determined from the number of elements in the
+ Heights and Widths properties respectively. Child elements are
+ arranged down column one first, then column two etc. If there are insufficient
+ columns then a new one is added.
+ The output is a new layout object that can be used as the parent for other user-interface components.
+
+ obj
= uix.Grid(
prop
,
value
,
...
)
+ also sets one or more property values.
+
+
+
+
+ uix.Grid properties
+ Property Value Description BackgroundColor
colorspec
Color to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b'). BeingDeleted
on | off Deletion status. Contents
empty GraphicsPlaceholder array | array of graphics objects Children within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself. DeleteFcn
function_handle
Function to call when the layout is being deleted. Heights
double vector Height of each of the rows. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. Padding
positive integer Number of pixels of extra space around the outside of the layout. Parent
empty GraphicsPlaceholder array | figure | container Parent of the layout. Position
[x y w h] Position (x,y) and size (w,h) within figure or container. Spacing
positive integer Number of pixels of extra space to leave between elements in the layout. Tag
string Tag to associate with layout. Type
string Type of graphics object. Units
inches | centimeters | normalized | points | pixels | characters Position units. Visible
on | off Visibility. Widths
double vector Width of each of the columns. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing.
+
+ For example:
+ f = figure
();
+g = uix.Grid
( 'Parent'
, f, 'Spacing'
, 5 );
+uicontrol
( 'Parent'
, g, 'Background'
, 'r'
)
+uicontrol
( 'Parent'
, g, 'Background'
, 'b'
)
+uicontrol
( 'Parent'
, g, 'Background'
, 'g'
)
+uix.Empty
( 'Parent'
, g )
+uicontrol
( 'Parent'
, g, 'Background'
, 'c'
)
+uicontrol
( 'Parent'
, g, 'Background'
, 'y'
)
+set
( g, 'Widths'
, [-1 100 -2], 'Heights'
, [-1 100] );
+
+
+
+
+
+ See also: uix.GridFlex
- for creating a grid arrangement with draggable dividers
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference3_2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference3_2.html
new file mode 100644
index 00000000..2d709f41
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference3_2.html
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+ uix.GridFlex
+
+
+
+
+
+
+
+
+
+ 3.2: uix.GridFlex
+
+
+
+
+
+ Arrange elements in a two dimensional grid with draggable dividers
+
+ obj
= uix.GridFlex(
)
+ creates a new new grid layout with draggable dividers between elements. The number of rows and
+ columns to use is determined from the number of elements in the
+ Heights and Widths properties respectively. Child elements are
+ arranged down column one first, then column two etc. If there are insufficient
+ columns then a new one is added.
+ The output is a new layout object that can be used as the parent for other user-interface components.
+
+ obj
= uix.GridFlex(
prop
,
value
,
...
)
+ also sets one or more property values.
+
+
+
+
+ uix.GridFlex properties
+ Property Value Description BackgroundColor
colorspec
Color to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b'). BeingDeleted
on | off Deletion status. Contents
empty GraphicsPlaceholder array | array of graphics objects Children within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself. DeleteFcn
function_handle
Function to call when the layout is being deleted. DividerMarkings
on | off Show markings on the draggable dividers (default 'on'). Heights
double vector Height of each of the rows. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. Padding
positive integer Number of pixels of extra space around the outside of the layout. Parent
empty GraphicsPlaceholder array | figure | container Parent of the layout. Position
[x y w h] Position (x,y) and size (w,h) within figure or container. Spacing
positive integer Number of pixels of extra space to leave between elements in the layout (default 5). Tag
string Tag to associate with layout. Type
string Type of graphics object. Units
inches | centimeters | normalized | points | pixels | characters Position units. Visible
on | off Visibility. Widths
double vector Width of each of the columns. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing.
+
+ For example:
+ f = figure
();
+g = uix.GridFlex
( 'Parent'
, f, 'Spacing'
, 5 );
+uicontrol
( 'Parent'
, g, 'Background'
, 'r'
)
+uicontrol
( 'Parent'
, g, 'Background'
, 'b'
)
+uicontrol
( 'Parent'
, g, 'Background'
, 'g'
)
+uix.Empty
( 'Parent'
, g )
+uicontrol
( 'Parent'
, g, 'Background'
, 'c'
)
+uicontrol
( 'Parent'
, g, 'Background'
, 'y'
)
+set
( g, 'Widths'
, [-1 100 -2], 'Heights'
, [-1 -2] );
+
+
+
+
+
+ See also: uix.Grid
- for creating a grid arrangement
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference4_1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference4_1.html
new file mode 100644
index 00000000..0afb71ab
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference4_1.html
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+ uix.Empty
+
+
+
+
+
+
+
+
+
+ 4.1: uix.Empty
+
+
+ Create an empty space
+
+ obj
= uix.Empty(
)
+ creates an empty space object that can be
+ used in layouts to add gaps between other elements.
+
+ obj
= uix.Empty(
param
,
value
,
...
)
+ also sets one or more property values.
+
+
+
+ uix.Empty properties
+ The empty space is achieved using a container that monitors
+ its parent's color and changes its own to match.
+ Property Value Description BeingDeleted
on | off Deletion status. HandleVisibility
on | off Visibility of the object. Parent
empty GraphicsPlaceholder array | figure | container Parent of the object. Position
[x y w h] Position (x,y) and size (w,h) within figure or container. Tag
string Tag to associate with object. Type
string Type of graphics object. Units
inches | centimeters | normalized | points | pixels | characters Position units. Visible
on | off Visibility.
+
+ For example:
+ f = figure
();
+box = uix.HBox
( 'Parent'
, f, 'Spacing'
, 5 );
+uicontrol
( 'Parent'
, box, 'Background'
, 'r'
)
+uix.Empty
( 'Parent'
, box )
+uicontrol
( 'Parent'
, box, 'Background'
, 'g'
)
+
+
+ See also: uix.HBox
- for arranging widgets horizontally
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference4_2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference4_2.html
new file mode 100644
index 00000000..9bbc620f
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference4_2.html
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+ uix.tracking
+
+
+
+
+
+
+
+
+
+ 4.2: uix.tracking
+
+
+ tracks anonymized usage data
+
+ uix.tracking(
p
,
v
,
id
)
+ tracks usage to the property p for the version v and identifier id using Google Analytics.
+ uix.tracking(
state
)
+ turns tracking on or off.
+ state
= uix.tracking(
'query'
)
+ queries whether tracking is on or off.
+
+
+
+ For example:
+ uix.tracking
('UA-45678-9'
,'1.2.3'
,'featurename'
)
+
+ uix.tracking
('on'
)
+
+ state = uix.tracking
('query'
)
+ state = 'on'
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference4_3.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference4_3.html
new file mode 100644
index 00000000..9955a1d3
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference4_3.html
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+ layoutRoot
+
+
+
+
+
+
+
+
+
+ 4.3: layoutRoot
+
+
+
+
+ returns the folder containing the GUI layout toolbox
+
+ folder
= layoutRoot(
)
+ returns the full path to the folder containing the GUI Layout Toolbox.
+
+
+
+ For example:
+ folder = layoutRoot
()
+ folder = 'C:\tools\glt2'
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+>
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/GUI Layout.html b/studio_functions/GUI Layout Toolbox/layoutdoc/GUI Layout.html
new file mode 100644
index 00000000..c0141bd5
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/GUI Layout.html
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started.html
new file mode 100644
index 00000000..2ed741a6
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started.html
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ Getting Started
+
+
+
+
+
+
+
+
+ Getting Started
+
+ This chapter gives an overview of this package, including its purpose,
+how to install it and any known issues at the time of release.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started1.html
new file mode 100644
index 00000000..6c6f9c78
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started1.html
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+ What is GUI Layout Toolbox?
+
+
+
+
+
+
+
+ 1: What is GUI Layout Toolbox?
+
+
+ GUI Layout Toolbox provides a package of MATLAB objects that allow for complex
+ arrangement of graphical user interface elements within a figure window. The
+ main capabilities provided are:
+
+ Automatic element arrangement horizontally, vertically or in grids
+ Ability to specify fixed sizes or resizing weights for each element
+ Ability to "nest" layouts to produce virtually any element arrangement
+ Divider bars for user-resizing of elements
+
+ These element arrangement capabilities are designed to match those found as
+ standard in other user-interface toolkits such as Java Swing, GTK, QT etc.
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started2.html
new file mode 100644
index 00000000..e93586d3
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started2.html
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+ Compatibility considerations
+
+
+
+
+
+
+
+ 2: Compatibility considerations
+
+
+
+
+
+
+
+ Section contents:
+
+
+
+
+
+
+
+
+ 2.1: Minimum MATLAB version
+
+ This is version 2 of GUI Layout Toolbox, designed to work with the new
+ MATLAB graphics system that was introduced in R2014b.
+ Version 1 works with MATLAB releases prior to R2014b that use the old
+ graphics system.
+
+
+ 2.2: Compatibility with version 1
+
+ If you are upgrading from version 1, there are a number of compatibility
+ considerations:
+
+Package name
+Version 1 classes were contained in the package "uiextras". Version 2 classes are
+contained in the package "uix". In version 2, a package "uiextras" is included
+to provide support for legacy code. Classes in "uiextras" extend
+corresponding classes in "uix", and contain only compatibility-related
+code.
+
+Contents property
+The contents of version 1 objects were accessible via the property Children
.
+The contents of version 2 objects are accessible via the property Contents
.
+Version 2 objects also provide a property Children
, but this controls the
+vertical stacking order rather than the layout order. Legacy code that accesses
+Children
will run without error, but will not achieve the desired change in
+layout order, and should be modified to access Contents
instead.
+
+An upcoming release of version 1 will include support for code that references
+contents via Contents
. That way, code modified to work in version 2 will also
+work in version 1.
+
+The background to this change is as follows. Version 1 objects were wrappers
+for built-in graphics objects, and presented contents in layout order via
+the property Children
. Version 2 objects extend built-in graphics objects,
+and as such, inherit properties, methods and events. One such property is
+Children
which is used to control the top-to-bottom stacking order.
+MATLAB stacking rules, e.g. controls are always on top of axes, mean that
+some reasonable layout orders may be invalid stacking orders, so a new
+property for layout order is required.
+
+Auto-parenting
+The new MATLAB graphics system introduces unparented objects, i.e. those with property Parent
+empty. The new system also introduces a separation between formal class constructors, e.g.
+matlab.ui.container.Panel
, and informal construction functions, e.g. uipanel
.
+Construction functions are auto-parenting, i.e. if Parent
is not specified then it is set to
+gcf
, whereas class constructors return objects with Parent
empty unless
+explicitly specified. Version 2 presents a formal interface of class constructors which follow this new
+convention.
+
+Classes in "uiextras" are auto-parenting so the behavior of legacy code is
+unchanged. However, best practice is to specify parent explicitly during
+construction.
+
+Defaults mechanism
+Version 1 provided a defaults mechanism (uiextras.get
, uiextras.set
+and uiextras.unset
) that mimicked get
and set
in the MATLAB
+graphics system itself. This feature has been removed from version 2. Users should use an
+alternative programming pattern, e.g. factory function, to create objects with standard settings.
+
+Enable and disable
+Version 1 provided a mechanism to enable and disable container contents using the property
+Enable
. This feature has been removed from version 2. Users should enable and disable
+controls directly rather than via containers.
+For more commentary, see this article .
+
+Other property name changes
+A number of property names have changed to achieve greater consistency
+across the package. For example, RowSizes
and ColumnSizes
in
+uiextras.Grid are now Heights
and Widths
in uix.Grid. The package
+"uiextras" provides support for legacy property names.
+
+ RowSizes
in "uiextras" is Heights
in "uix"
+ ColumnSizes
in "uiextras" is Widths
in "uix"
+ ShowMarkings
in "uiextras" is DividerMarkings
in "uix"
+
+
+Property shape changes
+Version 2 contents companion properties are now of the same size as Contents
,
+i.e. column vectors. In version 1, these properties were row vectors. The
+package "uiextras" provides support for legacy property values.
+
+ Tab selection behavior
+ In version 1, after adding a tab to a tab panel, the new tab is selected.
+ In version 2, the original selection is preserved, except if the tab panel was
+ empty, in which case the new tab is selected. This is consistent with the
+ behavior of uitabgroup
.
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started3.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started3.html
new file mode 100644
index 00000000..4964873c
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started3.html
@@ -0,0 +1,226 @@
+
+
+
+
+
+
+ Release notes
+
+
+
+
+
+
+
+ 3: Release notes
+
+
+ The GUI Layout Toolbox version numbers take the form major.minor.iter
. The
+ current version you have installed can be checked by typing ver
+ at the MATLAB command prompt.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Section contents:
+
+
+
+
+
+
+
+
+ 3.1: Version 2.3.5
+
+
+ Released 31 October 2020
+ Updated for compatibility with R2020b uipanels
+ Fixed G1959226 "Scrolling panel scrollbars and blanking plate do not match
+ background color"
+ Fixed G1959228 "Scrolling panel sliders remain after child is deleted"
+
+
+
+ 3.2: Version 2.3.4
+
+
+ Released 31 January 2019
+ Fixed G1910801 "Scrolling panel does not work in figure with Units other than 'pixels'"
+ Fixed G1911845 "Unexpected reordering of contents as axes toolbar causes axes to be removed and readded"
+
+
+
+ 3.3: Version 2.3.3
+
+
+ Released 25 October 2018
+ Updated for compatibility with R2018b axes toolbars
+ Fixed G1804440 "Flex containers position axes incorrectly when ActivePositionProperty is outerposition"
+
+
+
+ 3.4: Version 2.3.2
+
+
+ Released 1 May 2018
+ Set tooltip strings for BoxPanel dock/undock, minimize/maximize, help and close buttons
+ Set default padding for flex containers to 5 so that dividers are visible
+ Scroll uix.ScrollingPanel using mouse wheel for variable-sized contents
+ Fixed G1358897 "BoxPanel title is truncated on Mac high DPI display"
+ Fixed G1695618 "Warning on mouse motion while deleting HBoxFlex, VBoxFlex or GridFlex"
+
+
+
+ 3.5: Version 2.3.1
+
+
+ Released 31 January 2017
+ Specify minimum width and height of contents in uix.ScrollingPanel
+ Update contents position while dragging uix.ScrollingPanel scrollbox
+ Scroll uix.ScrollingPanel using mouse wheel
+ Updated toolbox logo
+
+
+
+ 3.6: Version 2.3
+
+
+ Released 24 November 2016
+ Added scrolling panel
+ Expand and collapse box panel by clicking on title
+ Fixed G1493103 "Error on construction behavior is inconstistent with builtin objects"
+
+
+
+ 3.7: Version 2.2.2
+
+
+ Released 22 August 2016
+ Fixed G1175938 "Cannot use data cursor mode with GUI Layout Toolbox containers"
+ Fixed G1367337 "Update flex container pointer on mouse press event"
+ Fixed G1380756 "Space behind TabPanel tabs should match parent color"
+ Added anonymous tracking of version, operating system and usage to help
+ us prioritize the improvements we should work on
+
+
+
+ 3.8: Version 2.2.1
+
+
+ Released 26 February 2016
+ Fixed G1346921 "Mouse pointer gets confused when moving between adjacent flex containers"
+ Fixed G1357340 "BoxPanel property ForegroundColor is initialized incorrectly"
+
+
+
+ 3.9: Version 2.2
+
+
+ Released 18 December 2015
+ Improved box panel title bar appearance
+ Changed selection behavior of uix.TabGroup to match that of uitabgroup when the selected tab is removed
+ Fixed G1253937 "uix.TabPanel/redrawTabs fails" (R2015b)
+ Fixed G1292238 "uix.BoxPanel/redrawBorders fails" (R2015b)
+ Fixed G1330841 "mouse-over-divider detection does not work for docked figures" (all)
+ Fixed G1332109 "uix.Empty background color does not match that of its Parent" (all)
+ Fixed G1334867 "cannot add axes to container" (R2016a prerelease)
+ Removed internal helper classes uix.AncestryObserver, uix.LocationObserver, uix.VisibilityObserver
+
+
+
+ 3.10: Version 2.1.2
+
+
+ Released 29 May 2015
+ Fixed G1250248 "uix.Empty becomes visible in a panel"
+ Fixed G1250249 "missing property Selection of uix.BoxPanel"
+ Fixed G1250808 "uix.TabPanel context menus are orphaned when reparenting to a different figure"
+
+
+
+ 3.11: Version 2.1.1
+
+
+ Released 15 May 2015
+ Added context menus on uix.TabPanel tab labels (G1245669)
+ Fixed G1164656 "cannot set relative tab widths"
+ Fixed G1019441 "property RowSizes of uiextras.GridFlex sets heights not widths"
+ Fixed G1165274 "missing properties RowSizes, MinimumRowSizes, ColumnSizes,
+ MinimumColumnSizes of uiextras.Grid, uiextras.GridFlex"
+ Fixed G1218142 "contents are lost when reordering via property Children"
+ Protected against G1136196 "segv when setting child visibility from 'off' to 'on' in response to being reparented"
+
+
+
+ 3.12: Version 2.1
+
+
+ Released 2 October 2014
+ Initial version for MATLAB R2014b
+ Versions 2.0.x were for prerelease testing
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started4.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started4.html
new file mode 100644
index 00000000..7c103b9d
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started4.html
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+ Installation
+
+
+
+
+
+
+
+ 4: Installation
+
+
+
+ GUI Layout Toolbox is provided as a MATLAB toolbox file (.mltbx
).
+
+
+ For instructions on installing and uninstalling, see the section on
+ managing toolboxes
+ in the MATLAB documentation.
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started5.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started5.html
new file mode 100644
index 00000000..a0cc61cb
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started5.html
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+ Support
+
+
+
+
+
+
+
+ 5: Support
+
+
+
+ This toolbox is not a MathWorks supported product. However, if you
+ have problems, suggestions or other comments, please contact the
+ authors:
+
+
+ If you like this toolbox, help others to find it by leaving a rating
+ and comment on the MATLAB Central File Exchange .
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started6.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started6.html
new file mode 100644
index 00000000..c9ca3e27
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started6.html
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+ Acknowledgements
+
+
+
+
+
+
+
+ 6: Acknowledgements
+
+ The authors wish to acknowledge the earlier contributions of the following MathWorks
+ consultants to this area:
+
+ Brad Phelan
+ Malcolm Wood
+ Richard Lang
+ Paul Kerr-Delworth
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+>
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/HierarchyExample.html b/studio_functions/GUI Layout Toolbox/layoutdoc/HierarchyExample.html
new file mode 100644
index 00000000..d9859f5f
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/HierarchyExample.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Border.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Border.png
new file mode 100644
index 00000000..0e58e8ac
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Border.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxInBox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxInBox.png
new file mode 100644
index 00000000..799d725c
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxInBox.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanel.png
new file mode 100644
index 00000000..94aef688
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanel.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanel2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanel2.png
new file mode 100644
index 00000000..af9ca016
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanel2.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample1.png
new file mode 100644
index 00000000..dc94dfa4
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample1.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample2.png
new file mode 100644
index 00000000..be25fcdb
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample2.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample3.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample3.png
new file mode 100644
index 00000000..577ac4e7
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample3.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample4.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample4.png
new file mode 100644
index 00000000..15a7b66f
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample4.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelHelpExample.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelHelpExample.png
new file mode 100644
index 00000000..1a295b83
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelHelpExample.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelMinimizeExample1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelMinimizeExample1.png
new file mode 100644
index 00000000..d9df27b4
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelMinimizeExample1.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelMinimizeExample2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelMinimizeExample2.png
new file mode 100644
index 00000000..28f290d4
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelMinimizeExample2.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelMinimizeExample3.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelMinimizeExample3.png
new file mode 100644
index 00000000..93b3072f
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelMinimizeExample3.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/CardPanel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/CardPanel.png
new file mode 100644
index 00000000..db0ab356
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/CardPanel.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/CombineBoxes.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/CombineBoxes.png
new file mode 100644
index 00000000..87db36e4
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/CombineBoxes.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/DefaultsFigure.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/DefaultsFigure.png
new file mode 100644
index 00000000..e0446a13
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/DefaultsFigure.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/DefaultsSystem1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/DefaultsSystem1.png
new file mode 100644
index 00000000..2c228e4e
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/DefaultsSystem1.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/DefaultsSystem2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/DefaultsSystem2.png
new file mode 100644
index 00000000..1065eac5
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/DefaultsSystem2.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Empty.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Empty.png
new file mode 100644
index 00000000..4f470418
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Empty.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/EnableExample1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/EnableExample1.png
new file mode 100644
index 00000000..0f46c6f2
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/EnableExample1.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/EnableExample2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/EnableExample2.png
new file mode 100644
index 00000000..3d8be827
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/EnableExample2.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/EnableExample3.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/EnableExample3.png
new file mode 100644
index 00000000..b3f62e72
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/EnableExample3.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Grid.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Grid.png
new file mode 100644
index 00000000..47ab7812
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Grid.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/GridFlex.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/GridFlex.png
new file mode 100644
index 00000000..76b64c51
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/GridFlex.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/HBox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/HBox.png
new file mode 100644
index 00000000..2c537518
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/HBox.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/HBoxFlex.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/HBoxFlex.png
new file mode 100644
index 00000000..91a2a3ae
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/HBoxFlex.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/HButtonBox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/HButtonBox.png
new file mode 100644
index 00000000..c7954468
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/HButtonBox.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Panel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Panel.png
new file mode 100644
index 00000000..a371495f
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Panel.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Panel2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Panel2.png
new file mode 100644
index 00000000..863de735
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Panel2.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/ScrollingPanel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/ScrollingPanel.png
new file mode 100644
index 00000000..9d806848
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/ScrollingPanel.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/TabPanel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/TabPanel.png
new file mode 100644
index 00000000..2af8973e
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/TabPanel.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VBox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VBox.png
new file mode 100644
index 00000000..fd703c91
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VBox.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VBoxFlex.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VBoxFlex.png
new file mode 100644
index 00000000..d02fc828
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VBoxFlex.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VButtonBox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VButtonBox.png
new file mode 100644
index 00000000..889d828c
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VButtonBox.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VisibleExample1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VisibleExample1.png
new file mode 100644
index 00000000..a15a62ca
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VisibleExample1.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VisibleExample2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VisibleExample2.png
new file mode 100644
index 00000000..c314bc82
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VisibleExample2.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VisibleExample3.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VisibleExample3.png
new file mode 100644
index 00000000..65e6085f
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VisibleExample3.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_inner.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_inner.png
new file mode 100644
index 00000000..5a9fad17
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_inner.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_layout_example_2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_layout_example_2.png
new file mode 100644
index 00000000..3f9f29f1
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_layout_example_2.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_layout_example_3.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_layout_example_3.png
new file mode 100644
index 00000000..a89912e9
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_layout_example_3.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_outer.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_outer.png
new file mode 100644
index 00000000..39858c43
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_outer.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example2.png
new file mode 100644
index 00000000..1605cb61
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example2.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example3.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example3.png
new file mode 100644
index 00000000..bccb0294
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example3.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example4.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example4.png
new file mode 100644
index 00000000..b5cec6b7
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example4.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example5.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example5.png
new file mode 100644
index 00000000..00dbadd5
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example5.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example6.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example6.png
new file mode 100644
index 00000000..9d1f70b3
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example6.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example_tab.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example_tab.png
new file mode 100644
index 00000000..98783ed8
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example_tab.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example_vbox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example_vbox.png
new file mode 100644
index 00000000..488072fa
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example_vbox.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_BorderLayout.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_BorderLayout.png
new file mode 100644
index 00000000..665011d3
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_BorderLayout.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_BoxPanel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_BoxPanel.png
new file mode 100644
index 00000000..dc9bb2a0
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_BoxPanel.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_CardPanel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_CardPanel.png
new file mode 100644
index 00000000..1d0166a9
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_CardPanel.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_Grid.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_Grid.png
new file mode 100644
index 00000000..afec6e5b
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_Grid.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_GridFlex.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_GridFlex.png
new file mode 100644
index 00000000..69e854f9
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_GridFlex.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_HBox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_HBox.png
new file mode 100644
index 00000000..916a4979
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_HBox.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_HBoxFlex.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_HBoxFlex.png
new file mode 100644
index 00000000..c161f950
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_HBoxFlex.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_HButtonBox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_HButtonBox.png
new file mode 100644
index 00000000..3a327a3f
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_HButtonBox.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_Panel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_Panel.png
new file mode 100644
index 00000000..ccfcff59
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_Panel.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_ScrollingPanel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_ScrollingPanel.png
new file mode 100644
index 00000000..7f1ff089
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_ScrollingPanel.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_TabPanel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_TabPanel.png
new file mode 100644
index 00000000..412b0de3
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_TabPanel.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_VBox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_VBox.png
new file mode 100644
index 00000000..14b5e5b1
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_VBox.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_VBoxFlex.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_VBoxFlex.png
new file mode 100644
index 00000000..867daf87
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_VBoxFlex.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_VButtonBox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_VButtonBox.png
new file mode 100644
index 00000000..53bbaaf9
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_VButtonBox.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bookicon.gif b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bookicon.gif
new file mode 100644
index 00000000..7f86c41b
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bookicon.gif differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/colorbar_example_2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/colorbar_example_2.png
new file mode 100644
index 00000000..928c5a8f
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/colorbar_example_2.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/colorbar_example_3.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/colorbar_example_3.png
new file mode 100644
index 00000000..cd48e213
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/colorbar_example_3.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser1.png
new file mode 100644
index 00000000..6186138a
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser1.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser2.png
new file mode 100644
index 00000000..88b579ad
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser2.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser3.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser3.png
new file mode 100644
index 00000000..096d9ef5
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser3.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser4.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser4.png
new file mode 100644
index 00000000..5129b573
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser4.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoicon.gif b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoicon.gif
new file mode 100644
index 00000000..c89e7acb
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoicon.gif differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/deploy.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/deploy.png
new file mode 100644
index 00000000..eae1f872
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/deploy.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/greenarrowicon.gif b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/greenarrowicon.gif
new file mode 100644
index 00000000..5c5d0e40
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/greenarrowicon.gif differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/guide1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/guide1.png
new file mode 100644
index 00000000..ce9b11e1
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/guide1.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/guide2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/guide2.png
new file mode 100644
index 00000000..4e328f4a
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/guide2.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_ex.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_ex.png
new file mode 100644
index 00000000..50c5df29
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_ex.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_fx.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_fx.png
new file mode 100644
index 00000000..5ac8b7b8
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_fx.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_gs.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_gs.png
new file mode 100644
index 00000000..2ab38963
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_gs.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_rn.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_rn.png
new file mode 100644
index 00000000..142c6c0b
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_rn.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_ug.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_ug.png
new file mode 100644
index 00000000..68381b54
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_ug.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/leftarrow.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/leftarrow.png
new file mode 100644
index 00000000..b8ffd424
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/leftarrow.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/pageicon.gif b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/pageicon.gif
new file mode 100644
index 00000000..3d35fdb0
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/pageicon.gif differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/pagesicon.gif b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/pagesicon.gif
new file mode 100644
index 00000000..9278b1f1
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/pagesicon.gif differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/reficon.gif b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/reficon.gif
new file mode 100644
index 00000000..44b05482
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/reficon.gif differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/rightarrow.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/rightarrow.png
new file mode 100644
index 00000000..4bdf3ec9
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/rightarrow.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/titleimage.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/titleimage.png
new file mode 100644
index 00000000..b9cd50bf
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/titleimage.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/uparrow.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/uparrow.png
new file mode 100644
index 00000000..4590b67b
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/uparrow.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_fixed1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_fixed1.png
new file mode 100644
index 00000000..003f4428
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_fixed1.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_fixed2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_fixed2.png
new file mode 100644
index 00000000..2d83f5ca
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_fixed2.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout0_1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout0_1.png
new file mode 100644
index 00000000..7ba448a8
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout0_1.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout0_2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout0_2.png
new file mode 100644
index 00000000..185fad3a
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout0_2.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout1.png
new file mode 100644
index 00000000..185fad3a
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout1.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout2.png
new file mode 100644
index 00000000..c8780a82
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout2.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout_anno1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout_anno1.png
new file mode 100644
index 00000000..30119a80
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout_anno1.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout_anno2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout_anno2.png
new file mode 100644
index 00000000..dda90125
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout_anno2.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_normalized1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_normalized1.png
new file mode 100644
index 00000000..94ce5e42
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_normalized1.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_normalized2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_normalized2.png
new file mode 100644
index 00000000..fa4e8c59
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_normalized2.png differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/LayoutsGUIDE.html b/studio_functions/GUI Layout Toolbox/layoutdoc/LayoutsGUIDE.html
new file mode 100644
index 00000000..7feb0d60
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/LayoutsGUIDE.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/PanelDock.html b/studio_functions/GUI Layout Toolbox/layoutdoc/PanelDock.html
new file mode 100644
index 00000000..f04afe41
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/PanelDock.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/PanelHelp.html b/studio_functions/GUI Layout Toolbox/layoutdoc/PanelHelp.html
new file mode 100644
index 00000000..12a7c42f
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/PanelHelp.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/PanelMinimize.html b/studio_functions/GUI Layout Toolbox/layoutdoc/PanelMinimize.html
new file mode 100644
index 00000000..d5d586de
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/PanelMinimize.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide.html
new file mode 100644
index 00000000..2d81313a
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide.html
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+ User guide
+
+
+
+
+
+
+
+
+ User guide
+
+ This chapter describes the purpose and overall design of the layout
+ tools that the toolbox provides. It also provides some examples of
+ creating some user interfaces using layouts.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1.html
new file mode 100644
index 00000000..57ac73c7
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Understanding layouts
+
+
+
+
+
+
+
+ 1: Understanding layouts
+
+ The purpose of a "layout" is to manage the positioning of one
+ or more user-interface components. This means that instead of
+ worrying about the exact position of each user interface component
+ you instead worry about the relative positioning of them; are they
+ arranged in a vertical list, horizontal list, a grid pattern, etc.
+ The best way to understand what layouts are and why they are a good user-interface
+ design tool is to see some examples. The sections below go through the
+ basics of building an interface using layouts and how to build complex
+ interfaces using them.
+
+
+
+
+
+
+
+
+
+
+
+ Section contents:
+
+
+
+
+
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_1.html
new file mode 100644
index 00000000..f12c0c16
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_1.html
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+ Layout basics
+
+
+
+
+
+
+
+
+
+ 1.1: Layout basics
+
+ To see how layouts work, let's use the most basic layout,
+ a horizontal list (or box). We first create a window:
+
+ f = figure
();
+
+
+ Now let's create the horizontal layout and add it to the figure. Note
+ that in common with other MATLAB graphics objects, one object is added to
+ another by setting the Parent
property - this will automatically
+ adjust the list of Children
in the parent object. The job of a
+ horizontal box layout is to arrange its contents in a horizontal line,
+ setting the position of each element to best fill the space:
+
+ layout = uix.HBox
( 'Parent', f );
+
+ Nothing's changed! That's because the layout is for arranging
+ other user-interface components - it doesn't draw anything itself. Let's
+ add some buttons. Note how after creating each button the existing contents
+ of the box make room for the new addition; we don't need to set the position of
+ any user-interface component!
+
+ uicontrol
( 'String', 'Button 1', 'Parent', layout );
+uicontrol
( 'String', 'Button 2', 'Parent', layout );
+uicontrol
( 'String', 'Button 3', 'Parent', layout );
+
. .
+
+ Other layouts work in exactly the same way, although visually
+ the end-result is quite different:
+
+ f = figure
();
+layout = uix.VBox
( 'Parent', f );
+uicontrol
( 'String', 'Button 1', 'Parent', layout );
+uicontrol
( 'String', 'Button 2', 'Parent', layout );
+uicontrol
( 'String', 'Button 3', 'Parent', layout );
+
+
+
+ f = figure
();
+layout = uix.TabPanel
( 'Parent', f );
+uicontrol
( 'String', 'Button 1', 'Parent', layout );
+uicontrol
( 'String', 'Button 2', 'Parent', layout );
+uicontrol
( 'String', 'Button 3', 'Parent', layout );
+
+
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_2.html
new file mode 100644
index 00000000..16bed6ef
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_2.html
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+ Types of layout
+
+
+
+
+
+
+
+
+
+ 1.2: Types of layout
+
+ The layouts in this toolbox come in three forms:
+
+ Panels : show a single child element with some decoration. Other children
+ of the layout are hidden from view. The visible child can be switched. Available
+ panels include
+ Panel ,
+ CardPanel ,
+ BoxPanel ,
+ TabPanel and
+ ScrollingPanel .
+
+ Boxes : arrange children linearly in a single row or column. Available boxes include
+ HBox ,
+ VBox ,
+ HBoxFlex and
+ VBoxFlex .
+
+ Grids : (also known as tables) arrange children in a two-dimensional grid. Available grids include
+ Grid and
+ GridFlex .
+
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_3.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_3.html
new file mode 100644
index 00000000..4cd20b6e
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_3.html
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+ Sizes and units
+
+
+
+
+
+
+
+
+
+ 1.3: Sizes and units
+
+ In the previous section we noted that when using layouts
+ you never need to set the position or size of a user-interface
+ component yourself - the layouts take care of it. So how do
+ you control the sizes of the components?
+ Each layout that arranges multiple items within its drawing area
+ has a sizing property: for horizontal boxes this is Widths
+ and for vertical boxes Heights
; for grids we have both Widths
+ and Heights
. These all obey the same convention:
+
+ Positive numbers indicate sizes in pixels (similar to "pixel" units)
+ Negative numbers indicate a weighting for variable sizing (similar to "normalized" units)
+
+ By default all sizes are set to -1 (variable size with unit weighting).
+ Let's take a simple example:
+
+ f = figure
();
+layout = uix.HBox
( 'Parent', f );
+uicontrol
( 'String', 'Button 1', 'Parent', layout );
+uicontrol
( 'String', 'Button 2', 'Parent', layout );
+uicontrol
( 'String', 'Button 3', 'Parent', layout );
+
+
+ We can set the middle element to be twice as wide as the others
+ (but still variable width) by setting its weight to -2 with the others at -1:
+
+ layout.Widths = [-1 -2 -1]
+
+
+ Alternatively we might want the first element to have a
+ fixed width of 100 pixels with the others filling any remaining
+ space equally:
+
+ layout.Widths = [100 -1 -1]
+
+
+
+ This ability to mix fixed and variable sized elements is
+ crucial in interface design. It really comes into its own when building
+ a hierarchy of layouts, described next.
+
+
+
+
+ 1.3.1:
+ Minimum sizes
+ Many of the multi-element layouts also provide a MinimumWidths
+ or MinimumHeights
+ property to prevent an element becoming too small. This is measured in
+ pixels and defaults to one pixel. Take care to ensure that the available
+ space is at least the sum of the minimum sizes, plus any padding and
+ spacing.
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_4.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_4.html
new file mode 100644
index 00000000..9186be9e
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_4.html
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+ Layout hierarchies
+
+
+
+
+
+
+
+
+
+ 1.4: Layout hierarchies
+
+ Consider the following simple interface:
+
+ Instead of thinking of this in terms of three elements that need
+ positioning, we can break it up into two simple linear ("box") arrangements:
+ a vertical box with the axes at the top and a control area at the bottom and
+ a horizontal box containing two buttons:
+ .
+ By placing the second layout (horizontal box) inside the first (vertical box)
+ we arrive at the complete layout. Since the sizes of the elements in each list
+ can be set to be fixed or flexible we can achieve a user-interface that is not just
+ arranged correctly when created, but also behaves well when resized.
+
+ Note that the buttons have stayed fixed height as the window grows and the
+ axes grow to fill the remaining space.
+
+
+
+ 1.4.1:
+ Code:
+ The example above can be created programmically pretty
+ much as described in text
+ (the completed example code is here:
+ [ view
+ | edit
+ | run ]
+ )
+ 1. Open a window
+ f = figure
( 'Position', 200*ones(1,4) );
+ 2. Create the first layout (vertical box) Inside this vertical box
+ we place the axes
+ vbox = uix.VBox
( 'Parent', f );
+axes( 'Parent', vbox );
+
+
+ 3. Create the second layout (horizontal box) Inside this horizontal box
+ we place two buttons
+hbox = uix.HButtonBox
( 'Parent', vbox, 'Padding', 5 );
+uicontrol
( 'Parent', hbox, ...
+ 'String', 'Button 1' );
+uicontrol
( 'Parent', hbox, ...
+ 'String', 'Button 2' );
+
+
+ 4. Set the sizes We want the axes to grow with the window so
+ set the first size to be -1 (which means variable size with wieght 1) and the buttons to stay fixed height so set the
+second size to 35 (fixed height of 35 pixels)
+set( vbox, 'Heights', [-1 35] )
+
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_5.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_5.html
new file mode 100644
index 00000000..64340bcc
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_5.html
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+ Why use layouts?
+
+
+
+
+
+
+
+
+
+ 1.5: Why use layouts?
+
+ MATLAB ships with a GUI design tool called GUIDE
. This
+ doesn't use layouts, but forces users to manually position each element. This approach
+ is a much faster way to build simple user-interfaces, so why would you want to
+use layouts?
+ The over-riding reason for using layouts or layout managers is
+ to gain control of the resizing behaviour of the interface without
+ having to write a complex "ResizeFcn". If you simply position user-interface elements
+ directly (either using GUIDE
or programmatically), you
+ have two choices about what happens when the window resizes:
+
+ For example:
+ 1. The user-interface components scale with the window (normalised units) We didn't really want the buttons to grow but everything resizes in proportion.
+ f = figure
( 'Position', 200*ones(1,4) );
+axes
( 'Parent', f, ...
+ 'Units', 'Normalized', ...
+ 'OuterPosition', [0.02 0.2 0.96 0.8] );
+uicontrol
( 'Parent', f, ...
+ 'Units', 'Normalized', ...
+ 'Position', [0.02 0.02 0.46 0.16], ...
+ 'String', 'Button 1' );
+uicontrol
( 'Parent', f, ...
+ 'Units', 'Normalized', ...
+ 'Position', [0.52 0.02 0.46 0.16], ...
+ 'String', 'Button 2' );
+
.
+
+ 2. The user-interface components stay fixed and the window resize creates empty space (pixel units) Although the buttons don't now grow, neither does the axes, which looks very odd.
+ f = figure
( 'Position', 200*ones(1,4) );
+axes
( 'Parent', f, ...
+ 'Units', 'Pixels', ...
+ 'OuterPosition', [10 35 190 175] );
+uicontrol
( 'Parent', f, ...
+ 'Units', 'Pixels', ...
+ 'Position', [5 5 90 25], ...
+ 'String', 'Button 1' );
+uicontrol
( 'Parent', f, ...
+ 'Units', 'Pixels', ...
+ 'Position', [105 5 90 25], ...
+ 'String', 'Button 2' );
+
.
+
+ Neither of these alternatives is particularly useful for a serious
+ user-interface. Typically there are user-interface components that should
+ be fixed size: icons, buttons, selectors etc; and others that should resize
+ with the window: graphs, images, prose text etc. To achieve this one needs
+ to be able to specify which interface components should be fixed size and
+ which variable. Over the last two decades, layouts have been shown to be
+ the method of choice for achieving this.
+ For example:
+ Using layouts, some user-interface components scale with the window, others stay fixed
+ f = figure
( 'Position', 200*ones(1,4) );
+vbox = uix.VBox
( 'Parent', f );
+axes( 'Parent', vbox );
+hbox = uix.HButtonBox
( 'Parent', vbox, 'Padding', 5 );
+uicontrol
( 'Parent', hbox, ...
+ 'String', 'Button 1' );
+uicontrol
( 'Parent', hbox, ...
+ 'String', 'Button 2' );
+set( vbox, 'Heights', [-1 35] )
+
.
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2.html
new file mode 100644
index 00000000..cdf0f1c7
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2.html
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+ Positioning axes
+
+
+
+
+
+
+
+ 2: Positioning axes
+
+
+
+ Unlike other MATLAB user interface components, axes
+ have two position properties: Position
and
+ OuterPosition
. This means one has some extra
+ options as to how the layout will arrange the axes.
+
+
+
+
+
+
+
+
+ Section contents:
+
+
+
+
+
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2_1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2_1.html
new file mode 100644
index 00000000..037e15a7
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2_1.html
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+ Position vs OuterPosition
+
+
+
+
+
+
+
+
+
+ 2.1: Position vs OuterPosition
+
+ Typically one
+ would position some axes using their OuterPosition
so that the
+ axis labels, title and other annotations are all contained within the
+ specified area. Sometimes, particularly if drawing images, one might want
+ to instead make the axes canvas (the white bit!) fill the specified area.
+ This is done by setting the Position
property instead.
+
+
+ For example:
+ figure
+axes
( 'Units', 'Normalized', 'OuterPosition', [0 0 1 1] )
+
+
+
+ figure
+axes
( 'Units', 'Normalized', 'Position', [0 0 1 1] )
+
+
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2_2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2_2.html
new file mode 100644
index 00000000..ade94859
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2_2.html
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+ Axes inside layouts
+
+
+
+
+
+
+
+
+
+ 2.2: Axes inside layouts
+
+ (The code for this example can be found here:
+ [ view
+ | edit
+ | run ]
+ )
+
+ When using layouts to position axes, the position property
+ is set by the layout, not the user. Whether the Position
+ or OuterPosition
property is used is determined by the
+ ActivePositionProperty
property of the axes
.
+ Note that the default setting is "outerposition".
+
+
+ The following example illustrates the two usages.
+
+
+ Open a window
+ Open a new figure window and remove the toolbar and menus.
+ window = figure
( 'Name', 'Axes inside layouts', ...
+ 'MenuBar', 'none', ...
+ 'Toolbar', 'none', ...
+ 'NumberTitle', 'off' );
+
+ Create the layout
+ The layout involves two axes side by side. This is done using a flexible horizontal box. The left-hand axes is left with the ActivePositionProperty
set to "outerposition", but the right-hand axes is switched to use Position
.
+ hbox = uix.HBoxFlex
('Parent', window, 'Spacing', 3);
+axes1 = axes
( 'Parent', hbox, ...
+ 'ActivePositionProperty', 'outerposition' );
+axes2 = axes
( 'Parent', hbox, ...
+ 'ActivePositionProperty', 'Position' );
+set( hbox, 'Widths', [-2 -1] );
+
+
+
+ Fill the axes
+ Using OuterPosition
(left-hand axes) is the normal mode and looks good for virtually any plot type. Using Position
is only really useful for 2D plots with the axes turned off, such as images.
+ x = membrane( 1, 15 );
+surf
( axes1, x );
+lighting
( axes1, 'gouraud' );
+shading
( axes1, 'interp' );
+l = light
( 'Parent', axes1 );
+camlight
( l, 'head' );
+axis
( axes1, 'tight' );
+
+imagesc
( x, 'Parent', axes2 );
+set( axes2, 'xticklabel', [], 'yticklabel', [] );
+
+
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2_3.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2_3.html
new file mode 100644
index 00000000..fb600398
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2_3.html
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+ Colorbars and legends
+
+
+
+
+
+
+
+
+
+ 2.3: Colorbars and legends
+
+ (The code for this example can be found here:
+ [ view
+ | edit
+ | run ]
+ )
+
+ When using layouts to position axes that can also have a
+ colorbar or legend it is very important to group the axes
+ with its colorbar and legend by putting them inside a uicontainer
.
+
+
+ The following example illustrates this.
+
+
+ Open a window
+ Open a new figure window and remove the toolbar and menus.
+ window = figure
( 'Name', 'Axes legend and colorbars', ...
+ 'MenuBar', 'none', ...
+ 'Toolbar', 'none', ...
+ 'NumberTitle', 'off' );
+
+
+ Create the layout
+ The layout involves two axes side by side. Each axes is placed into a uicontainer so that the legend and colorbar are "grouped" with the axes.
+ hbox = uix.HBoxFlex
('Parent', window, 'Spacing', 3);
+axes1 = axes
( 'Parent', uicontainer
('Parent', hbox) );
+axes2 = axes
( 'Parent', uicontainer
('Parent', hbox) );
+
+
+
+ Add decorations
+ Give the first axes a colorbar and the second axes a legend.
+ surf
( axes1, membrane
( 1, 15 ) );
+colorbar
( axes1 );
+
+theta = 0:360;
+plot
( axes2, theta, sind
(theta), theta, cosd
(theta) );
+legend
( axes2, 'sin', 'cos', 'Location', 'NorthWestOutside' );
+
+
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide3.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide3.html
new file mode 100644
index 00000000..ae9dec48
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide3.html
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+ Controlling visibility
+
+
+
+
+
+
+
+ 3: Controlling visibility
+
+ The examples in this section show the effect of setting the
+ Visible
property on a layout object.
+
+
+
+ Section contents:
+
+
+
+
+
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide3_1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide3_1.html
new file mode 100644
index 00000000..8a2f9cd3
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide3_1.html
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+ Visible example
+
+
+
+
+
+
+
+
+
+ 3.1: Visible example
+
+ (The code for this example can be found here:
+ [ view
+ | edit
+ | run ]
+ )
+
+ This example shows how the Visible
property can be
+ used to hide whole sections of an interface.
+
+
+ Open a window and add a panel
+ fig = figure
( 'Name', 'Visible example', ...
+ 'Position', [100 100 150 250], ...
+ 'MenuBar', 'none', ...
+ 'ToolBar', 'none', ...
+ 'NumberTitle', 'off' );
+panel = uix.BoxPanel
( 'Parent', fig, 'Title', 'Panel' );
+
+
+
+ Put some buttons inside the panel
+ box = uix.VButtonBox
( 'Parent', panel );
+uicontrol
( 'Parent', box, 'String', 'Button 1' );
+uicontrol
( 'Parent', box, 'String', 'Button 2' );
+uicontrol
( 'Parent', box, 'String', 'Button 3', 'Visible', 'off' );
+uicontrol
( 'Parent', box, 'String', 'Button 4' );
+uicontrol
( 'Parent', box, 'String', 'Button 5', 'Visible', 'off' );
+uicontrol
( 'Parent', box, 'String', 'Button 6' );
+
+
+
+ Try hiding the panel
+ set( panel, 'Visible', 'off' );
+
+
+
+ Try showing the panel. Note that the original Visible
state of each button is remembered.
+ set( panel, 'Visible', 'on' );
+
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4.html
new file mode 100644
index 00000000..04e4fb9f
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4.html
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+ Advanced maneuvers with panels
+
+
+
+
+
+
+
+ 4: Advanced maneuvers with panels
+
+
+ The uix.BoxPanel
provides some extra buttons
+ and callbacks that can be used to design advanced user-interface
+ layouts. In particular, the sections below illustrate how to create
+ interfaces with context help, and panels that can be minimized or undocked.
+
+
+
+
+
+
+
+
+
+
+
+
+ Section contents:
+
+
+
+
+
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4_1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4_1.html
new file mode 100644
index 00000000..48e7bcfb
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4_1.html
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+ Context help
+
+
+
+
+
+
+
+
+
+ 4.1: Context help
+
+
+ When a uix.BoxPanel
has its HelpFcn
+ filled in, a help button (?) is shown in the upper-right of the
+ title-bar. When the user clicks this button the specified function
+ is called.
+
+ For example:
+ Here we hookup the HelpFcn to simply bring up
+ the MATLAB documentation for each command. Clicking any of the "?" buttons
+ will cause the MATLAB help browser to open.
+ f = figure
( 'Name', 'uix.BoxPanel Help Example' );
+b = uix.HBox
( 'Parent', f );
+uix.BoxPanel
( 'Parent', b, 'Title', 'sin', 'HelpFcn', @(a,b) doc('sin') );
+uix.BoxPanel
( 'Parent', b, 'Title', 'cos', 'HelpFcn', @(a,b) doc('cos') );
+uix.BoxPanel
( 'Parent', b, 'Title', 'tan', 'HelpFcn', @(a,b) doc('tan') );
+
+
+
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4_2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4_2.html
new file mode 100644
index 00000000..dd9405ce
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4_2.html
@@ -0,0 +1,140 @@
+
+
+
+
+
+
+ Minimize and maximize
+
+
+
+
+
+
+
+
+
+ 4.2: Minimize and maximize
+
+
+ When a uix.BoxPanel
has its MinimizeFcn
+ filled in, a minimize/maximize button (▴/▾) is shown in the upper-right of the
+ title-bar. When the user clicks this button the specified function
+ is called. Since the behaviour of the parent container is
+ different in different use-cases, it is up to the user to write
+ some code to actually resize the panel. Note that minimizing
+ a panel to its title-bar only really makes sense inside a
+ uix.VBox
or uix.VBoxFlex
.
+
+ The following simple example shows how to add minimize/maximize
+ functionality to a box full of panels. Save the code into
+ a file called "minimizeexample.m" to run it.
+
+ (The code for this example can be found here:
+ [ view
+ | edit
+ | run ]
+ )
+
+
+ Create the layout with three panels
+ Open a new figure window and add three panels.
+ function
minimizeexample()
+width = 200;
+pheightmin = 20;
+pheightmax = 100;
+
+
+fig = figure
( 'Name'
, 'Collapsable GUI example'
, ...
+ 'NumberTitle'
, 'off'
, ...
+ 'Toolbar'
, 'none'
, ...
+ 'MenuBar'
, 'none'
);
+box = uix.VBox
( 'Parent', fig );
+
+panel{1} = uix.BoxPanel
( 'Title'
, 'Panel 1'
, 'Parent'
, box );
+panel{2} = uix.BoxPanel
( 'Title'
, 'Panel 2'
, 'Parent'
, box );
+panel{3} = uix.BoxPanel
( 'Title'
, 'Panel 3'
, 'Parent'
, box );
+set
( box, 'Heights', pheightmax*ones(1,3) );
+
+.
+uicontrol
( 'Style'
, 'PushButton'
, 'String'
, 'Button 1'
, 'Parent'
, panel{1} );
+uicontrol
( 'Style'
, 'PushButton'
, 'String'
, 'Button 2'
, 'Parent'
, panel{2} );
+uicontrol
( 'Style'
, 'PushButton'
, 'String'
, 'Button 3'
, 'Parent'
, panel{3} );
+
+
+pos = get
( fig, 'Position'
);
+set
( fig, 'Position'
, [pos(1,1:2),width,sum(box.Heights)] );
+
+
+
+ Add the minimize/maximize callback
+ We set each panel to call the same minimize/maximize function.
+ This function is nested inside the main function so that it has access
+ to the main function's variables. A better way to do this is to make the
+main function into a class, but this nested-function approach is fine
+for simple applications.
+ Note that as soon as we set the "MinimizeFcn" property the minimize/maximize
+ icon appears in the top-right of each panel. We use a cell-array to pass an
+ extra argument, the panel number, to the minimize function. This extra argument appears after the usual
+ eventSource
and eventData
arguments.
+ .
+set
( panel{1}, 'MinimizeFcn'
, {@nMinimize, 1} );
+set
( panel{2}, 'MinimizeFcn'
, {@nMinimize, 2} );
+set
( panel{3}, 'MinimizeFcn'
, {@nMinimize, 3} );
+
+
+ function
nMinimize( eventSource, eventData, whichpanel )
+
+ s = get
( box, 'Heights'
);
+ pos = get
( fig, 'Position'
);
+ panel{whichpanel}.Minimized = ~panel{whichpanel}.Minimized;
+ if
panel{whichpanel}.Minimized
+ s(whichpanel) = pheightmin;
+ else
+ s(whichpanel) = pheightmax;
+ end
+ set
( box, 'Heights'
, s );
+
+
+ delta_height = pos(1,4) - sum
( box.Heights );
+ set
( fig, 'Position'
, pos(1,:) + [0 delta_height 0 -delta_height] );
+ end
+
+end
+
+
+
+
+ Click the minimize buttons
+ Minimizing the middle panel causes it to shrink to just its
+ title-bar and the window shrinks accordingly. The
+ "Minimize" icon is replaced by a "Maximise" icon.
+
+ Re-maximizing the panel would
+ cause it to re-appear in full and the window to grow again.
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4_3.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4_3.html
new file mode 100644
index 00000000..00e25e98
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4_3.html
@@ -0,0 +1,154 @@
+
+
+
+
+
+
+ Dock and undock
+
+
+
+
+
+
+
+
+
+ 4.3: Dock and undock
+
+
+
+ When a uix.BoxPanel
has its DockFcn
+ filled in, a dock/undock button (↘/↗) is shown in the upper-right of the
+ title-bar. When the user clicks this button the specified function
+ is called. Since re-docking the panel into its previous parent
+ depends on the type of parent, it is up to the user to write
+ some code to actually extract or insert the panel.
+
+ The following simple example shows how to add dock/undock
+ functionality to a box full of panels. Save the code into
+ a file called "dockexample.m" to run it.
+
+ (The code for this example can be found here:
+ [ view
+ | edit
+ | run ]
+ )
+
+ Create the layout with three panels
+ Open a new figure window and add three panels.
+ function
dockexample()
+
+fig = figure
( 'Name'
, 'Dockable GUI example'
, ...
+ 'NumberTitle'
, 'off'
, ...
+ 'Toolbar'
, 'none'
, ...
+ 'MenuBar'
, 'none'
, ...
+ 'CloseRequestFcn'
, @nCloseAll );
+box = uix.HBox
( 'Parent'
, fig );
+
+
+panel{1} = uix.BoxPanel
( 'Title'
, 'Panel 1'
, 'Parent'
, box );
+panel{2} = uix.BoxPanel
( 'Title'
, 'Panel 2'
, 'Parent'
, box );
+panel{3} = uix.BoxPanel
( 'Title'
, 'Panel 3'
, 'Parent'
, box );
+
+
+uicontrol
( 'Style'
, 'PushButton'
, 'String'
, 'Button 1'
, 'Parent'
, panel{1} );
+uicontrol
( 'Style'
, 'PushButton'
, 'String'
, 'Button 2'
, 'Parent'
, panel{2} );
+uicontrol
( 'Style'
, 'PushButton'
, 'String'
, 'Button 3'
, 'Parent'
, panel{3} );
+
+
+
+ Add the dock/undock callback
+ We set each panel to call the same dock/undock function.
+ This function is nested inside the main function so that it has access
+ to the main function's variables. A better way to do this is to make the
+main function into a class, but this nested-function approach is fine
+for simple applications.
+ Note that as soon as we set the "DockFcn" property the Dock/Undock
+ icon appears in the top-right of each panel. We use a cell-array to pass an
+ extra argument, the panel number, to the minimize function. This extra argument appears after the usual
+ eventSource
and eventData
arguments.
+
+set
( panel{1}, 'DockFcn'
, {@nDock, 1} );
+set
( panel{2}, 'DockFcn'
, {@nDock, 2} );
+set
( panel{3}, 'DockFcn'
, {@nDock, 3} );
+
+
+ function
nDock( eventSource, eventData, whichpanel )
+
+ panel{whichpanel}.Docked = ~panel{whichpanel}.Docked;
+ if
panel{whichpanel}.Docked
+
+ newfig = get
( panel{whichpanel}, 'Parent'
);
+ set
( panel{whichpanel}, 'Parent'
, box );
+ delete
( newfig );
+ else
+
+ pos = getpixelposition
( panel{whichpanel} );
+ newfig = figure
( ...
+ 'Name'
, get
( panel{whichpanel}, 'Title'
), ...
+ 'NumberTitle'
, 'off'
, ...
+ 'MenuBar'
, 'none'
, ...
+ 'Toolbar'
, 'none'
, ...
+ 'CloseRequestFcn'
, {@nDock, whichpanel} );
+ figpos = get
( newfig, 'Position'
);
+ set
( newfig, 'Position'
, [figpos(1,1:2), pos(1,3:4)] );
+ set
( panel{whichpanel}, 'Parent'
, newfig, ...
+ 'Units'
, 'Normalized'
, ...
+ 'Position'
, [0 0 1 1] );
+ end
+ end
+
+
+ Add the close callback
+ If the user closes the main window we need to also close any
+ other windows that were created. This can be done by finding
+ the window that contains each panel and deleting it.
+
+ function
nCloseAll( ~, ~ )
+ for
ii=1:numel
( panel )
+ if
isvalid
( panel{ii} ) && ~strcmpi
( panel{ii}.BeingDeleted, 'on'
)
+ figh = ancestor
( panel{ii}, 'figure'
);
+ delete
( figh );
+ end
+ end
+
+ end
+end
+
+
+
+ Click the dock buttons
+ Undocking the middle panel causes the other two to fill the
+ vacated space. The undocked panel appears in its own window, with the
+ "Undock" icon replaced by a "Dock" icon.
+
.
+ Re-docking the panel would
+ cause it to be appended to the right of the list in the original window. Closing the main window
+ causes all panels, docked or undocked, and their enclosing windows to be closed.
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide5.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide5.html
new file mode 100644
index 00000000..a3df08ac
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide5.html
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+ Using layouts inside GUIDE GUIs
+
+
+
+
+
+
+
+ 5: Using layouts inside GUIDE GUIs
+
+
+ Whilst the layouts in this toolbox do not integrate into the
+ MATLAB Graphical User Interface Design Environment (GUIDE
), it
+ is possible to insert layouts into a GUIDE-built GUI as follows:
+ Create the GUIDE GUI
+ Create you GUIDE application as usual, placing a panel where you
+ want to insert the layout. You can turn the panel border and title
+ off if you do not want them.
+
+
+ Insert the layout
+ Edit the "OpeningFcn" in the GUIDE-created code and insert your
+ layout into the panel, making it fill the space. In the example below
+four boxpanels are inserted into a grid, which itself is placed inside
+ uipanel1
:
+
+
+function
guideApp_OpeningFcn(hObject, eventdata, handles, varargin)
+
+
+handles.output = hObject;
+
+
+guidata(hObject, handles);
+
+
+g = uix.GridFlex
( 'Parent'
, handles.uipanel1, ...
+ 'Units'
, 'Normalized'
, 'Position'
, [0 0 1 1], ...
+ 'Spacing'
, 5 );
+uix.BoxPanel
( 'Parent'
, g, 'Title'
, 'Panel 1'
);
+uix.BoxPanel
( 'Parent'
, g, 'Title'
, 'Panel 2'
);
+uix.BoxPanel
( 'Parent'
, g, 'Title'
, 'Panel 3'
);
+uix.BoxPanel
( 'Parent'
, g, 'Title'
, 'Panel 4'
);
+g.Heights = [-1 -1];
+
+
+ (Full source code for this application is available here:
+ [ view
+ | edit
+ | run ]
+ )
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide6.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide6.html
new file mode 100644
index 00000000..d07f9d22
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide6.html
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+ Deploying GUIs using the MATLAB Compiler
+
+
+
+
+
+
+
+ 6: Deploying GUIs using the MATLAB Compiler
+
+
+
+ Applications built using these layout tools can be deployed as standalone
+ executables using the MATLAB Compiler in
+ the same way as any other MATLAB application. There is, however, one thing to watch out for:
+
+ You must explicitly include the "Resources" folder within the +uix package
+
+ Example
+ Below is a screen-shot of the deploytool
setup
+ used to build the example application .
+ The "Resources" folder from the toolbox has been explicitly added as a
+shared resource so that the mouse-pointers and panel icons continue to work.
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7.html
new file mode 100644
index 00000000..7a9db9fd
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7.html
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+ A complete example
+
+
+
+
+
+
+
+ 7: A complete example
+
+
+
+
+ The following example application uses many of the layout features
+ discussed above in order to create a good-looking user interface that
+ scales well when resized. It is not designed to showcase all the
+ layout functionality, but shows how callbacks are added to provide
+ user interaction. It also exemplifies separating the data from the GUI,
+ a fundamental part of creating modular and maintainable applications.
+ The full application is available here:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Section contents:
+
+
+
+
+
+
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_1.html
new file mode 100644
index 00000000..d5ce65aa
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_1.html
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+ Application structure
+
+
+
+
+
+
+
+
+
+ 7.1: Application structure
+
+
+ There are many ways to build graphical applications in MATLAB, but
+ here we will take a very simple approach. If the application were to become
+larger and more complex, this approach would be changed to better mitigate
+ the complexity. Some notes on this are contained at the end .
+
+ The application is structured as a single function with callbacks and other helper
+ functions stored as "nested" subfunctions, i.e. functions inside the main function. This has
+ the advantage that the nested subfunctions can share access to any variables
+ declared in the main function. This is also a risk as anything we accidentally
+ declare in the main function becomes "global" within the application. For that reason
+ all logic is put into subfunctions and we restrict the main
+ function to just declaring two shared variables:
+
+ data : a structure containing all shared data
+ gui : a structure containing handles to GUI widgets
+
+
+function
demoBrowser()
+
+
+ data = createData();
+ gui = createInterface( data.DemoNames );
+
+
+ updateInterface();
+ redrawDemo();
+
+ .
+ function
data = createData() ... end
;
+ function
gui = createInterface(names) ... end
;
+ function
updateInterface() ... end
;
+ function
redrawDemo() ... end
;
+
+ .
+ function
onMenuSelection() ... end
;
+ function
onListSelection() ... end
;
+ function
onDemoHelp() ... end
;
+ function
onHelp() ... end
;
+ function
onExit() ... end
;
+
+end
+
+
+Note that all of the work is done in subfunctions. Most subfunctions
+are callbacks executed when a button is pressed or a menu selected. The four used
+at startup are helper functions:
+
+ createData : build the structure which contains all application data
+ createInterface : build the user interface
+ updateInterface : update selectors etc in response to a change in the data
+ redrawDemo : redraw the plot part of the interface
+
+ We will not dig into all the subfunctions and callbacks, but instead
+ concentrate on the GUI creation (createInterface )
+ and update (updateInterface ).
+
+ (Full source code for this application is available here:
+ [ view
+ | edit
+ | run ]
+ )
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_2.html
new file mode 100644
index 00000000..ccc55e4a
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_2.html
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+ createInterface
+
+
+
+
+
+
+
+
+
+ 7.2: createInterface
+
+ The interface creation is handled in the createInterface
+ subfunction. This has two distinct sections: menu building and widget arrangement.
+ The menus are built using the standard MATLAB menu building command uimenu
,
+ so let's concentrate on the widget arrangement.
+
+ The top-level layout is a horizontal arrangement, placing the controls
+to the left of the main plot. We make the layout draggable by using the
+"flex" variant of HBox, and put a panel in each side. Note that setting the
+"HelpFcn" for the view panel adds a small "?" icon for bringing up help. See
+here for more details.
+
+
+mainLayout = uix.HBoxFlex
( 'Parent'
, gui.Window, 'Spacing'
, 3 );
+
+
+controlPanel = uix.BoxPanel
( ...
+ 'Parent'
, mainLayout, ...
+ 'Title'
, 'Select a demo:'
);
+gui.ViewPanel = uix.BoxPanel
( ...
+ 'Parent'
, mainLayout, ...
+ 'Title'
, 'Viewing: ???'
, ...
+ 'HelpFcn'
, @onDemoHelp );
+
+
+set
( mainLayout, 'Widths'
, [-1,-2] );
+
+
+
+The controls panel is filled with a vertical layout containing the listbox
+and a button. Note the callbacks that are specified for both the list and button. These
+both call further subfunctions that are able to access the common "data" and "gui"
+shared structures.
+
+
+controlLayout = uix.VBox
( 'Parent'
, controlPanel, ...
+ 'Padding'
, 3, 'Spacing'
, 3 );
+gui.ListBox = uicontrol
( 'Style'
, 'list'
, ...
+ 'BackgroundColor'
, 'w'
, ...
+ 'Parent'
, controlLayout, ...
+ 'String'
, demoList(:), ...
+ 'Value'
, 1, ...
+ 'Callback'
, @onListSelection);
+gui.HelpButton = uicontrol
( 'Style'
, 'PushButton'
, ...
+ 'Parent'
, controlLayout, ...
+ 'String'
, 'Help for <demo>'
, ...
+ 'Callback'
, @onDemoHelp );
+set
( controlLayout, 'Heights'
, [-1 28] );
+
+
+
+Finally, the view itself is simply an axes placed inside the view panel:
+
+
+gui.ViewAxes = axes
( 'Parent'
, gui.ViewPanel );
+
+
+
+ (Full source code for this application is available here:
+ [ view
+ | edit
+ | run ]
+ )
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_3.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_3.html
new file mode 100644
index 00000000..9bf8a672
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_3.html
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+ updateInterface
+
+
+
+
+
+
+
+
+
+ 7.3: updateInterface
+
+ The second subfunction we will look at, updateInterface
, uses the
+ current selections to update the interface. This uses the structure
+ "data" to update various parts of the interface. For this simple example this just means:
+
+ 1. Update the selected item in the listbox
+ set( gui.ListBox, 'Value'
, data.SelectedDemo );
+ 2. Update the help button label
+ demoName = data.DemoNames{ data.SelectedDemo };set
( gui.HelpButton, 'String'
, ['Help for '
,demoName] );
+ 3. Update the view panel title
+ set
( gui.ViewPanel, 'Title'
, sprintf
( 'Viewing: %s'
, demoName ) );
+ 4. Update the ticked menu
+ menus = get
( gui.ViewMenu, 'Children'
);
+set
( menus, 'Checked'
, 'off'
);
+
+whichMenu = strcmpi
( demoName, get
( menus, 'Label'
) );
+set
( menus(whichMenu), 'Checked'
, 'on'
);
+
+
+ In general, this update function is called whenever the underlying
+ shared "data" structure is changed. This happens when the user clicks
+ a button, selects a list item or a menu. Next we will look at a typical
+ callback.
+ (Full source code for this application is available here:
+ [ view
+ | edit
+ | run ]
+ )
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_4.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_4.html
new file mode 100644
index 00000000..abf373ed
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_4.html
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+ onListSelection
+
+
+
+
+
+
+
+
+
+ 7.4: onListSelection
+
+ Finally, let's have a look at how one of the callbacks works: "onListSelection", the function
+ that is called when an item is selected in the listbox. The other
+ callbacks obey the same pattern.
+ The basic rule of thumb is that a callback should not update any part of
+ the user interface directly - it's job is to respond to user interaction by changing the "data" structure.
+ In this example, each callback changes the underlying data structure
+ then asks the interface to refresh. This might mean that things update in the
+interface that don't need to, but ensures the callbacks remain simple and that all
+interface update logic is in one place. Extending this to more granular interface updates
+ is straightforward. See Scalability for more details.
+ For the listbox callback, the "src" argument is a handle to the
+ listbox and we simply need to update the SelectedDemo field of "data"
+ to reflect the new selection. We then ask the rest of the interface to
+ update in response to the change.
+
+
+
+data.SelectedDemo = get
( src, 'Value'
);
+updateInterface();
+redrawDemo();
+
+
+ (Full source code for this application is available here:
+ [ view
+ | edit
+ | run ]
+ )
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_5.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_5.html
new file mode 100644
index 00000000..3730b54f
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_5.html
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+ Running it
+
+
+
+
+
+
+
+
+
+ 7.5: Running it
+
+ When the main function is launched (click
+ here )
+ it first creates the data, then the GUI, then updates the GUI using the data. At this point the
+ function exits and control is returned to the command prompt. Note, however,
+ that the GUI is still onscreen and will still respond to user interaction.
+ This works because the "shared" variables in the main function are not cleared when the
+ function exits. They are only cleared once the GUI is closed. This is a slightly
+ unusual, but very useful, feature of using nested functions for building
+ applications.
+ For example:
+ >> demoBrowser
+
+
+ (Full source code for this application is available here:
+ [ view
+ | edit
+ | run ]
+ )
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_6.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_6.html
new file mode 100644
index 00000000..f4940c7b
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_6.html
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+ Scalability
+
+
+
+
+
+
+
+
+
+ 7.6: Scalability
+
+ As applications get bigger the code gets more complex. The simple
+ application structure used here does not scale well to large applications,
+ however some small adjustments can make life much better:
+
+ Convert the "data" structure into a handle object . This allows
+ a single "data" object to be shared between mutliple graphical interfaces, and in turn means that the interface
+ need not be built as a single monolithic entity.
+ Use the events system to trigger updates
+ to specific parts of the GUI in response to bits of the data object changing. This removes the need
+ for a single large "UpdateInterface" function and reduces coupling between parts of the interface. For example,
+ the "SelectedDemo" property would have an associated event such that when it is changed by a callback (or from the command-line) it
+ notifies other interface components of the change. Each interface component (or group thereof) can
+ just listen for the events that affect it.
+
+ Advice on how to build large-scale applications is beyond the scope
+ of this document. If you need help in this area, please contact your MathWorks
+ account manager who will be able to put you in touch with a technical specialist.
+
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
+
+>
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/VisibleExample.html b/studio_functions/GUI Layout Toolbox/layoutdoc/VisibleExample.html
new file mode 100644
index 00000000..ac5f7cf3
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/VisibleExample.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/about.html b/studio_functions/GUI Layout Toolbox/layoutdoc/about.html
new file mode 100644
index 00000000..8e7fc660
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/about.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/atoz.html b/studio_functions/GUI Layout Toolbox/layoutdoc/atoz.html
new file mode 100644
index 00000000..550482a0
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/atoz.html
@@ -0,0 +1,181 @@
+
+
+
+
+ GUI Layout Toolbox documentation: Index
+
+
+
+ Alphabetical index
+
+ A -
+ B -
+ C -
+ D -
+ E -
+ F -
+ G -
+ H -
+ I -
+ J -
+ K -
+ L -
+ M
+
+ N -
+ O -
+ P -
+ Q -
+ R -
+ S -
+ T -
+ U -
+ V -
+ W -
+ X -
+ Y -
+ Z
+
+
+
+
+ © 2020 The MathWorks Inc
+ Terms of Use
+ Patents
+ Trademarks
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/compatibility.html b/studio_functions/GUI Layout Toolbox/layoutdoc/compatibility.html
new file mode 100644
index 00000000..b2d0ee7c
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/compatibility.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserCreateInterface.html b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserCreateInterface.html
new file mode 100644
index 00000000..a898794f
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserCreateInterface.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserOnListSelection.html b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserOnListSelection.html
new file mode 100644
index 00000000..5716a18d
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserOnListSelection.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserRun.html b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserRun.html
new file mode 100644
index 00000000..7e1365fe
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserRun.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserScalability.html b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserScalability.html
new file mode 100644
index 00000000..e0958b95
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserScalability.html
@@ -0,0 +1 @@
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserStructure.html b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserStructure.html
new file mode 100644
index 00000000..ce85576a
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserStructure.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserUpdateInterface.html b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserUpdateInterface.html
new file mode 100644
index 00000000..83048e5d
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserUpdateInterface.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/doc.css b/studio_functions/GUI Layout Toolbox/layoutdoc/doc.css
new file mode 100644
index 00000000..8a52a82c
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/doc.css
@@ -0,0 +1,95 @@
+ H4 { color: rgb(153,0,0);
+ font-family: Arial,Helvetica,sans-serif;
+ font-weight: bold;
+ font-size: smallnormal;
+ }
+
+ H3 { color: rgb(153,0,0);
+ font-family: Arial,Helvetica,sans-serif;
+ font-weight: bold;
+ font-size: large;
+ }
+
+ H2 { color: rgb(153,0,0);
+ font-weight: bold;
+ font-size: x-large;
+ font-family: Arial,Helvetica,sans-serif;
+ }
+
+ H1 { color: rgb(10,0,0);
+ font-weight: bold;
+ font-size: xx-large;
+ font-family: Arial,Helvetica,sans-serif;
+ }
+
+ P { font-weight: normal;
+ font-style: normal;
+ color: rgb(0, 0, 32);
+ font-family: Arial,Helvetica,sans-serif;
+ text-decoration: none;
+ }
+
+ LI { font-weight: normal;
+ font-style: normal;
+ color: rgb(0, 0, 32);
+ font-family: Arial,Helvetica,sans-serif;
+ text-decoration: none;
+ }
+
+ A { font-weight: normal;
+ font-style: normal;
+ color: rgb(0,0,180, 0, 0);
+ font-family: Arial,Helvetica,sans-serif;
+ text-decoration: none;
+ }
+
+ CODE { font-family: Courier New,Courier,monospace;
+ color: #000044;
+ font-size: -1;
+ }
+CODE.FUNCTION {
+ color: #0000EE;
+ font-weight: bold;
+}
+CODE.INARG {
+ color: #008800;
+ font-weight: bold;
+}
+CODE.OUTARG {
+ color: #880000;
+ font-weight: bold;
+ }
+CODE.COMMENT {
+ color: #008800;
+}
+CODE.STRING {
+ color: #DD00FF;
+}
+
+TABLE.PROPERTYTABLE {
+ border-width: 3;
+ border-style: inset;
+ border-color: #777777;
+ cellpadding: 4;
+ cellspacing: 0;
+}
+TH.PROPERTYTABLE {
+ font-weight: bold;
+ color: #000000;
+ border-width: 2;
+ border-style: inset;
+ background-color: #b2b2b2;
+}
+TD.PROPERTYTABLE {
+ font-weight: normal;
+ color: #000000;
+ border-width: 2;
+ border-style: inset;
+ background-color: #f2f2f2;
+}
+
+PRE { font-family: Courier New,Courier,monospace;
+ color: #000044;
+ font-size: -1;
+}
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/frames.html b/studio_functions/GUI Layout Toolbox/layoutdoc/frames.html
new file mode 100644
index 00000000..3b236e26
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/frames.html
@@ -0,0 +1,12 @@
+
+
+
+ GUI Layout Documentation
+
+
+
+
+
+
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/helpindex.xml b/studio_functions/GUI Layout Toolbox/layoutdoc/helpindex.xml
new file mode 100644
index 00000000..8d828521
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/helpindex.xml
@@ -0,0 +1,118 @@
+
+
+
+
+A complete example
+About
+Acknowledgements
+Advanced maneuvers with panels
+Application design
+Application structure
+axes
+Axes inside layouts
+Box
+ uix.HBox (Function reference: 2.1)
+ uix.VBox (Function reference: 2.2)
+ uix.HBoxFlex (Function reference: 2.3)
+ uix.VBoxFlex (Function reference: 2.4)
+
+Boxes
+BoxPanel
+Button box
+ uix.HButtonBox (Function reference: 2.5)
+ uix.VButtonBox (Function reference: 2.6)
+
+Callbacks
+CardPanel
+Colorbars and legends
+Compatibility considerations
+Compiler
+Context help
+Controlling visibility
+createInterface
+Deploying GUIs using the MATLAB Compiler
+Dock and undock
+Draggable dividers
+ uix.HBoxFlex (Function reference: 2.3)
+ uix.VBoxFlex (Function reference: 2.4)
+ uix.GridFlex (Function reference: 3.2)
+
+Empty
+Examples
+Flexible layout
+ uix.HBoxFlex (Function reference: 2.3)
+ uix.VBoxFlex (Function reference: 2.4)
+
+Folder
+Function reference
+Getting Started
+Grid
+GridFlex
+Grids
+GUIDE
+HBox
+HBoxFlex
+HButtonBox
+Help
+Horizontal button layout
+Horizontal layout
+ uix.HBox (Function reference: 2.1)
+ uix.HBoxFlex (Function reference: 2.3)
+
+Installation
+Installation folder
+Layout basics
+Layout hierarchies
+layoutRoot
+MATLAB Compiler
+Minimize and maximize
+Minimum sizes
+onListSelection
+Other functions
+Panel
+Panels
+Position vs OuterPosition
+Positioning axes
+Release notes
+Root
+Running it
+Scalability
+ScrollingPanel
+Sizes and units
+Support
+TabPanel
+Tracking
+Types of layout
+uix.BoxPanel
+uix.CardPanel
+uix.Empty
+uix.Grid
+uix.GridFlex
+uix.HBox
+uix.HBoxFlex
+uix.HButtonBox
+uix.Panel
+uix.ScrollingPanel
+uix.TabPanel
+uix.tracking
+uix.VBox
+uix.VBoxFlex
+uix.VButtonBox
+Understanding layouts
+Undock
+Uninstall
+updateInterface
+User guide
+Using layouts inside GUIDE GUIs
+VBox
+VBoxFlex
+VButtonBox
+Vertical button layout
+Vertical layout
+ uix.VBox (Function reference: 2.2)
+ uix.VBoxFlex (Function reference: 2.4)
+
+Visible example
+What is GUI Layout Toolbox?
+Why use layouts?
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/_0.cfe b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/_0.cfe
new file mode 100644
index 00000000..db432f76
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/_0.cfe differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/_0.cfs b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/_0.cfs
new file mode 100644
index 00000000..1f92793e
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/_0.cfs differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/_0.si b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/_0.si
new file mode 100644
index 00000000..d69cdbcf
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/_0.si differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/segments.gen b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/segments.gen
new file mode 100644
index 00000000..63a7ec9a
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/segments.gen differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/segments_1 b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/segments_1
new file mode 100644
index 00000000..da81286a
Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/segments_1 differ
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/helptoc.html b/studio_functions/GUI Layout Toolbox/layoutdoc/helptoc.html
new file mode 100644
index 00000000..2e1b12f9
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/helptoc.html
@@ -0,0 +1,37 @@
+
+
+
+ Table of Contents
+
+
+
+
+ GUI Layout
+
+ Getting Started
+ 1. What is GUI Layout Toolbox?
+ 2. Compatibility considerations
+ 3. Release notes
+ 4. Installation
+ 5. Support
+ 6. Acknowledgements
+
+
+ Examples
+
+
+ User guide
+ 1. Understanding layouts
+ 2. Positioning axes
+ 3. Controlling visibility
+ 4. Advanced maneuvers with panels
+ 5. Using layouts inside GUIDE GUIs
+ 6. Deploying GUIs using the MATLAB Compiler
+ 7. A complete example
+
+
+ Function reference
+
+ Index
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/helptoc.xml b/studio_functions/GUI Layout Toolbox/layoutdoc/helptoc.xml
new file mode 100644
index 00000000..499b9bb4
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/helptoc.xml
@@ -0,0 +1,12 @@
+
+
+
+
+ GUI Layout
+ Getting Started1. What is GUI Layout Toolbox? 2. Compatibility considerations 3. Release notes 4. Installation 5. Support 6. Acknowledgements
+ Examples
+ User guide1. Understanding layouts1.1. Layout basics 1.2. Types of layout 1.3. Sizes and units 1.4. Layout hierarchies 1.5. Why use layouts? 2. Positioning axes2.1. Position vs OuterPosition 2.2. Axes inside layouts 2.3. Colorbars and legends 3. Controlling visibility3.1. Visible example 4. Advanced maneuvers with panels4.1. Context help 4.2. Minimize and maximize 4.3. Dock and undock 5. Using layouts inside GUIDE GUIs 6. Deploying GUIs using the MATLAB Compiler 7. A complete example7.1. Application structure 7.2. createInterface 7.3. updateInterface 7.4. onListSelection 7.5. Running it 7.6. Scalability
+ Function reference1. Panels1.1. uix.Panel 1.2. uix.CardPanel 1.3. uix.BoxPanel 1.4. uix.TabPanel 1.5. uix.ScrollingPanel 2. Boxes2.1. uix.HBox 2.2. uix.VBox 2.3. uix.HBoxFlex 2.4. uix.VBoxFlex 2.5. uix.HButtonBox 2.6. uix.VButtonBox 3. Grids3.1. uix.Grid 3.2. uix.GridFlex 4. Other functions4.1. uix.Empty 4.2. uix.tracking 4.3. layoutRoot
+ Index
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/index.html b/studio_functions/GUI Layout Toolbox/layoutdoc/index.html
new file mode 100644
index 00000000..5c68954c
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/index.html
@@ -0,0 +1,54 @@
+
+
+
+
+
+ GUI Layout Toolbox
+
+
+
+
+
+
+ GUI Layout Toolbox
+ Version: 2.3.5
+
+ GUI Layout Toolbox is a layout manager for creating MATLAB graphical user
+ interfaces that resize gracefully. The classes supplied can be used in
+ combination to produce virtually any user interface layout.
+
+
+
+ Arrange MATLAB user interface components horizontally, vertically or in grids
+ Mix fixed- and variable-size components
+ Resize components interactively by dragging dividers
+ Show and hide components using tabs and panels
+ Show part of a large component in a scrollable panel
+
+
+
+ This toolbox was developed by
+ David Sampson and
+ Ben Tordoff from the
+ Consulting Services group
+ at MathWorks .
+
+
+ Contents:
+
+ Getting Started : Introductory notes and installation instructions
+ Examples : A list of the examples that are provided in the documentation
+ User guide : Describes how to use these tools
+ Function reference : A list of the available functions
+ Index :
+Alphabetical index of sections, functions and concepts
+
+
+
+ © 2020 The MathWorks Ltd
+ Terms of Use
+ Patents
+ Trademarks
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/info.xml b/studio_functions/GUI Layout Toolbox/layoutdoc/info.xml
new file mode 100644
index 00000000..ef78de74
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/info.xml
@@ -0,0 +1,11 @@
+
+
+
+
+14
+GUI Layout
+toolbox
+$toolbox/matlab/icons/bookicon.gif
+../layoutdoc
+
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/layoutDocRoot.m b/studio_functions/GUI Layout Toolbox/layoutdoc/layoutDocRoot.m
new file mode 100644
index 00000000..3ae3cc13
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/layoutDocRoot.m
@@ -0,0 +1,12 @@
+function folder = layoutDocRoot()
+%layoutDocRoot Return the location of the GUI Layout Toolbox documentation.
+%
+% folder = layoutDocRoot()
+%
+% See also: layoutRoot
+
+% Copyright 2014 The MathWorks, Inc.
+
+folder = fileparts( mfilename( 'fullpath' ) );
+
+end % layoutDocRoot
\ No newline at end of file
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/layoutRoot.html b/studio_functions/GUI Layout Toolbox/layoutdoc/layoutRoot.html
new file mode 100644
index 00000000..60ea04fe
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/layoutRoot.html
@@ -0,0 +1 @@
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/releasenotes.html b/studio_functions/GUI Layout Toolbox/layoutdoc/releasenotes.html
new file mode 100644
index 00000000..b5881263
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/releasenotes.html
@@ -0,0 +1 @@
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/termsOfUse.m b/studio_functions/GUI Layout Toolbox/layoutdoc/termsOfUse.m
new file mode 100644
index 00000000..386c744e
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/termsOfUse.m
@@ -0,0 +1,8 @@
+function termsOfUse
+ if verLessThan('matlab','8.5')
+ helpview([matlabroot,'/license.txt'])
+ else
+ helpview([matlabroot,'/license_agreement.txt'])
+ end
+end
+
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.BoxPanel.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.BoxPanel.html
new file mode 100644
index 00000000..d0f551a1
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.BoxPanel.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.CardPanel.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.CardPanel.html
new file mode 100644
index 00000000..b439ef14
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.CardPanel.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.Empty.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.Empty.html
new file mode 100644
index 00000000..18194480
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.Empty.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.Grid.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.Grid.html
new file mode 100644
index 00000000..eb460a34
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.Grid.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.GridFlex.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.GridFlex.html
new file mode 100644
index 00000000..4d9c55be
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.GridFlex.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.HBox.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.HBox.html
new file mode 100644
index 00000000..02857cad
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.HBox.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.HBoxFlex.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.HBoxFlex.html
new file mode 100644
index 00000000..6988221c
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.HBoxFlex.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.HButtonBox.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.HButtonBox.html
new file mode 100644
index 00000000..471742fb
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.HButtonBox.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.Panel.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.Panel.html
new file mode 100644
index 00000000..27078921
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.Panel.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.ScrollingPanel.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.ScrollingPanel.html
new file mode 100644
index 00000000..403cd9c9
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.ScrollingPanel.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.TabPanel.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.TabPanel.html
new file mode 100644
index 00000000..740483a7
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.TabPanel.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.VBox.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.VBox.html
new file mode 100644
index 00000000..d53bef34
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.VBox.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.VBoxFlex.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.VBoxFlex.html
new file mode 100644
index 00000000..3e8d63c6
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.VBoxFlex.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.VButtonBox.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.VButtonBox.html
new file mode 100644
index 00000000..ebf2e984
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.VButtonBox.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.tracking.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.tracking.html
new file mode 100644
index 00000000..bdce69af
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.tracking.html
@@ -0,0 +1 @@
+ >
diff --git a/studio_functions/GUI Layout Toolbox/license.txt b/studio_functions/GUI Layout Toolbox/license.txt
new file mode 100644
index 00000000..60c73dcb
--- /dev/null
+++ b/studio_functions/GUI Layout Toolbox/license.txt
@@ -0,0 +1,26 @@
+Copyright (c) 2020, The MathWorks, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* In all cases, the software is, and all modifications and derivatives of the
+ software shall be, licensed to you solely for use in conjunction with
+ MathWorks products and service offerings.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/studio_functions/GUIs/ERP Tab/binoper_studioGUI.fig b/studio_functions/GUIs/ERP Tab/binoper_studioGUI.fig
new file mode 100755
index 00000000..0489a3c6
Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/binoper_studioGUI.fig differ
diff --git a/studio_functions/GUIs/ERP Tab/binoper_studioGUI.m b/studio_functions/GUIs/ERP Tab/binoper_studioGUI.m
new file mode 100755
index 00000000..5a66387f
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/binoper_studioGUI.m
@@ -0,0 +1,862 @@
+
+% Note: very preliminary alfa version. Only for testing purpose. May 2008
+%
+% HELP PENDING for this function
+% Write erplab at command window for help
+%
+%
+% Bin Operations:
+%
+% The Bin Operations function allows you to compute RUN bins that are linear
+% combinations of the bins in the current ERP structure. For example, you can
+% average multiple bins together, and you can compute difference waves. It operates in the same manner as Channel Operations. That is, you create equations that look like this: bin6 = 0.5*bin3 0.5*bin2. This is like a simplified version of the erpmanip program in ERPSS. We will eventually create a more sophisticated version that has the same power as erpmanip.
+%
+% Your bins are stored in a Matlab structure named ERP, at binavg field
+% (ERP.binvg). This field has 3 dimensions:
+%
+% row = channels
+% column = points (signal)
+% depth = bin's slot (bin index).
+%
+% So, the depth dimension will increase as you define a RUN bin, correctly
+% numbered (sorted). To create a RUN bin you have simply to use an algebraic expression for that bin.
+%
+% Example:
+%
+% Currently you have 4 bins created, and now you need to create a RUN bin
+% (bin 5) with the difference between bin 2 and 4. So, you should go to Bin
+% Operation, at the ERPLAB menu, and this will pop up a RUN GUI. At the editing window enter the next simple expression:
+%
+% bin5 = bin2 - bin4 label Something Important
+%
+% and press APPEND.
+%
+% Note1: You can also write in a short style expression: b5 = b2 - b4.
+%
+% For label setting you could use : ...label Something Important or
+% ....label = Something Important
+%
+% If you do not define a label, binoperator will use a short expression of
+% the current formula as a label, BIN5: B2-B4
+%
+% In case you need to create more than one RUN bin, you will need to enter
+% a carriage return at the end of each expression (formula) as you are writing
+% a list of algebraic expressions.
+%
+% Example:
+%
+% b5 = b2 - b4 label bla-bla
+% b6 = (b1+b3)/2 label= attended or b6 = 0.5*b1 + 0.5*b3 ...
+% b7 = abs(b5) label rectified or b7 = sqrt(b5^2) ...
+%
+% and press APPEND.
+%
+% Note 2: You already realized you can use bins just predefined in your list,
+% so be cautious with this predefinition to avoid mistakes in long lists.
+%
+% Note 3: Also you can use more complex expressions as this:
+% bin8 = (b1+b2)/2 - (b3+b4)/2
+% or, eventually, something much weirder as this b9 = sqrt(b2^2 + b3^2)
+%
+% Finally, you can save and load your formulas in order to avoid to rewrite
+% it more than one time. Use EXPORT & IMPORT buttons for this,
+% respectively.
+%
+% See pop_binoperator()
+%
+% Author: Javier Lopez-Calderon & Steven Luck
+% Center for Mind and Brain
+% University of California, Davis,
+% Davis, CA
+% 2009
+
+%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b
+%
+% ERPLAB Toolbox
+% Copyright © 2007 The Regents of the University of California
+% Created by Javier Lopez-Calderon and Steven Luck
+% Center for Mind and Brain, University of California, Davis,
+% javlopez@ucdavis.edu, sjluck@ucdavis.edu
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see .
+
+% Begin initialization code - DO NOT EDIT
+
+function varargout = binoper_studioGUI(varargin)
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @binoper_studioGUI_OpeningFcn, ...
+ 'gui_OutputFcn', @binoper_studioGUI_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+% End initialization code - DO NOT EDIT
+
+%--------------------------------------------------------------------------
+function binoper_studioGUI_OpeningFcn(hObject, eventdata, handles, varargin)
+% Choose default command line output for binoper_studioGUI
+handles.output = [];
+try
+ ERP = varargin{1};
+ %
+ % Prepare List of current Bins
+ %
+ listb = [];
+ nbinmax = ERP.nbin;
+ for b=1:nbinmax
+ listb{b} = ['BIN' num2str(b) ' = ' ERP.bindescr{b} ];
+ end
+ chanlocs = ERP.chanlocs;
+ bindescr = ERP.bindescr;
+catch
+ ERP = [];
+ listb = '';
+ nbinmax = 1;
+ chanlocs = [];
+end
+try
+ def = varargin{2};
+ formulas = def{1};
+ wbmsgon = def{2};
+catch
+ formulas = [];
+ wbmsgon = 1;
+end
+
+example{1} = 'b$ = (b1+b3)/2 label attended left';
+example{2} = 'B$ = (B1+B3+B5)/3 label = attended left';
+example{3} = 'bin$ = sqrt(bin1^2+bin3^2) label distance';
+example{4} = 'b$ = (b1-b3)/(b1+b3) label = Special';
+example{5} = 'b$ = 0.5*b1+0.5*b3 label = attended left';
+example{6} = 'b$ = wavgbin(1,3) label = attended left (weighted)';
+example{7} = 'BIN$ = 0.5*b1 + 0.5*b3 label attended left';
+example{8} = sprintf('L=[1 3 5 7 9]\nR=[2 4 6 8 10]\nB$ = 0.5*b3@L + 0.5*b4@R label GLOBAL CONTRA');
+
+handles.nbinmax = nbinmax;
+handles.example = example;
+handles.exacounter = 0;
+handles.listname = [];
+handles.chanlocs = chanlocs;
+handles.bindescr = bindescr;
+
+%
+% Name & version
+%
+erplab_studio_default_values;
+version = erplabstudiover;
+
+set(handles.gui_chassis,'Name', ['EStudio ' version ' - Bin Operation GUI'])
+
+%formulas = erpworkingmemory('binformulas');
+
+label1 = 'Send file rather than individual equations';
+label2 = '(creates compact history)';
+set(handles.checkbox_sendfile2history, 'string',[label1 ' ' label2]);
+set(handles.listbox_bin,'String', listb)
+
+%
+% Gui memory
+%
+binopGUI = erpworkingmemory('binopGUI');
+
+if isempty(binopGUI)
+ set(handles.button_recursive,'Value', 1); % default is Modify existing ERPset (recursive updating)
+ set(handles.button_savelist, 'Enable','off')
+
+ %
+ % File List
+ %
+ set(handles.edit_filelist,'String','');
+ set(handles.checkbox_sendfile2history,'Value',0)
+else
+ if binopGUI.emode==0
+ set(handles.button_recursive,'Value', 1);
+ set(handles.button_no_recu,'Value', 0);
+ else
+ set(handles.button_recursive,'Value', 0);
+ set(handles.button_no_recu,'Value', 1);
+ end
+ if binopGUI.hmode==0
+ set(handles.checkbox_sendfile2history,'Value', 0);
+ else
+ set(handles.checkbox_sendfile2history,'Value', 1);
+ end
+ set(handles.edit_filelist,'String', binopGUI.listname );
+end
+if isempty(formulas)
+ set(handles.editor,'String','');
+else
+ if iscell(formulas)
+ set(handles.editor, 'String', formulas)
+ else
+ try
+ fid_formula = fopen( formulas );
+
+ formcell = textscan(fid_formula, '%s','delimiter', '\r');
+ formulas = char(formcell{:});
+ compacteditor(hObject, eventdata, handles);
+ set(handles.editor,'String',formulas);
+ fclose(fid_formula);
+ set(handles.button_savelist, 'Enable','on')
+ catch
+ end
+ end
+end
+%wbmsgon = erpworkingmemory('wbmsgon');
+if isempty(wbmsgon) || wbmsgon==0
+ set(handles.bwarning,'Value', 0)
+elseif wbmsgon==1
+ set(handles.bwarning,'Value', 1)
+else
+ set(handles.bwarning,'Value', 1)
+end
+
+%
+% Color GUI
+%
+handles = painterplabstudio(handles);
+
+%
+% Set font size
+%
+handles = setfonterplabestudio(handles);
+
+% Update handles structure
+guidata(hObject, handles);
+
+% help
+helpbutton
+
+drawnow
+uiwait(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+function varargout = binoper_studioGUI_OutputFcn(hObject, eventdata, handles)
+% Get default command line output from handles structure
+
+varargout{1} = handles.output;
+
+% The figure can be deleted now
+delete(handles.gui_chassis);
+pause(0.5)
+
+%--------------------------------------------------------------------------
+function editor_Callback(hObject, eventdata, handles)
+
+compacteditor(hObject, eventdata, handles);
+
+handles.listname = [];
+% Update handles structure
+guidata(hObject, handles);
+
+%--------------------------------------------------------------------------
+function editor_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function pushbutton_help_Callback(hObject, eventdata, handles)
+% doc pop_binoperator
+web https://github.com/lucklab/erplab/wiki/ERP-Bin-Operations -browser
+
+%--------------------------------------------------------------------------
+function RUN_Callback(hObject, eventdata, handles)
+
+listname = handles.listname;
+compacteditor(hObject, eventdata, handles);
+formulalist = get(handles.editor,'String');
+wbmsgon = get(handles.bwarning,'Value');
+
+if strcmp(formulalist,'')
+ msgboxText = 'You have not yet written a formula!';
+ title = 'ERPLAB: binoperGUI few inputs';
+ errorfound(msgboxText, title);
+ return
+end
+if size(formulalist,2)>256
+ msgboxText = ['Formulas length exceed 256 characters.\n'...
+ 'Be sure to press [Enter] after you have entered each formula.'];
+ title = 'ERPLAB: binoperGUI few inputs';
+ errorfound(sprintf(msgboxText), title);
+ return
+end
+
+%
+% Check formulas
+%
+if get(handles.button_recursive,'Value')
+ editormode = 0;
+else
+ editormode = 1;
+end
+[option, recall, goeson] = checkformulas(cellstr(formulalist), 'binoperGUI', editormode);
+if goeson==0
+ return
+end
+if isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==1
+ BackERPLABcolor = [ 1 1 0];
+ question = ['Equations at editor window have not been saved yet.\n'...
+ 'What would you like to do?'];
+ title = 'WARNING: Save List of edited bins';
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor)
+ button = questdlg(sprintf(question), title,'Save and run','Run without saving', 'Cancel','Run without saving');
+ set(0,'DefaultUicontrolBackgroundColor',oldcolor)
+
+ if strcmpi(button,'Save and run')
+ fullname = savelist(hObject, eventdata, handles);
+ listname = fullname;
+ handles.output = {listname, wbmsgon}; % sent filenam string)
+ elseif strcmpi(button,'Run without saving')
+ handles.output = {cellstr(formulalist), wbmsgon}; % sent like a cell string (with formulas)
+ elseif strcmpi(button,'Cancel') || strcmpi(button,'')
+ handles.output = [];
+ handles.listname = [];
+ % Update handles structure
+ guidata(hObject, handles);
+ return
+ end
+elseif isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==0
+ handles.output = {cellstr(formulalist), wbmsgon}; % sent like a cell string (with formulas)
+elseif ~isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==1
+ handles.output = {listname, wbmsgon}; % sent filename string
+elseif ~isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==0
+ handles.output = {cellstr(formulalist), wbmsgon}; % sent like a cell string (with formulas)
+end
+
+% erpworkingmemory('binformulas', formulalist);
+%
+% memory for Gui
+%
+binopGUI.emode = editormode;
+binopGUI.hmode = get(handles.checkbox_sendfile2history,'Value');
+binopGUI.listname = listname;
+erpworkingmemory('binopGUI', binopGUI);
+
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+function cancel_Callback(hObject, eventdata, handles)
+handles.output = [];
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+function eraser_Callback(hObject, eventdata, handles)
+set(handles.editor, 'String','')
+handles.output = [];
+disp('Formulas were erased.')
+set(handles.button_savelist, 'Enable','off')
+
+handles.listname = [];
+% Update handles structure
+guidata(hObject, handles);
+
+%--------------------------------------------------------------------------
+function help_Callback(hObject, eventdata, handles)
+
+fprintf('\n\n\n\n\n')
+help pop_binoperator
+
+%--------------------------------------------------------------------------
+function button_saveaslist_Callback(hObject, eventdata, handles)
+compacteditor(hObject, eventdata, handles);
+fulltext = strtrim(get(handles.editor,'String'));
+
+if size(fulltext,2)>256
+ msgboxText = ['Formulas length exceed 256 characters.\n'...
+ 'Be sure to press [Enter] after you have entered each formula.'];
+ title = 'ERPLAB: binoperGUI few inputs';
+ errorfound(sprintf(msgboxText), title);
+ return
+end
+if ~strcmp(fulltext,'')
+ fullname = savelist(hObject, eventdata, handles);
+ if isempty(fullname)
+ return
+ end
+ set(handles.edit_filelist, 'String', fullname )
+ set(handles.button_savelist, 'Enable', 'on')
+ handles.listname = fullname;
+ % Update handles structure
+ guidata(hObject, handles);
+else
+ set(handles.button_saveaslist,'Enable','off')
+ msgboxText = 'You have not yet written a formula!';
+ title = 'ERPLAB: binoperGUI few inputs';
+ errorfound(msgboxText, title);
+ set(handles.button_saveaslist,'Enable','on')
+ return
+end
+
+%--------------------------------------------------------------------------
+function button_loadlist_Callback(hObject, eventdata, handles)
+
+[filename, filepath] = uigetfile({'*.txt';'*.*'},'Select a formulas-file');
+if isequal(filename,0)
+ disp('User selected Cancel')
+ return
+else
+ fullname = fullfile(filepath, filename);
+ disp(['pop_binoperation(): For formulas-file, user selected ', fullname])
+end
+set(handles.edit_filelist,'String',fullname);
+fid_formula = fopen( fullname );
+try
+ formcell = textscan(fid_formula, '%s','delimiter', '\r');
+ formulas = char(formcell{:});
+catch
+ serr = lasterror;
+ msgboxText = ['Please, check your file:\n '...
+ fullname '\n'...
+ serr.message];
+ title = 'ERPLAB: pop_binoperation() error:';
+ errorfound(sprintf(msgboxText), title);
+ return
+end
+if size(formulas,2)>256
+ msgboxText = ['Formulas length exceed 256 characters.\n'...
+ 'Be sure to press [Enter] after you have entered each formula.'];
+ title = 'ERPLAB: binoperGUI few inputs';
+ errorfound(sprintf(msgboxText), title);
+ return
+end
+
+compacteditor(hObject, eventdata, handles);
+set(handles.editor,'String',formulas);
+fclose(fid_formula);
+set(handles.button_savelist, 'Enable','on')
+handles.listname = fullname;
+
+% Update handles structure
+guidata(hObject, handles);
+
+%--------------------------------------------------------------------------
+function listbox_bin_Callback(hObject, eventdata, handles)
+
+numbin = get(hObject, 'Value');
+if isempty(numbin)
+ return
+end
+linet = get(handles.editor, 'Value');
+if linet == 0
+ linet = 1;
+end
+formulas = cellstr(get(handles.editor, 'String'));
+formulas{linet} = [formulas{linet} 'b' num2str(numbin)];
+set(handles.editor, 'String', char(formulas));
+
+%--------------------------------------------------------------------------
+function listbox_bin_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function button_example_Callback(hObject, eventdata, handles)
+nbinmax = handles.nbinmax;
+example = handles.example;
+exacounter = handles.exacounter;
+exacounter = exacounter + 1;
+
+if get(handles.button_no_recu,'Value')
+ prechar = 'n';
+else
+ prechar = '';
+end
+
+text = cellstr(get(handles.editor, 'String'));
+
+if isempty([text{:}]) || exacounter>length(example)
+ exacounter = 1;
+end
+if length(text)==1 && strcmp(text{1}, '')
+ exacurr = char(regexprep(example{exacounter},'\$',num2str(nbinmax+exacounter)));
+ text{1} = [prechar exacurr];
+else
+ exacurr = char(regexprep(example{exacounter},'\$',num2str(nbinmax+exacounter)));
+ text{end+1} = [prechar exacurr];
+end
+
+set(handles.editor, 'String', char(text));
+handles.exacounter = exacounter;
+% Update handles structure
+guidata(hObject, handles);
+
+%--------------------------------------------------------------------------
+function fullname = savelist(hObject, eventdata, handles)
+fulltext = char(get(handles.editor,'String'));
+if isempty(fulltext)
+ return
+end
+fullnamepre = get(handles.edit_filelist,'String');
+
+%
+% Save OUTPUT file
+%
+[filename, filepath, filterindex] = uiputfile({'*.txt';'*.dat';'*.*'},'Save formulas-file as', fullnamepre);
+
+if isequal(filename,0)
+ disp('User selected Cancel')
+ fullname = [];
+ return
+else
+ [px, fname, ext] = fileparts(filename);
+
+ if strcmp(ext,'')
+
+ if filterindex==1 || filterindex==3
+ ext = '.txt';
+ else
+ ext = '.dat';
+ end
+ end
+
+ fname = [ fname ext];
+ fullname = fullfile(filepath, fname);
+ fid_list = fopen( fullname , 'w');
+
+ for i=1:size(fulltext,1)
+ fprintf(fid_list,'%s\n', fulltext(i,:));
+ end
+
+ fclose(fid_list);
+ set(handles.button_savelist, 'Enable','on')
+end
+
+%--------------------------------------------------------------------------
+function compacteditor(hObject, eventdata, handles)
+texteditor = strtrim(get(handles.editor,'String'));
+if isempty(texteditor)
+ return
+end
+
+formul = cellstr(texteditor);
+nfl = length(formul);
+k = 1;
+formulalist = cell(1);
+
+for i=1:nfl
+ if ~strcmp(formul{i},'')
+ formulalist{k} = formul{i};
+ k = k+1;
+ end
+end
+
+formulalist = strtrimx(formulalist);
+set(handles.editor,'String', char(formulalist));
+
+%--------------------------------------------------------------------------
+function button_savelist_Callback(hObject, eventdata, handles)
+compacteditor(hObject, eventdata, handles);
+fulltext = strtrim(get(handles.editor,'String'));
+if size(fulltext,2)>256
+ msgboxText = ['Formulas length exceed 256 characters.\n'...
+ 'Be sure to press [Enter] after you have entered each formula.'];
+ title = 'ERPLAB: binoperGUI few inputs';
+ errorfound(sprintf(msgboxText), title);
+ return
+end
+if ~strcmp(fulltext,'')
+ fullname = get(handles.edit_filelist, 'String');
+ if ~strcmp(fullname,'')
+
+ fid_list = fopen( fullname , 'w');
+
+ for i=1:size(fulltext,1)
+ fprintf(fid_list,'%s\n', fulltext(i,:));
+ end
+
+ fclose(fid_list);
+ handles.listname = fullname;
+ % Update handles structure
+ guidata(hObject, handles);
+ disp(['Saving equation list at ' fullname ' '])
+ else
+ button_saveaslist_Callback(hObject, eventdata, handles)
+ return
+ end
+else
+ set(handles.button_saveaslist,'Enable','off')
+ msgboxText = 'You have not yet written a formula!';
+ title = 'ERPLAB: binoperGUI few inputs';
+ errorfound(msgboxText, title);
+ set(handles.button_saveaslist,'Enable','on')
+ return
+end
+
+%--------------------------------------------------------------------------
+function checkbox_sendfile2history_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function edit_filelist_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function edit_filelist_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function button_clearfile_Callback(hObject, eventdata, handles)
+set(handles.edit_filelist,'String','');
+set(handles.button_savelist, 'Enable', 'off')
+
+%--------------------------------------------------------------------------
+function button_recursive_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+ set(handles.button_no_recu,'Value',0)
+ val = testsyntaxtype(hObject, eventdata, handles, 'recu');
+
+ if val==0;
+ set(handles.button_recursive, 'Value', 0)
+ set(handles.button_no_recu, 'Value', 1)
+ end
+
+ %%% handles = editorbackup(hObject, eventdata, handles);
+ %%% Update handles structure
+ %%guidata(hObject, handles);
+else
+ set(hObject,'Value',1)
+end
+
+% % % if get(hObject,'Value')==0
+% % % set(hObject,'Value',1)
+% % % else
+% % % set(handles.button_no_recu,'Value',0)
+% % % end
+
+%--------------------------------------------------------------------------
+function button_no_recu_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+ set(handles.button_recursive,'Value',0)
+ val = testsyntaxtype(hObject, eventdata, handles, 'norecu');
+ if val==0
+ set(handles.button_recursive, 'Value', 1)
+ set(handles.button_no_recu, 'Value', 0)
+ end
+ %%% handles = editorbackup(hObject, eventdata, handles);
+ %%% Update handles structure
+ %%%guidata(hObject, handles);
+else
+ set(hObject,'Value',1)
+end
+
+% % % if get(hObject,'Value')==0
+% % % set(hObject,'Value',1)
+% % % else
+% % % set(handles.button_recursive,'Value',0)
+% % % end
+
+%--------------------------------------------------------------------------
+function val = testsyntaxtype(hObject, eventdata, handles, whocall)
+val = 1;
+formulaArray = get(handles.editor,'String');
+
+if isempty(formulaArray)
+ return
+else
+ formulaArray = strtrim(cellstr(formulaArray));
+end
+nformulas = length(formulaArray);
+[expspliter parts] = regexp(formulaArray, '=','match','split');
+ask4fix = 1;
+wantfix = 0;
+newnumbin = 1;
+
+for t=1:nformulas
+ fcomm = formulaArray{t};
+ tokcommentb = regexpi(fcomm, '^#', 'match'); % comment symbol (June 3, 2013)
+
+ if isempty(tokcommentb) % skip comment symbol
+ pleft = regexpi(parts{t}{1}, '(\s*nb[in]*\d+)', 'tokens');
+ plcom = regexpi(parts{t}{1}, '(\s*b[in]*\d+)', 'tokens');
+
+ if isempty(pleft) && ~isempty(plcom) && strcmpi(whocall,'norecu')
+ if ask4fix
+ BackERPLABcolor = [1 0.9 0.3]; % yellow
+ question = ['For non recursive mode, left side of equation\nmust be define as a new bin.\n'...
+ 'For instance, nbin1 = ...\n\n'...
+ 'Do you want that ERPLAB corrects the syntax for you?'];
+ title = 'WARNING: Syntax is not proper for non recursive mode';
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor)
+ button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes');
+ set(0,'DefaultUicontrolBackgroundColor',oldcolor)
+
+ if strcmpi(button,'Yes')
+ ask4fix = 0;
+ wantfix = 1;
+ elseif strcmpi(button,'Cancel')
+ val = 0; % cancel
+ break
+ else
+ ask4fix = 0;
+ wantfix = 0;
+ end
+ %else
+ % wantfix =1;
+ end
+ elseif ~isempty(pleft) && strcmpi(whocall,'recu')
+ if ask4fix
+ BackERPLABcolor = [1 0.9 0.3]; % yellow
+ question = ['For recursive mode, left side of equation cannot\nbe define as a new bin.\n'...
+ 'For instance, you must write bin1 = ...\n\n'...
+ 'Do you want that ERPLAB corrects the syntax for you?'];
+ title = 'WARNING: Syntax is not proper for recursive mode';
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor)
+ button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes');
+ set(0,'DefaultUicontrolBackgroundColor',oldcolor)
+
+ if strcmpi(button,'Yes')
+ ask4fix = 0;
+ wantfix =1;
+ elseif strcmpi(button,'Cancel')
+ val = 0; % cancel
+ break
+ else
+ ask4fix = 0;
+ wantfix = 0;
+ end
+ %else
+ % wantfix =1;
+ end
+ %else
+ % wantfix = 0;
+
+ end
+ if wantfix && (~isempty(pleft) || ~isempty(plcom))% fixed (June 3, 2013): JLC
+ fprintf('WARNING: equation %s ', formulaArray{t})
+ if strcmpi(whocall,'recu') % for recursive mode delete the n in nch
+ formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*','','ignorecase')), strtrim(parts{t}{2}));
+ else
+ formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*b(\D*)(\d*)',['nb$1' num2str(newnumbin)],'ignorecase')), strtrim(parts{t}{2}));
+ newnumbin = newnumbin+1;
+ end
+ fprintf('was changed to equation %s \n', formulaArray{t})
+ end
+ end
+end
+if val==1
+ set(handles.editor,'String', char(formulaArray));
+end
+
+%--------------------------------------------------------------------------
+function bwarning_Callback(hObject, eventdata, handles)
+% if get(hObject,'Value')
+% %
+% % Gui memory
+% %
+% erpworkingmemory('wbmsgon', 1);
+% else
+% %
+% % Gui memory
+% %
+% erpworkingmemory('wbmsgon', 0);
+% end
+
+%--------------------------------------------------------------------------
+function pushbutton_contraipsi_assistant_Callback(hObject, eventdata, handles)
+
+chanlocs = handles.chanlocs;
+bindescr = handles.bindescr;
+
+%
+% Call GUI for assistant
+%
+formcell = contraipsiGUI(chanlocs, bindescr);
+if isempty(formcell)
+ disp('User selected Cancel')
+ return
+end
+formulas = char(formcell{:});
+set(handles.editor,'String',formulas);
+set(handles.button_recursive,'Value',0);
+set(handles.button_no_recu,'Value',1);
+
+
+%--------------------------------------------------------------------------
+function bwarning_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function cancel_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function RUN_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function panel1_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function button_example_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function eraser_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function help_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function button_loadlist_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function button_savelist_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function button_saveaslist_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function button_clearfile_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function button_recursive_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function button_no_recu_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function checkbox_sendfile2history_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function pushbutton_export_bin_list_Callback(hObject, eventdata, handles)
+list_of_bins = get(handles.listbox_bin,'String');
+nlob = length(list_of_bins);
+for i=1:nlob
+ fprintf('%s\n',list_of_bins{i});
+end
+fprintf('\n\nEnd of list.\n\n')
+
+%--------------------------------------------------------------------------
+function gui_chassis_CloseRequestFcn(hObject, eventdata, handles)
+if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting')
+ % The GUI is still in UIWAIT, us UIRESUME
+ uiresume(handles.gui_chassis);
+else
+ % The GUI is no longer waiting, just close it
+ delete(handles.gui_chassis);
+end
diff --git a/studio_functions/GUIs/ERP Tab/csd_chan_locations.fig b/studio_functions/GUIs/ERP Tab/csd_chan_locations.fig
new file mode 100755
index 00000000..6c7bbb55
Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/csd_chan_locations.fig differ
diff --git a/studio_functions/GUIs/ERP Tab/csd_chan_locations.m b/studio_functions/GUIs/ERP Tab/csd_chan_locations.m
new file mode 100755
index 00000000..b58d4c8b
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/csd_chan_locations.m
@@ -0,0 +1,338 @@
+function varargout = csd_chan_locations(varargin)
+% CSD_CHAN_LOCATIONS MATLAB code for csd_chan_locations.fig
+% CSD_CHAN_LOCATIONS, by itself, creates a new CSD_CHAN_LOCATIONS or raises the existing
+% singleton*.
+%
+% H = CSD_CHAN_LOCATIONS returns the handle to a new CSD_CHAN_LOCATIONS or the handle to
+% the existing singleton*.
+%
+% CSD_CHAN_LOCATIONS('CALLBACK',hObject,eventData,handles,...) calls the local
+% function named CALLBACK in CSD_CHAN_LOCATIONS.M with the given input arguments.
+%
+% CSD_CHAN_LOCATIONS('Property','Value',...) creates a new CSD_CHAN_LOCATIONS or raises
+% the existing singleton*. Starting from the left, property value pairs are
+% applied to the GUI before csd_chan_locations_OpeningFcn gets called. An
+% unrecognized property name or invalid value makes property application
+% stop. All inputs are passed to csd_chan_locations_OpeningFcn via varargin.
+%
+% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
+% instance to run (singleton)".
+%
+% See also: GUIDE, GUIDATA, GUIHANDLES
+
+% Edit the above text to modify the response to help csd_chan_locations
+
+% Last Modified by GUIDE v2.5 10-Aug-2022 21:02:42
+
+% Begin initialization code - DO NOT EDIT
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @csd_chan_locations_OpeningFcn, ...
+ 'gui_OutputFcn', @csd_chan_locations_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+% End initialization code - DO NOT EDIT
+
+% --- Executes just before csd_chan_locations is made visible.
+function csd_chan_locations_OpeningFcn(hObject, eventdata, handles, varargin)
+% This function has no output args, see OutputFcn.
+% hObject handle to figure
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+% varargin command line arguments to csd_chan_locations (see VARARGIN)
+
+% Choose default command line output for csd_chan_locations
+handles.output = hObject;
+
+%
+% Color GUI
+%
+%handles = painterplab(handles);
+
+%
+% Set font size
+%
+%handles = setfonterplab(handles);
+
+% initialise with defaults
+handles.mcont = 4;
+handles.smoothl = 0.00001;
+handles.headrad = 10;
+
+handles.csdsave = 1;
+
+handles.output = [];
+
+
+axes(hObject)
+
+path_to_pic = which('CSD_elec_plot.png');
+if numel(path_to_pic) ~= 0 % iff a path to the pic exists, show it
+ imshow('CSD_elec_plot.png')
+end
+
+
+% Update handles structure
+guidata(hObject, handles);
+
+
+
+
+
+% help
+% helpbutton
+
+% UIWAIT makes csd_chan_locations wait for user response (see UIRESUME)
+uiwait(handles.figure1);
+
+
+% --- Outputs from this function are returned to the command line.
+function varargout = csd_chan_locations_OutputFcn(hObject, eventdata, handles)
+% varargout cell array for returning output args (see VARARGOUT);
+% hObject handle to figure
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Get default command line output from handles structure
+varargout{1} = handles.output;
+% The figure can be deleted now
+delete(handles.figure1);
+pause(0.1)
+
+
+
+
+
+% --- Executes on button press in generate.
+function generate_Callback(hObject, eventdata, handles)
+% hObject handle to generate (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Sanity-check output
+% if isa(handles.mcont,'double') ~= 1 || isnan(handles.mcont)
+% ertext = 'mcont was set to 4';
+% disp(ertext)
+% handles.mcont = 4;
+% end
+%
+% % beep
+% % disp('X was not a Y');
+%
+% handles.output = [];
+
+
+
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.figure1);
+
+% --- Executes on button press in reset.
+% function reset_Callback(hObject, eventdata, handles)
+% % hObject handle to reset (see GCBO)
+% % eventdata reserved - to be defined in a future version of MATLAB
+% % handles structure with handles and user data (see GUIDATA)
+% web('http://psychophysiology.cpmc.columbia.edu/software/CSDtoolbox/index.html','-browser');
+
+
+
+% --------------------------------------------------------------------
+function initialize_gui(fig_handle, handles, isreset)
+% If the metricdata field is present and the reset flag is false, it means
+% we are we are just re-initializing a GUI by calling it from the cmd line
+% while it is up. So, bail out as we dont want to reset the data.
+
+
+
+
+
+% Update handles structure
+guidata(handles.figure1, handles);
+
+
+
+% function mcont_Callback(hObject, eventdata, handles)
+% % hObject handle to mcont (see GCBO)
+% % eventdata reserved - to be defined in a future version of MATLAB
+% % handles structure with handles and user data (see GUIDATA)
+%
+% % Hints: get(hObject,'String') returns contents of mcont as text
+% % str2double(get(hObject,'String')) returns contents of mcont as a double
+% mcont = str2double(get(hObject,'String'));
+%
+% % We don't want to return the new value if the input was not a double
+% if isnan(mcont)
+% beep
+% disp('Please ensure that the input was a number.');
+% set(hObject,'String','4');
+% else
+% % input seems valid
+% % Save the new value
+% handles.mcont = mcont;
+% guidata(hObject,handles)
+% end
+
+
+
+% --- Executes during object creation, after setting all properties.
+function mcont_CreateFcn(hObject, eventdata, handles)
+% hObject handle to mcont (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+% Hint: edit controls usually have a white background on Windows.
+% See ISPC and COMPUTER.
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+% --- Executes during object creation, after setting all properties.
+function uipanel1_CreateFcn(hObject, eventdata, handles)
+% hObject handle to uipanel1 (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+
+
+% function lambdabox_Callback(hObject, eventdata, handles)
+% % hObject handle to lambdabox (see GCBO)
+% % eventdata reserved - to be defined in a future version of MATLAB
+% % handles structure with handles and user data (see GUIDATA)
+%
+% % Hints: get(hObject,'String') returns contents of lambdabox as text
+% % str2double(get(hObject,'String')) returns contents of lambdabox as a double
+% smoothl = str2double(get(hObject,'String'));
+%
+% % We don't want to save the new value if the input was not a double
+% if isnan(smoothl)
+% beep
+% disp('Please ensure that the input was a number.');
+% set(hObject,'String','0.00001');
+% else
+% % input seems valid
+% % Save the new value
+% handles.smoothl = smoothl;
+% guidata(hObject,handles)
+% end
+
+
+
+% --- Executes during object creation, after setting all properties.
+function lambdabox_CreateFcn(hObject, eventdata, handles)
+% hObject handle to lambdabox (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+% Hint: edit controls usually have a white background on Windows.
+% See ISPC and COMPUTER.
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+
+% function headradbox_Callback(hObject, eventdata, handles)
+% % hObject handle to headradbox (see GCBO)
+% % eventdata reserved - to be defined in a future version of MATLAB
+% % handles structure with handles and user data (see GUIDATA)
+%
+% % Hints: get(hObject,'String') returns contents of headradbox as text
+% % str2double(get(hObject,'String')) returns contents of headradbox as a double
+% headrad = str2double(get(hObject,'String'));
+%
+% % We don't want to return the new value if the input was not a double
+% if isnan(headrad)
+% beep
+% disp('Please ensure that the input was a number.');
+% set(hObject,'String','10');
+% else
+% % input seems valid
+% % Save the new value
+% handles.headrad = headrad;
+% guidata(hObject,handles)
+% end
+
+
+% --- Executes during object creation, after setting all properties.
+function headradbox_CreateFcn(hObject, eventdata, handles)
+% hObject handle to headradbox (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+% Hint: edit controls usually have a white background on Windows.
+% See ISPC and COMPUTER.
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+
+
+
+
+
+% --- Executes on button press in savenew.
+function savenew_Callback(hObject, eventdata, handles)
+% hObject handle to savenew (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Hint: get(hObject,'Value') returns toggle state of savenew
+csdsave = get(hObject,'Value');
+% Save the new value
+handles.csdsave = 1;
+guidata(hObject,handles)
+
+
+% --- Executes when user attempts to close figure1.
+function figure1_CloseRequestFcn(hObject, eventdata, handles)
+% hObject handle to figure1 (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+handles.output = [handles.mcont handles.smoothl handles.headrad handles.csdsave];
+
+
+if isequal(get(handles.figure1, 'waitstatus'), 'waiting')
+ %The GUI is still in UIWAIT, us UIRESUME
+ handles.output = '';
+ %Update handles structure
+ guidata(hObject, handles);
+ uiresume(handles.figure1);
+else
+ % The GUI is no longer waiting, just close it
+ delete(handles.figure1);
+end
+
+
+% --- Executes during object creation, after setting all properties.
+function bigheadplot_CreateFcn(hObject, eventdata, handles)
+% hObject handle to bigheadplot (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+% Hint: place code in OpeningFcn to populate bigheadplot
+
+axes(hObject)
+
+path_to_pic = which('CSD_elec_plot.png');
+if numel(path_to_pic) ~= 0 % iff a path to the pic exists, show it
+ imshow('CSD_elec_plot.png')
+end
+
+
+% % --- Executes on button press in pushbutton_help.
+% function pushbutton_help_Callback(hObject, eventdata, handles)
+% % hObject handle to pushbutton_help (see GCBO)
+% % eventdata reserved - to be defined in a future version of MATLAB
+% % handles structure with handles and user data (see GUIDATA)
+% web https://github.com/lucklab/erplab/wiki/Current-Source-Density-(CSD)-tool -browser
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_CSD_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_CSD_GUI.m
new file mode 100755
index 00000000..98d47310
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_CSD_GUI.m
@@ -0,0 +1,306 @@
+%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com
+%Center for Mind and Brain
+%University of California, Davis
+%Davis, CA, USA
+%Feb. 2022
+
+% ERPLAB Studio
+
+function varargout = f_ERP_CSD_GUI(varargin)
+global observe_ERPDAT;
+% addlistener(observe_ERPDAT,'ALLERP_change',@allErpChanged);
+% addlistener(observe_ERPDAT,'ERP_change',@onErpChanged);
+% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange);
+addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged);
+
+
+gui_erp_CSD = struct();
+
+%-----------------------------Name the title----------------------------------------------
+% global ERP_CSD_gui;
+[version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+if nargin == 0
+ fig = figure(); % Parent figure
+ ERP_CSD_gui = uiextras.BoxPanel('Parent', fig, 'Title', 'Convert Voltage to CSD', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel
+elseif nargin == 1
+ ERP_CSD_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Convert Voltage to CSD', 'Padding', 5,'BackgroundColor',ColorB_def);
+else
+ ERP_CSD_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Convert Voltage to CSD', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def);
+end
+
+%-----------------------------Draw the panel-------------------------------------
+try
+ FonsizeDefault = varargin{2};
+catch
+ FonsizeDefault = [];
+end
+if isempty(FonsizeDefault)
+ FonsizeDefault = f_get_default_fontsize();
+end
+drawui_erp_bin_operation(FonsizeDefault);
+varargout{1} = ERP_CSD_gui;
+
+ function drawui_erp_bin_operation(FonsizeDefault)
+ FontSize_defualt = FonsizeDefault;
+
+ if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded')
+ Enable_label = 'off';
+ else
+ Enable_label = 'on';
+ end
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+ %%--------------------channel and bin setting----------------------
+ gui_erp_CSD.DataSelBox = uiextras.VBox('Parent', ERP_CSD_gui,'BackgroundColor',ColorB_def);
+
+ %%Display the lacations of electrodes: may use other function to
+ %%replace current one.
+ % gui_erp_CSD.erp_h_erp = uicontrol('Style','radiobutton','Parent', gui_erp_CSD.erp_history_title,'String','ERP','callback',@ERP_H_ERP,'Value',0); % 2F
+ gui_erp_CSD.erp_history_table = uiextras.HBox('Parent', gui_erp_CSD.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_CSD.erp_h_erp = axes( 'Parent', gui_erp_CSD.erp_history_table, 'ActivePositionProperty', 'Position');
+ set( gui_erp_CSD.erp_h_erp,'xticklabel', [], 'yticklabel', []);
+
+
+ %%Parameters
+ gui_erp_CSD.sif_title = uiextras.HBox('Parent', gui_erp_CSD.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_CSD.sif_text = uicontrol('Style','text','Parent', gui_erp_CSD.sif_title,...
+ 'String','Spline interpolation flexibility m-constant value (4 is recommended)','FontSize',FontSize_defualt,'Max',10,'BackgroundColor',ColorB_def); % 2F
+
+ gui_erp_CSD.sif_num = uicontrol('Style','edit','Parent', gui_erp_CSD.sif_title,...
+ 'String','4','FontSize',FontSize_defualt,'Enable',Enable_label,'callback',@csd_sif); % 2F
+ set(gui_erp_CSD.sif_title,'Sizes',[210,50]);
+
+ gui_erp_CSD.scl_title = uiextras.HBox('Parent', gui_erp_CSD.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_CSD.scl_text = uicontrol('Style','text','Parent', gui_erp_CSD.scl_title,...
+ 'String','Smoothing constant lambda (0.00001 is recommended)','FontSize',FontSize_defualt,'Max',10,'BackgroundColor',ColorB_def); % 2F
+
+ gui_erp_CSD.scl_num = uicontrol('Style','edit','Parent', gui_erp_CSD.scl_title,...
+ 'String','0.00001','FontSize',FontSize_defualt,'Enable',Enable_label,'callback',@csd_scl); % 2F
+ set(gui_erp_CSD.scl_title,'Sizes',[210,50]);
+
+ gui_erp_CSD.hr_title = uiextras.HBox('Parent', gui_erp_CSD.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_CSD.hr_text = uicontrol('Style','text','Parent', gui_erp_CSD.hr_title,...
+ 'String','Head radius CSD rescaling values (10cm is recommended)','FontSize',FontSize_defualt,'Max',10,'BackgroundColor',ColorB_def); % 2F
+
+ gui_erp_CSD.hr_num = uicontrol('Style','edit','Parent', gui_erp_CSD.hr_title,...
+ 'String','10','FontSize',FontSize_defualt,'Enable',Enable_label,'callback',@csd_hr); % 2F
+ set(gui_erp_CSD.hr_title,'Sizes',[210,50]);
+
+
+ %%-----------------Run---------------------------------------------
+ gui_erp_CSD.run_title = uiextras.HBox('Parent', gui_erp_CSD.DataSelBox,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_CSD.run_title);
+ gui_erp_CSD.run = uicontrol('Style','pushbutton','Parent',gui_erp_CSD.run_title,...
+ 'String','Run','callback',@apply_run,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F
+ uiextras.Empty('Parent', gui_erp_CSD.run_title);
+ set(gui_erp_CSD.run_title,'Sizes',[85 90 85]);
+
+ gui_erp_CSD.location_title = uiextras.HBox('Parent', gui_erp_CSD.DataSelBox,'BackgroundColor',ColorB_def);
+ uicontrol('Style','pushbutton','Parent',gui_erp_CSD.location_title,...
+ 'String','?','callback',@tool_link,'FontSize',16,'BackgroundColor',[1 1 1],'Max',10); % 2F
+ gui_erp_CSD.location = uicontrol('Style','pushbutton','Parent',gui_erp_CSD.location_title,...
+ 'String','Expand Locations','callback',@CSD_undock_loct,'FontSize',FontSize_defualt,'BackgroundColor',[1 1 1],'Enable',Enable_label); % 2F
+ set(gui_erp_CSD.DataSelBox,'Sizes',[230,40,40,40,30,30]);
+ end
+
+
+
+%%**************************************************************************%%
+%%--------------------------Sub function------------------------------------%%
+%%**************************************************************************%%
+
+ function CSD_undock_loct(~,~)
+ %%https://github.com/lucklab/erplab/wiki/Current-Source-Density-(CSD)-tool -browser
+ csd_chan_locations;
+ end
+%%-------------------Setting value for Spline interpolation flexibility m-constant value----------------
+ function csd_sif(source,~)
+ mcont = str2double(source.String);
+ if isnan(mcont)
+ gui_erp_CSD.sif_num.String=4;
+ beep;
+ msgboxText = ['Convert voltage to CSD - Please ensure that the input was a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ else
+ % input seems valid
+ % Save the new value
+ gui_erp_CSD.sif_num.String = mcont;
+ end
+ end
+
+%%-------------------Setting value for Smoothing constant lambda---------------------------------------
+ function csd_scl(source,~)
+ mcont = str2double(source.String);
+ if isnan(mcont)
+ gui_erp_CSD.scl_num.String=4;
+ beep;
+ msgboxText = ['Convert voltage to CSD - Please ensure that the input was a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ else
+ % input seems valid
+ % Save the new value
+ gui_erp_CSD.scl_num.String = mcont;
+ end
+ end
+
+%%-------------------setting Head radius CSD rescaling values---------------------------------------
+ function csd_hr(source,~)
+ mcont = str2double(source.String);
+
+ if isnan(mcont)
+ gui_erp_CSD.hr_num.String=4;
+ beep;
+ msgboxText = ['Convert voltage to CSD - Please ensure that the input was a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ else
+ % input seems valid
+ % Save the new value
+ gui_erp_CSD.hr_num.String = mcont;
+ end
+ end
+
+%%---------------------CSD tool link-------------------------------------
+ function tool_link(~,~)
+ web('https://github.com/lucklab/erplab/wiki/Current-Source-Density-(CSD)-tool','-browser');
+ end
+%%---------------------Run-------------------------------------------------
+ function apply_run(~,~)
+
+ csd_param(1) = str2double(gui_erp_CSD.sif_num.String);
+ csd_param(2) = str2double(gui_erp_CSD.scl_num.String);
+ csd_param(3) = str2double(gui_erp_CSD.hr_num.String);
+ csd_param(4) = 1;
+ erpworkingmemory('csd_param',csd_param);
+ Selectederp_Index= estudioworkingmemory('selectederpstudio');
+ if isempty(Selectederp_Index)
+ Selectederp_Index = observe_ERPDAT.CURRENTERP;
+ if isempty(Selectederp_Index)
+ beep;
+ msgboxText = ['Convert voltage to CSD - No ERPset was selected'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+ %%---------------------Compute CSD for each ERPset----------------
+ try
+ erpworkingmemory('f_ERP_proces_messg','Convert Voltage to CSD');
+ observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started.
+ ALLERPCOM = evalin('base','ALLERPCOM');
+ % Set names of slected ERPsets
+ Save_file_label = 0;
+ Answer = f_ERP_save_multi_file(observe_ERPDAT.ALLERP,Selectederp_Index,'_CSD');
+ if isempty(Answer)
+ beep;
+ disp('User selected Cancel');
+ return;
+ end
+
+ if ~isempty(Answer{1})
+ ALLERP_out = Answer{1};
+ Save_file_label = Answer{2};
+ end
+
+ %%Loop for the selcted ERPsets
+ for Numofselectederp = 1:numel(Selectederp_Index)
+ ERP = ALLERP_out(Selectederp_Index(Numofselectederp));
+ [ERP, ERPCOM] = pop_currentsourcedensity(ERP);
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ %%display the loctions of electrodes for each selected ERPsets.
+ path_to_pic = which('CSD_elec_plot.png');
+ if numel(path_to_pic) ~= 0 % iff a path to the pic exists, show it
+ myImage = imread('CSD_elec_plot.png');
+ imshow(myImage,'Parent',gui_erp_CSD.erp_h_erp);
+ end
+
+ observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP;%%Save the transformed ERPset
+ if Save_file_label==1
+ [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath);
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ end
+ end%%Loop for ERPsets end
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);
+ assignin('base','ALLERPCOM',ALLERPCOM);
+ assignin('base','ERPCOM',ERPCOM);
+ erpworkingmemory('f_ERP_bin_opt',1);
+ try
+ Selected_ERP_afd = [length(observe_ERPDAT.ALLERP)-numel(Selectederp_Index)+1:length(observe_ERPDAT.ALLERP)];
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP)-numel(Selectederp_Index)+1;
+ catch
+ Selected_ERP_afd = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ end
+
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ estudioworkingmemory('selectederpstudio',Selected_ERP_afd);
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Process_messg =2;
+ return;
+ catch
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ Selected_ERP_afd =observe_ERPDAT.CURRENTERP;
+ estudioworkingmemory('selectederpstudio',Selected_ERP_afd);
+ erpworkingmemory('f_ERP_bin_opt',1);
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Process_messg =3;%%
+ end
+ observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+ end
+
+
+%%--------Setting current ERPset/session history based on the current updated ERPset------------
+ function Count_currentERPChanged(~,~)
+ Selectederp_Index= estudioworkingmemory('selectederpstudio');
+ if isempty(Selectederp_Index)
+ Selectederp_Index = observe_ERPDAT.CURRENTERP;
+
+ if isempty(Selectederp_Index)
+ beep;
+ msgboxText = ['Convert voltage to CSD - No ERPset was selected'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ checked_ERPset_Index = S_binchan.checked_ERPset_Index;
+
+ if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded')
+ checked_curr_index = 1;
+ else
+ checked_curr_index = 0;
+ end
+ if isempty(checked_ERPset_Index)
+ checked_ERPset_Index = f_checkerpsets(observe_ERPDAT.ALLERP,Selectederp_Index);
+ end
+ if checked_curr_index || any(checked_ERPset_Index(:))
+ Enable_label = 'off';
+
+ else
+ Enable_label = 'on';
+
+ end
+ gui_erp_CSD.run.Enable = Enable_label;
+ gui_erp_CSD.sif_num.Enable = Enable_label;
+ gui_erp_CSD.scl_num.Enable = Enable_label;
+ gui_erp_CSD.hr_num.Enable = Enable_label;
+ gui_erp_CSD.location.Enable = Enable_label;
+ end
+end
\ No newline at end of file
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_append_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_append_GUI.m
new file mode 100644
index 00000000..d0fa6348
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_append_GUI.m
@@ -0,0 +1,555 @@
+%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com
+%Center for Mind and Brain
+%University of California, Davis
+%Davis, CA, USA
+%Feb. 2022
+
+% ERPLAB Studio
+
+function varargout = f_ERP_append_GUI(varargin)
+global observe_ERPDAT;
+% addlistener(observe_ERPDAT,'ALLERP_change',@allErpChanged);
+% addlistener(observe_ERPDAT,'ERP_change',@onErpChanged);
+% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange);
+addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged);
+% addlistener(observe_ERPDAT,'Process_messg_change',@Process_messg_change);
+
+gui_erp_append = struct();
+
+%-----------------------------Name the title----------------------------------------------
+% global box_erp_history;
+
+try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+catch
+ ColorB_def = [0.95 0.95 0.95];
+end
+
+if nargin == 0
+ fig = figure(); % Parent figure
+ box_erp_history = uiextras.BoxPanel('Parent', fig, 'Title', 'Append ERPsets', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel
+elseif nargin == 1
+ box_erp_history = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Append ERPsets', 'Padding', 5,'BackgroundColor',ColorB_def);
+else
+ box_erp_history = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Append ERPsets', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def);
+end
+
+%-----------------------------Draw the panel-------------------------------------
+try
+ FonsizeDefault = varargin{2};
+catch
+ FonsizeDefault = [];
+end
+if isempty(FonsizeDefault)
+ FonsizeDefault = f_get_default_fontsize();
+end
+drawui_erp_append(FonsizeDefault);
+varargout{1} = box_erp_history;
+
+ function drawui_erp_append(FonsizeDefault)
+ try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+ catch
+ ColorB_def = [0.95 0.95 0.95];
+ end
+ %%--------------------channel and bin setting----------------------
+ gui_erp_append.DataSelBox = uiextras.VBox('Parent', box_erp_history,'BackgroundColor',ColorB_def);
+
+ gui_erp_append.erpappend_select_title = uiextras.HBox('Parent', gui_erp_append.DataSelBox,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_append.erpappend_select_title);
+
+ gui_erp_append.sameerpset = uicontrol('Style','radiobutton','Parent', gui_erp_append.erpappend_select_title,'String','Same as ERPset Panel',...
+ 'callback',@same_to_erpset,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def,'Value',1); % 2F
+
+ gui_erp_append.erpset_custom = uicontrol('Style','radiobutton','Parent',gui_erp_append.erpappend_select_title,'String','Custom',...
+ 'callback',@erpsetcutom,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def,'Value',0);
+ set(gui_erp_append.erpappend_select_title, 'Sizes',[50 145 70]);
+
+ gui_erp_append.erp_append_title = uiextras.HBox('Parent', gui_erp_append.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_append.erp_h_all = uicontrol('Style','text','Parent',gui_erp_append.erp_append_title,'String','ERPsets',...
+ 'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def,'HorizontalAlignment','left'); % 2F
+ gui_erp_append.erpset_edit = uicontrol('Style','edit','Parent', gui_erp_append.erp_append_title,'String',' ',...
+ 'callback',@erpset_edit,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable','off'); % 2F
+ set(gui_erp_append.erp_append_title, 'Sizes',[65 200]);
+
+
+ gui_erp_append.advance_help_title = uiextras.HBox('Parent',gui_erp_append.DataSelBox,'Spacing',1,'BackgroundColor',ColorB_def);
+ % uiextras.Empty('Parent', gui_erp_append.advance_help_title);
+ uicontrol('Style', 'pushbutton','Parent',gui_erp_append.advance_help_title,'String','?','callback',@erpset_append_help,'Enable','on','FontSize',16);
+ % uiextras.Empty('Parent', gui_erp_append.advance_help_title);
+ gui_erp_append.append_advance = uicontrol('Style', 'pushbutton','Parent',gui_erp_append.advance_help_title,...
+ 'String','Advanced','callback',@advance_erpappend,'FontSize',FonsizeDefault);
+ gui_erp_append.append_run = uicontrol('Style', 'pushbutton','Parent',gui_erp_append.advance_help_title,'String','Run',...
+ 'callback',@append_run,'FontSize',FonsizeDefault);
+
+ set(gui_erp_append.DataSelBox,'Sizes',[30 25 30]);
+
+ if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded')
+ Enableflag = 'off';
+ else
+ Enableflag = 'on';
+ end
+ gui_erp_append.erpset_edit.Enable = Enableflag;
+ gui_erp_append.erpset_option.Enable = Enableflag;
+ gui_erp_append.append_advance.Enable = Enableflag;
+ gui_erp_append.append_run.Enable = Enableflag;
+ gui_erp_append.sameerpset.Enable = Enableflag;
+ gui_erp_append.erpset_custom.Enable = Enableflag;
+ end
+
+
+
+%%**************************************************************************%%
+%%--------------------------Sub function------------------------------------%%
+%%**************************************************************************%%
+
+%%-------------------------same_to_erpset----------------------------------
+ function same_to_erpset(~,~)
+ gui_erp_append.sameerpset.Value=1;
+ gui_erp_append.erpset_custom.Value=0;
+ gui_erp_append.erpset_edit.Enable = 'off';
+ ERPArray = estudioworkingmemory('selectederpstudio');
+ gui_erp_append.erpset_edit.String = num2str(ERPArray);
+ end
+
+
+%%-----------------erpsetcutom---------------------------------------------
+ function erpsetcutom(~,~)
+ gui_erp_append.sameerpset.Value=0;
+ gui_erp_append.erpset_custom.Value=1;
+ gui_erp_append.erpset_edit.Enable = 'on';
+ end
+
+
+%%-------------------------Append help------------------------------------
+ function erpset_append_help(~,~)
+ web('https://github.com/lucklab/erplab/wiki/Appending-ERPSETS','-browser');
+ end
+
+
+%%-------------------edit the ERPset to append-----------------------------
+ function erpset_edit(Source,~)
+ ERPArray = str2num(Source.String);
+ if isempty(ERPArray) || numel(ERPArray)==1
+ messgStr = strcat('Append ERPsets > You have to specify 2 ERPsets, at least.');
+ erpworkingmemory('f_ERP_proces_messg',messgStr);
+ fprintf(2,['\n Warning: ',messgStr,'.\n']);
+ observe_ERPDAT.Process_messg=4;
+ return;
+ end
+ if min(ERPArray) <=0
+ messgStr = strcat('Append ERPsets > Index of inputs should not be larger than 0.');
+ erpworkingmemory('f_ERP_proces_messg',messgStr);
+ fprintf(2,['\n Warning: ',messgStr,'.\n']);
+ observe_ERPDAT.Process_messg=4;
+ return;
+ end
+
+ if max(ERPArray) > length(observe_ERPDAT.ALLERP)
+ messgStr = strcat('Append ERPsets > Index of inputs should not be larger than',32,num2str(length(observe_ERPDAT.ALLERP)),'.');
+ erpworkingmemory('f_ERP_proces_messg',messgStr);
+ fprintf(2,['\n Warning: ',messgStr,'.\n']);
+ observe_ERPDAT.Process_messg=4;
+ return;
+ end
+ end
+
+
+%%-----------------Advance setting for ERPset append-----------------------
+ function advance_erpappend(~,~)
+ %%Send message to Message panel
+ erpworkingmemory('f_ERP_proces_messg','Append ERPsets');
+ observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started.
+
+ ERPArray = str2num(gui_erp_append.erpset_edit.String);
+ if isempty(ERPArray) || numel(ERPArray)==1
+ messgStr = strcat('Append ERPsets > You have to specify 2 ERPsets, at least.');
+ erpworkingmemory('f_ERP_proces_messg',messgStr);
+ fprintf(2,['\n Warning: ',messgStr,'.\n']);
+ observe_ERPDAT.Process_messg=4;
+ return;
+ end
+ if min(ERPArray) <=0
+ messgStr = strcat('Append ERPsets > Index of inputs should not be larger than 0.');
+ erpworkingmemory('f_ERP_proces_messg',messgStr);
+ fprintf(2,['\n Warning: ',messgStr,'.\n']);
+ observe_ERPDAT.Process_messg=4;
+ return;
+ end
+ if max(ERPArray) > length(observe_ERPDAT.ALLERP)
+ messgStr = strcat('Append ERPsets > Index of inputs should not be larger than',32,num2str(length(observe_ERPDAT.ALLERP)),'.');
+ erpworkingmemory('f_ERP_proces_messg',messgStr);
+ fprintf(2,['\n Warning: ',messgStr,'.\n']);
+ beep;
+ observe_ERPDAT.Process_messg=4;
+ return;
+ end
+ %%check number of samples/channels, and data type
+ messgStr = check_ERPset(ERPArray);
+ if ~isempty(messgStr)
+ erpworkingmemory('f_ERP_proces_messg',messgStr);
+ beep;
+ fprintf(2,['\n Warning: ',messgStr,'.\n']);
+ observe_ERPDAT.Process_messg=4;
+ return
+ end
+
+
+ try
+ ALLERP= observe_ERPDAT.ALLERP;
+ nloadedset = length(observe_ERPDAT.ALLERP);
+ def = estudioworkingmemory('pop_appenderp');
+ if isempty(def)
+ if isempty(observe_ERPDAT.ALLERP)
+ inp1 = 1; %from hard drive
+ erpset = [];
+ erpoption = 1;
+ else
+ inp1 = 0; %from erpset menu
+ erpset = 1:length(ALLERP);
+ erpoption = 1;%% 1. same as ERPset panel; 2 custom define
+ end
+ isprefix = 0;
+ prefixlist = '';
+ def = {inp1 erpoption, erpset prefixlist};
+ %def = { erpset prefixlist};
+ else
+ if ~isempty(ALLERP)
+ if isnumeric(def{2}) % JavierLC 11-17-11
+ [uu, mm] = unique_bc2(def{3}, 'first');
+ def{3} = [def{3}(sort(mm))];
+ end
+ end
+ end
+
+ ERPsetArraydef = str2num(gui_erp_append.erpset_edit.String);
+ if isempty(ERPsetArraydef) || max(ERPsetArraydef)> length(observe_ERPDAT.ALLERP)
+ ERPsetArraydef = observe_ERPDAT.CURRENTERP;
+ end
+ def{1} = 0;
+ def{3} = ERPsetArraydef;
+ def{2} = gui_erp_append.sameerpset.Value;
+ ERPArrayERPpanel = estudioworkingmemory('selectederpstudio');
+ def{5} = ERPArrayERPpanel;
+
+ %
+ % Call GUI
+ %
+ answer = f_appenderpGUI(nloadedset, def);
+ if isempty(answer)
+ disp('User selected Cancel')
+ return
+ end
+ optioni = answer{1}; %1 means from hard drive, 0 means from erpsets menu
+ ERPsetop = answer{2};
+ erpset = answer{3};
+ prefixlist = answer{4};
+
+
+ estudioworkingmemory('pop_appenderp',answer);
+
+ if optioni==1 % from files
+ filelist = erpset;
+ ALLERP = {ALLERP, filelist}; % truco
+ else % from erpsets menu
+ %erpset = erpset;
+ end
+ if isempty(prefixlist)
+ prefixliststr = ''; % do not include prefix
+ elseif isnumeric(prefixlist)
+ prefixliststr = 'erpname'; % use erpname instead
+ else
+ prefixliststr = prefixlist; % include prefix from list
+ end
+ erpworkingmemory('pop_appenderp', { optioni, erpset, prefixlist });
+
+ ALLERPCOM = evalin('base','ALLERPCOM');
+
+ if optioni==0
+ messgStr = check_ERPset(erpset);
+ if ~isempty(messgStr)
+ erpworkingmemory('f_ERP_proces_messg',messgStr);
+ beep;
+ fprintf(2,['\n Warning: ',messgStr,'.\n']);
+ observe_ERPDAT.Process_messg=4;
+ return
+ end
+ %%check prefixes
+
+ if ~isempty(prefixliststr) && numel(erpset) ~= length(prefixliststr)
+ messgStr = strcat('Append ERPsets > prefixes must to be as large as ERPset indx');
+ erpworkingmemory('f_ERP_proces_messg',messgStr);
+ beep;
+ fprintf(2,['\n Warning: ',messgStr,'.\n']);
+ observe_ERPDAT.Process_messg=4;
+ return
+ end
+ end
+ %
+ % Somersault
+ %
+ if optioni==1 && ~isempty(erpset)
+ if isempty(prefixliststr)
+ [ERP,ERPCOM] = pop_appenderp( erpset, 'Saveas', 'off', 'History', 'gui');
+ else
+ fid_list = fopen( erpset );
+ formcell = textscan(fid_list, '%[^\n]','CommentStyle','#', 'whitespace', '');
+ lista = formcell{:};
+
+ if numel(lista) ~= length(prefixliststr)
+ messgStr = strcat('Append ERPsets > prefixes must to be as large as ERPset indx');
+ erpworkingmemory('f_ERP_proces_messg',messgStr);
+ beep;
+ fprintf(2,['\n Warning: ',messgStr,'.\n']);
+ observe_ERPDAT.Process_messg=4;
+ return
+ end
+
+ [ERP, ERPCOM] = pop_appenderp(erpset, 'Prefixes', prefixliststr, 'Saveas', 'off', 'History', 'gui');
+ end
+ else
+
+ if isempty(prefixliststr)
+ [ERP, ERPCOM] = pop_appenderp(ALLERP, 'Erpsets', erpset, 'Saveas', 'off', 'History', 'gui');
+ else
+ [ERP, ERPCOM] = pop_appenderp(ALLERP, 'Erpsets', erpset, 'Prefixes', prefixliststr, 'Saveas', 'off', 'History', 'gui');
+ end
+ end
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);%%SAVE the command
+ pathName_def = erpworkingmemory('ERP_save_folder');
+ if isempty(pathName_def)
+ pathName_def =cd;
+ end
+ erpName_new = '';
+ fileName_new = '';
+ pathName_new = '';
+ Save_file_label =0;
+
+ Answer = f_ERP_save_single_file(strcat('append'),'',length(observe_ERPDAT.ALLERP)+1);
+ if isempty(Answer)
+ % erpName_new = strcat(num2str(length(observe_ERPDAT.ALLERP)+1),'append');
+ % Save_file_label =0;
+ disp('User selected Cancel.');
+ return;
+ end
+
+ if ~isempty(Answer)
+ ERPName = Answer{1};
+ if ~isempty(ERPName)
+ erpName_new = ERPName;
+ end
+ fileName_full = Answer{2};
+ if isempty(fileName_full)
+ fileName_new = '';
+ Save_file_label =0;
+ elseif ~isempty(fileName_full)
+
+ [pathstr, file_name, ext] = fileparts(fileName_full);
+ ext = '.erp';
+ if strcmp(pathstr,'')
+ pathstr = pathName_def;
+ end
+ fileName_new = [file_name,ext];
+ pathName_new = pathstr;
+ Save_file_label =1;
+ end
+ end
+
+ ERP.erpname = erpName_new;
+ ERP.filename = fileName_new;
+ ERP.filepath = pathName_new;
+ if Save_file_label==1
+ ERP_save =ERP;
+ ERP_save.filepath = pathName_new;
+ [ERP, issave, ERPCOM] = pop_savemyerp(ERP_save, 'erpname', ERP_save.erpname, 'filename', ERP_save.erpname, 'filepath',ERP_save.filepath);
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ end
+ observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP;
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ assignin('base','ALLERPCOM',ALLERPCOM);
+ assignin('base','ERPCOM',ERPCOM);
+ assignin('base','ERP',observe_ERPDAT.ERP);
+ assignin('base','CURRENTERP',observe_ERPDAT.CURRENTERP);
+ erpworkingmemory('f_ERP_bin_opt',1);
+ observe_ERPDAT.Process_messg =2;
+ estudioworkingmemory('selectederpstudio',observe_ERPDAT.CURRENTERP);
+ OpValue = answer{2};
+ gui_erp_append.sameerpset.Value = OpValue;
+ gui_erp_append.erpset_custom.Value = ~OpValue;
+ gui_erp_append.erpset_edit.String = num2str(answer{3});
+
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ catch
+ observe_ERPDAT.Process_messg =3;
+ return;
+ end
+ observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+ end
+
+
+
+%%--------------------------Run--------------------------------------------
+ function append_run(~,~)
+
+ %%Send message to Message panel
+ erpworkingmemory('f_ERP_proces_messg','Append ERPsets');
+ observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started.
+ %%-------check the inputed ERPsetArray-----------------------------
+ ERPArray = str2num(gui_erp_append.erpset_edit.String);
+ if isempty(ERPArray) || numel(ERPArray)==1
+ messgStr = strcat('Append ERPsets > You have to specify 2 ERPsets, at least.');
+ erpworkingmemory('f_ERP_proces_messg',messgStr);
+ fprintf(2,['\n Warning: ',messgStr,'.\n']);
+ observe_ERPDAT.Process_messg=4;
+ return;
+ end
+ if min(ERPArray) <=0
+ messgStr = strcat('Append ERPsets > Index of inputs should not be larger than 0.');
+ erpworkingmemory('f_ERP_proces_messg',messgStr);
+ fprintf(2,['\n Warning: ',messgStr,'.\n']);
+ observe_ERPDAT.Process_messg=4;
+ return;
+ end
+ if max(ERPArray) > length(observe_ERPDAT.ALLERP)
+ messgStr = strcat('Append ERPsets > Index of inputs should not be larger than',32,num2str(length(observe_ERPDAT.ALLERP)),'.');
+ erpworkingmemory('f_ERP_proces_messg',messgStr);
+ fprintf(2,['\n Warning: ',messgStr,'.\n']);
+ beep;
+ observe_ERPDAT.Process_messg=4;
+ return;
+ end
+ %%check number of samples/channels, and data type
+ messgStr = check_ERPset(ERPArray);
+ if ~isempty(messgStr)
+ erpworkingmemory('f_ERP_proces_messg',messgStr);
+ beep;
+ fprintf(2,['\n Warning: ',messgStr,'.\n']);
+ observe_ERPDAT.Process_messg=4;
+ return
+ end
+ ALLERPCOM = evalin('base','ALLERPCOM');
+ ALLERP = observe_ERPDAT.ALLERP;
+ prefixliststr = '';
+ for Numoferpset = 1:numel(ERPArray)
+ prefixliststr{Numoferpset} = ALLERP(ERPArray(Numoferpset)).erpname;
+
+ end
+
+ try
+ [ERP, ERPCOM] = pop_appenderp(ALLERP, 'Erpsets', ERPArray, 'Prefixes', prefixliststr, 'Saveas', 'off', 'History', 'gui');
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);%%SAVE the command
+ pathName_def = erpworkingmemory('ERP_save_folder');
+ if isempty(pathName_def)
+ pathName_def =cd;
+ end
+ erpName_new = '';
+ fileName_new = '';
+ pathName_new = '';
+ Save_file_label =0;
+ Answer = f_ERP_save_single_file(strcat('append'),'',length(observe_ERPDAT.ALLERP)+1);
+ if isempty(Answer)
+ disp('User selected Cancel.');
+ return;
+ % erpName_new = strcat(num2str(length(observe_ERPDAT.ALLERP)+1),'append');
+ % Save_file_label =0;
+ end
+ if ~isempty(Answer)
+ ERPName = Answer{1};
+ if ~isempty(ERPName)
+ erpName_new = ERPName;
+ end
+ fileName_full = Answer{2};
+ if isempty(fileName_full)
+ fileName_new = '';
+ Save_file_label =0;
+ elseif ~isempty(fileName_full)
+ [pathstr, file_name, ext] = fileparts(fileName_full);
+ ext = '.erp';
+ if strcmp(pathstr,'')
+ pathstr = pathName_def;
+ end
+ fileName_new = [file_name,ext];
+ pathName_new = pathstr;
+ Save_file_label =1;
+ end
+ end
+ ERP.erpname = erpName_new;
+ ERP.filename = fileName_new;
+ ERP.filepath = pathName_new;
+ if Save_file_label==1
+ ERP_save =ERP;
+ ERP_save.filepath = pathName_new;
+ [ERP, issave, ERPCOM] = pop_savemyerp(ERP_save, 'erpname', ERP_save.erpname, 'filename', ERP_save.erpname, 'filepath',ERP_save.filepath);
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ end
+ observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP;
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ assignin('base','ALLERPCOM',ALLERPCOM);
+ assignin('base','ERPCOM',ERPCOM);
+ erpworkingmemory('f_ERP_bin_opt',1);
+ observe_ERPDAT.Process_messg =2;
+ estudioworkingmemory('selectederpstudio',observe_ERPDAT.CURRENTERP);
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ catch
+ observe_ERPDAT.Process_messg =3;
+ return;
+ end%% end try
+ observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+ end
+
+
+%%--------Setting current ERPset/session history based on the current updated ERPset------------
+ function Count_currentERPChanged(~,~)
+ if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded')
+ Enableflag = 'off';
+ else
+ Enableflag = 'on';
+ end
+ gui_erp_append.erpset_edit.Enable = Enableflag;
+ gui_erp_append.erpset_option.Enable = Enableflag;
+ gui_erp_append.append_advance.Enable = Enableflag;
+ gui_erp_append.append_run.Enable = Enableflag;
+ gui_erp_append.sameerpset.Enable = Enableflag;
+ gui_erp_append.erpset_custom.Enable = Enableflag;
+ if gui_erp_append.sameerpset.Value ==1%%same to the
+ %%selected erpsert as the "ERPset" panel.
+ ERPArray = estudioworkingmemory('selectederpstudio');
+ gui_erp_append.erpset_edit.String = num2str(ERPArray);
+ gui_erp_append.erpset_edit.Enable = 'off';
+ else
+ gui_erp_append.erpset_edit.Enable = 'on';
+ end
+ end
+
+
+%%-------------Check number of bin/channel, and data type------------------
+ function msgboxText = check_ERPset(ERPArray)
+ msgboxText = '';
+ nfile = numel(ERPArray);
+ if nfile >1
+ numpoints = zeros(1,nfile);
+ numchans = zeros(1,nfile);
+ chckdatatype = cell(1);
+ ALLERP= observe_ERPDAT.ALLERP;
+ for j=1:nfile
+ numpoints(j) = ALLERP(ERPArray(j)).pnts;
+ numchans(j) = ALLERP(ERPArray(j)).nchan;
+ chckdatatype{j} = ALLERP(ERPArray(j)).datatype;
+ clear ERP1
+ end
+ if length(unique(numpoints))>1
+ msgboxText = 'Append ERPsets > The selected ERPsets have different number of points';
+ end
+
+ if length(unique(numchans))>1
+ msgboxText = 'Append ERPsets > The selected ERPsets have different number of channel';
+ end
+ if length(unique(chckdatatype))>1
+ msgboxText = 'Append ERPsets > The selected ERPsets have different data type';
+ end
+ end
+ end
+
+end
\ No newline at end of file
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_baselinecorr_detrend_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_baselinecorr_detrend_GUI.m
new file mode 100755
index 00000000..e5264de1
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_baselinecorr_detrend_GUI.m
@@ -0,0 +1,585 @@
+%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com
+%Center for Mind and Brain
+%University of California, Davis
+%Davis, CA, USA
+%Feb. 2022
+
+% ERPLAB Studio
+
+function varargout = f_ERP_baselinecorr_detrend_GUI(varargin)
+
+% global gui_erp_blc_dt;
+global observe_ERPDAT;
+% addlistener(observe_ERPDAT,'ALLERP_change',@erpschange);
+% addlistener(observe_ERPDAT,'ERP_change',@drawui_CB);
+% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange);
+addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged);
+
+%%---------------------------gui-------------------------------------------
+[version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+if nargin == 0
+ fig = figure(); % Parent figure
+ ERP_basecorr_detrend_box = uiextras.BoxPanel('Parent', fig, 'Title', 'Baseline Correction & Linear Detrend', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel
+elseif nargin == 1
+ ERP_basecorr_detrend_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Baseline Correction & Linear Detrend', 'Padding', 5,'BackgroundColor',ColorB_def);
+else
+ ERP_basecorr_detrend_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Baseline Correction & Linear Detrend', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def);
+end
+
+gui_erp_blc_dt = struct();
+try
+ FonsizeDefault = varargin{2};
+catch
+ FonsizeDefault = [];
+end
+if isempty(FonsizeDefault)
+ FonsizeDefault = f_get_default_fontsize();
+end
+erp_blc_dt_gui(FonsizeDefault);
+varargout{1} = ERP_basecorr_detrend_box;
+%%********************Draw the GUI for ERP measurement tool*****************
+ function erp_blc_dt_gui(FonsizeDefault)
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+
+ if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded')
+ Enable_label = 'off';
+ else
+ Enable_label = 'on';
+ end
+ gui_erp_blc_dt.blc_dt = uiextras.VBox('Parent',ERP_basecorr_detrend_box,'Spacing',1,'BackgroundColor',ColorB_def);
+
+ %%Measurement type
+ gui_erp_blc_dt.blc_dt_type_title = uiextras.HBox('Parent', gui_erp_blc_dt.blc_dt,'Spacing',1,'BackgroundColor',ColorB_def);
+ uicontrol('Style', 'text','Parent', gui_erp_blc_dt.blc_dt_type_title,...
+ 'String','Type:','FontWeight','bold','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def);
+ gui_erp_blc_dt.blc_dt_option = uiextras.HBox('Parent', gui_erp_blc_dt.blc_dt,'Spacing',1,'BackgroundColor',ColorB_def);
+
+ gui_erp_blc_dt.blc = uicontrol('Style', 'radiobutton','Parent', gui_erp_blc_dt.blc_dt_option,...
+ 'String','Baseline Correction','callback',@baseline_correction_erp,'Value',1,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ gui_erp_blc_dt.dt = uicontrol('Style', 'radiobutton','Parent', gui_erp_blc_dt.blc_dt_option,...
+ 'String','Linear detrend','callback',@detrend_erp,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ %%Baseline period: Pre, post whole custom
+ gui_erp_blc_dt.blc_dt_baseline_period_title = uiextras.HBox('Parent', gui_erp_blc_dt.blc_dt,'Spacing',1,'BackgroundColor',ColorB_def);
+ uicontrol('Style', 'text','Parent', gui_erp_blc_dt.blc_dt_baseline_period_title,...
+ 'String','Baseline Period:','FontWeight','bold','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ gui_erp_blc_dt.blc_dt_bp_option = uiextras.HBox('Parent', gui_erp_blc_dt.blc_dt,'Spacing',1,'BackgroundColor',ColorB_def);
+
+ gui_erp_blc_dt.pre = uicontrol('Style', 'radiobutton','Parent', gui_erp_blc_dt.blc_dt_bp_option,...
+ 'String','Pre','callback',@pre_erp,'Value',1,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ gui_erp_blc_dt.post = uicontrol('Style', 'radiobutton','Parent', gui_erp_blc_dt.blc_dt_bp_option,...
+ 'String','Post','callback',@post_erp,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ gui_erp_blc_dt.whole = uicontrol('Style', 'radiobutton','Parent', gui_erp_blc_dt.blc_dt_bp_option,...
+ 'String','Whole','callback',@whole_erp,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ gui_erp_blc_dt.blc_dt_bp_option_cust = uiextras.HBox('Parent', gui_erp_blc_dt.blc_dt,'Spacing',1,'BackgroundColor',ColorB_def);
+
+ gui_erp_blc_dt.custom = uicontrol('Style', 'radiobutton','Parent', gui_erp_blc_dt.blc_dt_bp_option_cust,...
+ 'String','Custom (ms) [start stop]','callback',@custom_erp,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ gui_erp_blc_dt.custom_edit = uicontrol('Style', 'edit','Parent', gui_erp_blc_dt.blc_dt_bp_option_cust,...
+ 'String','','callback',@custom_edit,'Enable',Enable_label,'FontSize',FonsizeDefault);
+
+ if observe_ERPDAT.ERP.times(1)>=0
+ CUstom_String = '';
+ else
+ CUstom_String = num2str([observe_ERPDAT.ERP.times(1),0]);
+ end
+ gui_erp_blc_dt.custom_edit.String = CUstom_String;
+ set(gui_erp_blc_dt.blc_dt_bp_option_cust, 'Sizes',[160 135]);
+
+
+ %%Bin and channels selection
+ gui_erp_blc_dt.blc_dt_bin_chan_title = uiextras.HBox('Parent', gui_erp_blc_dt.blc_dt,'Spacing',1,'BackgroundColor',ColorB_def);
+ uicontrol('Style', 'text','Parent', gui_erp_blc_dt.blc_dt_bin_chan_title,...
+ 'String','Bin and Chan Selection:','FontWeight','bold','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ gui_erp_blc_dt.blc_bin_chan_option = uiextras.HBox('Parent', gui_erp_blc_dt.blc_dt,'Spacing',1,'BackgroundColor',ColorB_def);
+
+ gui_erp_blc_dt.all_bin_chan = uicontrol('Style', 'radiobutton','Parent', gui_erp_blc_dt.blc_bin_chan_option,...
+ 'String','All(Recommended)','callback',@All_bin_chan,'Value',1,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ gui_erp_blc_dt.Selected_bin_chan = uicontrol('Style', 'radiobutton','Parent', gui_erp_blc_dt.blc_bin_chan_option,...
+ 'String','Selected bin & chan','callback',@Selected_bin_chan,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ set(gui_erp_blc_dt.blc_bin_chan_option, 'Sizes',[125 175]);
+
+ %%Cancel and advanced
+ gui_erp_blc_dt.other_option = uiextras.HBox('Parent',gui_erp_blc_dt.blc_dt,'Spacing',1,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_blc_dt.other_option,'BackgroundColor',ColorB_def);
+ gui_erp_blc_dt.reset = uicontrol('Parent',gui_erp_blc_dt.other_option,'Style','pushbutton',...
+ 'String','Reset','callback',@Reset_blc_dt,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]);
+ uiextras.Empty('Parent', gui_erp_blc_dt.other_option);
+ gui_erp_blc_dt.apply = uicontrol('Style','pushbutton','Parent',gui_erp_blc_dt.other_option,...
+ 'String','Apply','callback',@apply_blc_dt,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]);
+ uiextras.Empty('Parent', gui_erp_blc_dt.other_option);
+ set(gui_erp_blc_dt.other_option, 'Sizes',[15 105 30 105 15]);
+
+ set(gui_erp_blc_dt.blc_dt,'Sizes',[18 25 15 25 25 15 25 30]);
+
+ end
+%%****************************************************************************************************************************************
+%%******************* Subfunctions ***************************************************************************************************
+%%****************************************************************************************************************************************
+
+%%--------------------------------setting for amplitude------------------
+ function baseline_correction_erp(source,~)
+ gui_erp_blc_dt.blc.Value =1;
+ gui_erp_blc_dt.dt.Value = 0;
+ end
+
+%%--------------------------Setting for phase-----------------------------
+ function detrend_erp(source,~)
+ gui_erp_blc_dt.dt.Value = 1;
+ gui_erp_blc_dt.blc.Value =0;
+ end
+
+%%----------------Setting for "pre"-----------------------------------------
+ function pre_erp(~,~)
+ gui_erp_blc_dt.pre.Value=1;
+ gui_erp_blc_dt.post.Value=0;
+ gui_erp_blc_dt.whole.Value=0;
+ gui_erp_blc_dt.custom.Value=0;
+ gui_erp_blc_dt.custom_edit.Enable = 'off';
+ if observe_ERPDAT.ERP.times(1)>=0
+ CUstom_String = '';
+ else
+ CUstom_String = num2str([observe_ERPDAT.ERP.times(1),0]);
+ end
+ gui_erp_blc_dt.custom_edit.String = CUstom_String;
+
+ end
+
+
+%%----------------Setting for "post"-----------------------------------------
+ function post_erp(~,~)
+ gui_erp_blc_dt.pre.Value=0;
+ gui_erp_blc_dt.post.Value=1;
+ gui_erp_blc_dt.whole.Value=0;
+ gui_erp_blc_dt.custom.Value=0;
+ gui_erp_blc_dt.custom_edit.Enable = 'off';
+
+ if observe_ERPDAT.ERP.times(end)<=0
+ CUstom_String = '';
+ else
+ CUstom_String = num2str([0 observe_ERPDAT.ERP.times(end)]);
+ end
+ gui_erp_blc_dt.custom_edit.String = CUstom_String;
+
+ end
+
+%%----------------Setting for "whole"-----------------------------------------
+ function whole_erp(~,~)
+ gui_erp_blc_dt.pre.Value=0;
+ gui_erp_blc_dt.post.Value=0;
+ gui_erp_blc_dt.whole.Value=1;
+ gui_erp_blc_dt.custom.Value=0;
+ gui_erp_blc_dt.custom_edit.Enable = 'off';
+ CUstom_String = num2str([observe_ERPDAT.ERP.times(1) observe_ERPDAT.ERP.times(end)]);
+ gui_erp_blc_dt.custom_edit.String = CUstom_String;
+ end
+
+%%----------------Setting for "custom"-----------------------------------------
+ function custom_erp(~,~)
+ gui_erp_blc_dt.pre.Value=0;
+ gui_erp_blc_dt.post.Value=0;
+ gui_erp_blc_dt.whole.Value=0;
+ gui_erp_blc_dt.custom.Value=1;
+ gui_erp_blc_dt.custom_edit.Enable = 'on';
+ end
+
+%%----------------input baseline period defined by user----------------------
+ function custom_edit(Source,~)
+ lat_osci = str2num(Source.String);
+ if isempty(lat_osci)
+ beep;
+ msgboxText = ['Baseline Correction & Linear Detrend - Invalid input for "baseline range"'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if numel(lat_osci) ==1
+ beep;
+ msgboxText = ['Baseline Correction & Linear Detrend - Wrong baseline range. Please, enter two values'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if lat_osci(1)>= lat_osci(2)
+ beep;
+ msgboxText = ['Baseline Correction & Linear Detrend - The first value must be smaller than the second one'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if lat_osci(2) > observe_ERPDAT.ERP.times(end)
+ beep;
+ msgboxText = ['Baseline Correction & Linear Detrend - Second value must be smaller than',32,num2str(observe_ERPDAT.ERP.times(end))];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if lat_osci(1) < observe_ERPDAT.ERP.times(1)
+ beep;
+ msgboxText = ['Baseline Correction & Linear Detrend - First value must be larger than',32,num2str(observe_ERPDAT.ERP.times(1))];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ end
+
+%%---------------------Setting for all chan and bin------------------------
+ function All_bin_chan(~,~)
+ gui_erp_blc_dt.all_bin_chan.Value = 1;
+ gui_erp_blc_dt.Selected_bin_chan.Value = 0;
+ end
+
+%%----------------Setting for selected bin and chan------------------------
+ function Selected_bin_chan(~,~)
+ gui_erp_blc_dt.all_bin_chan.Value = 0;
+ gui_erp_blc_dt.Selected_bin_chan.Value = 1;
+ end
+%%--------------------------Setting for plot-------------------------------
+ function apply_blc_dt(~,~)
+
+ Selected_erpset = estudioworkingmemory('selectederpstudio');
+ if isempty(Selected_erpset)
+ Selected_erpset = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ estudioworkingmemory('selectederpstudio',Selected_erpset);
+ end
+
+
+ try
+ if gui_erp_blc_dt.pre.Value==1
+ BaselineMethod = 'pre';
+ elseif gui_erp_blc_dt.post.Value==1
+ BaselineMethod = 'post';
+ elseif gui_erp_blc_dt.whole.Value==1
+ BaselineMethod = 'all';
+ elseif gui_erp_blc_dt.custom.Value ==1
+ BaselineMethod = str2num(gui_erp_blc_dt.custom_edit.String);
+ end
+ catch
+ BaselineMethod = 'pre';
+ end
+
+ %%Check the baseline period defined by the custom.
+ if gui_erp_blc_dt.custom.Value ==1
+ if isempty(BaselineMethod)
+ beep;
+ msgboxText = ['Baseline Correction & Linear Detrend - Invalid input for baseline range; Please reset two values'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if numel(BaselineMethod) ==1
+ beep;
+ msgboxText = ['Baseline Correction & Linear Detrend - Wrong baseline range. Please, enter two values'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if BaselineMethod(1)>= BaselineMethod(2)
+ beep;
+ msgboxText = ['Baseline Correction & Linear Detrend - The first value must be smaller than the second one'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if roundn(BaselineMethod(2),-3) > roundn(observe_ERPDAT.ERP.times(end),-3)
+ beep;
+ msgboxText = ['Baseline Correction & Linear Detrend - Second value must be smaller than',32,num2str(observe_ERPDAT.ERP.times(end))];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if roundn(BaselineMethod(1),-3) < roundn(observe_ERPDAT.ERP.times(1),-3)
+ beep;
+ msgboxText = ['Baseline Correction & Linear Detrend - First value must be larger than',32,num2str(observe_ERPDAT.ERP.times(1))];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+
+ %%Run the function based on the defined parameters
+ Check_Selected_erpset = [0 0 0 0 0 0 0];
+ S_ws_binchan= estudioworkingmemory('geterpbinchan');
+ if numel(Selected_erpset)>1
+ try
+ Check_Selected_erpset = S_ws_binchan.checked_ERPset_Index;
+ catch
+ Check_Selected_erpset = f_checkerpsets(observe_ERPDAT.ALLERP,Selected_erpset);
+ end
+ end
+
+ %%--------------Loop start for removeing baseline for the selected ERPsets------------
+ if gui_erp_blc_dt.dt.Value ==1
+ Suffix_str = char(strcat('detrend'));
+ else
+ Suffix_str = char(strcat('baselinecorr'));
+ end
+ if numel(Selected_erpset)>1
+ if gui_erp_blc_dt.dt.Value ==1
+ Suffix_str = char(strcat('detrend'));
+ else
+ Suffix_str = char(strcat('baselinecorr'));
+ end
+
+ Answer = f_ERP_save_multi_file(observe_ERPDAT.ALLERP,Selected_erpset,Suffix_str);
+ if isempty(Answer)
+ beep;
+ disp('User selected Cancel');
+ return;
+ end
+
+ if ~isempty(Answer{1})
+ ALLERP_advance = Answer{1};
+ Save_file_label = Answer{2};
+ end
+
+ elseif numel(Selected_erpset)==1
+ Save_file_label = 0;
+ ALLERP_advance = observe_ERPDAT.ALLERP;
+ end
+
+ %%%%-------------------Loop fpor baseline correction---------------
+ erpworkingmemory('f_ERP_proces_messg','Baseline correction & Linear detrend');
+ observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started.
+
+ ALLERPCOM = evalin('base','ALLERPCOM');
+
+ try
+ BinArray = [];
+ ChanArray = [];
+ for Numoferp = 1:numel(Selected_erpset)
+
+ if Selected_erpset(Numoferp)> length(observe_ERPDAT.ALLERP)
+ error('EStudio says: No corresponding ERP exists in ALLEERP');
+ break;
+ end
+
+ ERP = observe_ERPDAT.ALLERP(Selected_erpset(Numoferp));
+ if (Check_Selected_erpset(1)==1 || Check_Selected_erpset(2)==2) && gui_erp_blc_dt.Selected_bin_chan.Value ==1
+ if Check_Selected_erpset(1) ==1
+ msgboxText = ['Number of bins across the selected ERPsets is different!'];
+ elseif Check_Selected_erpset(2)==2
+ msgboxText = ['Number of channels across the selected ERPsets is different!'];
+ elseif Check_Selected_erpset(1)==1 && Check_Selected_erpset(2)==2
+ msgboxText = ['Number of channels and bins vary across the selected ERPsets'];
+ end
+ question = [ '%s\n\n "All" will be active instead of "Selected bin and chan".'];
+ title = 'EStudio: Baseline correction & linear detrend';
+ button = questdlg(sprintf(question, msgboxText), title,'OK','OK');
+ BinArray = [];
+ ChanArray = [];
+ end
+
+ if (Check_Selected_erpset(1)==0 && Check_Selected_erpset(2)==0) && gui_erp_blc_dt.Selected_bin_chan.Value ==1
+ try
+ BinArray = S_ws_binchan.bins{1};
+ ChanArray = S_ws_binchan.elecs_shown{1};
+ [chk, msgboxText] = f_ERP_chckbinandchan(ERP, BinArray, [],1);
+ if chk(1)==1
+ BinArray = [1:ERP.nbin];
+ end
+ [chk, msgboxText] = f_ERP_chckbinandchan(ERP,[], ChanArray,2);
+ if chk(2)==1
+ ChanArray = [1:ERP.nchan];
+ end
+
+ catch
+ BinArray = [1:ERP.nbin];
+ ChanArray = [1:ERP.nchan];
+ end
+ end
+
+ if gui_erp_blc_dt.all_bin_chan.Value == 1
+ BinArray = [1:ERP.nbin];
+ ChanArray = [1:ERP.nchan];
+ end
+
+
+ if gui_erp_blc_dt.dt.Value ==1
+ [ERP ERPCOM] = pop_erplindetrend( ERP, BaselineMethod , 'Saveas', 'off','History','gui');
+ else
+ [ERP ERPCOM]= pop_blcerp( ERP , 'Baseline', BaselineMethod, 'Saveas', 'off','History','gui');
+ end
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ if Numoferp ==1
+ [~, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);
+ end
+
+ %%Only the slected bin and chan were selected to remove baseline and detrending and others are remiained.
+ if ~isempty(BinArray)
+ ERP_before_bl = ALLERP_advance(Selected_erpset(Numoferp));
+ ERP_before_bl.bindata(ChanArray,:,BinArray) = ERP.bindata(ChanArray,:,BinArray);
+ ERP_before_bl.history = ERP.history;
+ ERP = ERP_before_bl;
+ end
+
+
+ if numel(Selected_erpset) ==1
+ Answer = f_ERP_save_single_file(strcat(ERP.erpname,'-',Suffix_str),ERP.filename,Selected_erpset(Numoferp));
+ if isempty(Answer)
+ beep;
+ disp('User selectd cancal');
+ return;
+ end
+
+ if ~isempty(Answer)
+ ERPName = Answer{1};
+ if ~isempty(ERPName)
+ ERP.erpname = ERPName;
+ end
+ fileName_full = Answer{2};
+ if isempty(fileName_full)
+ ERP.filename = ERP.erpname;
+ elseif ~isempty(fileName_full)
+
+ [pathstr, file_name, ext] = fileparts(fileName_full);
+ ext = '.erp';
+ if strcmp(pathstr,'')
+ pathstr = cd;
+ end
+ ERP.filename = [file_name,ext];
+ ERP.filepath = pathstr;
+ %%----------save the current sdata as--------------------
+ [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath);
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ end
+ end
+ end
+
+ if Save_file_label
+ [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath);
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ end
+
+ observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP;
+
+ end%%Loop end for the selected ERset
+
+ erpworkingmemory('f_ERP_BLS_Detrend',{BaselineMethod,0,1});
+ %%
+ % [~, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);
+ assignin('base','ALLERPCOM',ALLERPCOM);
+ assignin('base','ERPCOM',ERPCOM);
+ try
+ Selected_ERP_afd = [length(observe_ERPDAT.ALLERP)-numel(Selected_erpset)+1:length(observe_ERPDAT.ALLERP)];
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP)-numel(Selected_erpset)+1;
+ catch
+ Selected_ERP_afd = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ end
+
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ estudioworkingmemory('selectederpstudio',Selected_ERP_afd);
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Process_messg =2;
+ catch
+ Selected_ERP_afd = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+
+ estudioworkingmemory('selectederpstudio',Selected_ERP_afd);
+
+ observe_ERPDAT.Process_messg =3;
+ erpworkingmemory('f_ERP_BLS_Detrend',{BaselineMethod,0,1});
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ return;
+ end
+ observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+ end
+
+
+%%-----------------Setting for save option---------------------------------
+ function Reset_blc_dt(~,~)
+ gui_erp_blc_dt.blc.Value =1;
+ gui_erp_blc_dt.dt.Value = 0;
+ gui_erp_blc_dt.pre.Value=1;
+ gui_erp_blc_dt.post.Value=0;
+ gui_erp_blc_dt.whole.Value=0;
+ gui_erp_blc_dt.custom.Value=0;
+ gui_erp_blc_dt.custom_edit.Enable = 'off';
+ if observe_ERPDAT.ERP.times(1)>=0
+ CUstom_String = '';
+ else
+ CUstom_String = num2str([observe_ERPDAT.ERP.times(1),0]);
+ end
+ gui_erp_blc_dt.custom_edit.String = CUstom_String;
+ gui_erp_blc_dt.all_bin_chan.Value = 1;
+ gui_erp_blc_dt.Selected_bin_chan.Value = 0;
+ end
+
+
+%%-------------------Setting for the whole panel of fitering based on ALLERP and CURRENTERP--------------
+ function Count_currentERPChanged(~,~)
+ if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded') || ~strcmp(observe_ERPDAT.ERP.datatype,'ERP')
+ Enable_Label = 'off';
+ else
+ Enable_Label = 'on';
+ end
+
+ gui_erp_blc_dt.blc.Enable = Enable_Label;
+ gui_erp_blc_dt.dt.Enable = Enable_Label;
+ gui_erp_blc_dt.apply.Enable = Enable_Label;
+ gui_erp_blc_dt.reset.Enable = Enable_Label;
+ gui_erp_blc_dt.pre.Enable= Enable_Label;
+ gui_erp_blc_dt.post.Enable= Enable_Label;
+ gui_erp_blc_dt.whole.Enable= Enable_Label;
+ gui_erp_blc_dt.custom.Enable= Enable_Label;
+ gui_erp_blc_dt.custom_edit.Enable = Enable_Label;
+ gui_erp_blc_dt.apply.Enable = Enable_Label;
+ gui_erp_blc_dt.reset.Enable = Enable_Label;
+ gui_erp_blc_dt.all_bin_chan.Enable = Enable_Label;
+ gui_erp_blc_dt.Selected_bin_chan.Enable = Enable_Label;
+
+ if gui_erp_blc_dt.custom.Value==1
+ gui_erp_blc_dt.custom_edit.Enable = 'on';
+ else
+ gui_erp_blc_dt.custom_edit.Enable = 'off';
+ end
+
+ Selected_erpset = estudioworkingmemory('selectederpstudio');
+ if isempty(Selected_erpset)
+ Selected_erpset = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ estudioworkingmemory('selectederpstudio',Selected_erpset);
+ end
+ S_binchan = estudioworkingmemory('geterpbinchan');
+
+ Check_Selected_erpset = [0 0 0 0 0 0 0];
+ if numel(Selected_erpset)>1
+ Check_Selected_erpset = S_binchan.checked_ERPset_Index;
+ end
+ if Check_Selected_erpset(1) ==1 || Check_Selected_erpset(2) == 2
+ gui_erp_blc_dt.all_bin_chan.Enable = 'on';
+ gui_erp_blc_dt.Selected_bin_chan.Enable = 'off';
+ gui_erp_blc_dt.all_bin_chan.Value = 1;
+ gui_erp_blc_dt.Selected_bin_chan.Value = 0;
+ end
+ end
+
+end
+%Progem end: ERP Measurement tool
\ No newline at end of file
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_bin_channel_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_bin_channel_GUI.m
new file mode 100755
index 00000000..6db8737e
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_bin_channel_GUI.m
@@ -0,0 +1,509 @@
+%%This function is used to get the 'Bin and Channel Selection' Panel and record the change of th selected channels and selected bins
+
+% *** This function is part of ERPLAB Studio Toolbox ***
+% Author: Guanghui Zhang & Steven Luck
+% Center for Mind and Brain
+% University of California, Davis,
+% Davis, CA
+% 2022
+
+
+function varargout = f_ERP_bin_channel_GUI(varargin)
+
+global observe_ERPDAT;
+% addlistener(observe_ERPDAT,'ALLERP_change',@allErpChanged);
+addlistener(observe_ERPDAT,'ERP_chan_change',@ERP_chan_changed);
+addlistener(observe_ERPDAT,'ERP_bin_change',@ERP_bin_changed);
+% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange);
+addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged);
+
+%---------------------------Initialize parameters------------------------------------
+try
+ SelectedIndex = observe_ERPDAT.CURRENTERP;
+catch
+ disp('f_ERP_bin_channel_GUI error: No CURRENTERP is on Matlab Workspace');
+ return;
+end
+% end
+if SelectedIndex ==0
+
+ disp('f_ERP_bin_channel_GUI error: No ERPset is imported');
+ return;
+end
+if SelectedIndex>length(observe_ERPDAT.ALLERP)
+ SelectedIndex =1;
+end
+
+S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedIndex);
+estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+
+EStduio_gui_erp_bin_chan = struct();
+
+%-----------------------------Name the title----------------------------------------------
+% global EStudio_box_bin_chan;
+[version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+if nargin == 0
+ fig = figure(); % Parent figure
+ EStudio_box_bin_chan = uiextras.BoxPanel('Parent', fig, 'Title', 'Bin and Channel Selection', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel
+elseif nargin == 1
+ EStudio_box_bin_chan = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Bin and Channel Selection', 'Padding', 5,'BackgroundColor',ColorB_def);
+else
+ EStudio_box_bin_chan = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Bin and Channel Selection', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def);
+end
+
+%-----------------------------Draw the panel-------------------------------------
+
+
+observe_ERPDAT.ERP_chan = S_erpbinchan.geterpbinchan.elecs_shown{1};
+observe_ERPDAT.ERP_bin = S_erpbinchan.geterpbinchan.bins{1};
+try
+ FonsizeDefault = varargin{2};
+catch
+ FonsizeDefault = [];
+end
+if isempty(FonsizeDefault)
+FonsizeDefault = f_get_default_fontsize();
+end
+
+drawui_bin_chan(FonsizeDefault)
+varargout{1} = EStudio_box_bin_chan;
+
+ function drawui_bin_chan(FonsizeDefault)
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+ %%--------------------channel and bin setting----------------------
+ EStduio_gui_erp_bin_chan.DataSelBox = uiextras.VBox('Parent', EStudio_box_bin_chan,'BackgroundColor',ColorB_def);
+ EStduio_gui_erp_bin_chan.DataSelGrid = uiextras.Grid('Parent', EStduio_gui_erp_bin_chan.DataSelBox,'BackgroundColor',ColorB_def);
+
+
+ % Second column:
+ uicontrol('Style','text','Parent', EStduio_gui_erp_bin_chan.DataSelGrid,'String','Channels','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 1B
+ Chanlist = observe_ERPDAT.ERP.chanlocs;
+ Chanlist_name{1} = 'All';
+ for Numofchan = 1:length(Chanlist)
+ Chanlist_name{Numofchan+1} = char(strcat(num2str(Numofchan),'.',32,Chanlist(Numofchan).labels));
+ end
+ EStduio_gui_erp_bin_chan.ElecRange = uicontrol('Parent', EStduio_gui_erp_bin_chan.DataSelGrid,'Style','listbox','min',1,'max',length(Chanlist_name),...
+ 'String', Chanlist_name,'Callback',@onElecRange,'FontSize',FonsizeDefault,'Enable','on'); % 2B
+
+ if S_erpbinchan.geterpbinchan.checked_curr_index ==1 || S_erpbinchan.geterpbinchan.checked_ERPset_Index(2) ==2
+ EStduio_gui_erp_bin_chan.ElecRange.Enable = 'off';
+ end
+
+ if numel(S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index}) == numel(Chanlist)
+ EStduio_gui_erp_bin_chan.ElecRange.Value =1;
+ else
+ EStduio_gui_erp_bin_chan.ElecRange.Value = S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index}+1;
+ end
+
+
+ % Third column:
+ uicontrol('Style','text','Parent', EStduio_gui_erp_bin_chan.DataSelGrid,'String','Bins','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 1C
+
+ BinNum = observe_ERPDAT.ERP.nbin;
+ BinName = observe_ERPDAT.ERP.bindescr;
+ brange = cell(BinNum+1,1);
+ brange(1) = {'ALL'};
+ for i = 1:BinNum
+ brange(i+1) = {strcat(num2str(i),'.',32,BinName{i})};
+ end
+ EStduio_gui_erp_bin_chan.BinRange = uicontrol('Parent', EStduio_gui_erp_bin_chan.DataSelGrid,'Style','listbox','Min',1,'Max',BinNum+1,...
+ 'String', brange,'callback',@onBinChanged,'FontSize',FonsizeDefault); % 2C
+ if BinNum== numel(S_erpbinchan.geterpbinchan.bins{1})
+ EStduio_gui_erp_bin_chan.BinRange.Value =1;
+ else
+ EStduio_gui_erp_bin_chan.BinRange.Value = S_erpbinchan.geterpbinchan.bins{1}+1;
+ end
+ if S_erpbinchan.geterpbinchan.checked_curr_index ==1 || S_erpbinchan.geterpbinchan.checked_ERPset_Index(1) ==1
+ EStduio_gui_erp_bin_chan.BinRange.Enable = 'off';
+ end
+
+ set(EStduio_gui_erp_bin_chan.DataSelGrid, 'ColumnSizes',[ -1.2 -2],'RowSizes',[20 -3]);
+ end
+
+
+
+%%**************************************************************************%%
+%%--------------------------Sub function------------------------------------%%
+%%**************************************************************************%%
+
+
+%----------------------------Get the changed channels----------------------*
+ function onElecRange ( src, ~)
+ erpworkingmemory('f_ERP_proces_messg','Bin and Channel Selection-select channel(s)');
+ observe_ERPDAT.Process_messg =1;
+
+ SelectedERP_Index= estudioworkingmemory('selectederpstudio');
+ if isempty(SelectedERP_Index)
+ SelectedERP_Index = observe_ERPDAT.CURRENTERP;
+ if isempty(SelectedERP_Index)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP_Index);
+ S_erpbinchan.geterpbinchan = S_erpplot.geterpbinchan;
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+ S_erpbinchan.geterpbinchan= estudioworkingmemory('geterpbinchan');
+ if isempty(S_erpbinchan.geterpbinchan)
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP_Index);
+ S_erpbinchan.geterpbinchan = S_erpplot.geterpbinchan;
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+
+ new_chans = src.Value;
+ if isempty(new_chans)
+ beep;
+ disp(['No channel was selected']);
+ return;
+ end
+ [~,y_chan_index_select] = find(new_chans==1);
+ if isempty(y_chan_index_select) && numel(new_chans) < numel(src.String)-1 %% 'All' is not slected
+
+ if S_erpbinchan.geterpbinchan.checked_ERPset_Index(2) ==2%% the number of channels varied across ERPsets
+ S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index} = new_chans-1;
+ S_erpbinchan.geterpbinchan.elec_n(S_erpbinchan.geterpbinchan.Select_index) = numel(new_chans);
+ S_erpbinchan.geterpbinchan.first_elec(S_erpbinchan.geterpbinchan.Select_index) = new_chans(1)-1;
+ else
+ for Numofselecterp = 1:numel(SelectedERP_Index)
+ S_erpbinchan.geterpbinchan.elecs_shown{Numofselecterp} = new_chans-1;
+ S_erpbinchan.geterpbinchan.elec_n(Numofselecterp) = numel(new_chans);
+ S_erpbinchan.geterpbinchan.first_elec(Numofselecterp) = new_chans(1)-1;
+ end
+ end
+ EStduio_gui_erp_bin_chan.ElecRange.Value = new_chans;
+ else%% 'All' is selected and included or all channels are slected except 'ALL'
+ carray = src.String;
+ carray(1) = [];
+ if S_erpbinchan.geterpbinchan.checked_ERPset_Index(2) ==2
+ S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index} = [1:numel(carray)];
+ S_erpbinchan.geterpbinchan.elec_n(S_erpbinchan.geterpbinchan.Select_index) = numel(carray);
+ S_erpbinchan.geterpbinchan.first_elec(S_erpbinchan.geterpbinchan.Select_index) = 1;
+ else
+
+ for Numofselecterp = 1:numel(SelectedERP_Index)
+ S_erpbinchan.geterpbinchan.elecs_shown{Numofselecterp} = [1:numel(carray)];
+ S_erpbinchan.geterpbinchan.elec_n(Numofselecterp) = numel(carray);
+ S_erpbinchan.geterpbinchan.first_elec(Numofselecterp) = 1;
+ end
+
+ end
+
+ EStduio_gui_erp_bin_chan.ElecRange.Value = 1;
+ end
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ observe_ERPDAT.ERP_chan = S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index};
+ observe_ERPDAT.Process_messg =2;
+ %%Plot waves
+ try
+ try
+ S_ws_geterpvalues = estudioworkingmemory('geterpvalues');
+ S_ws_viewer = S_ws_geterpvalues.Viewer;
+ catch
+ S_ws_viewer = 'off';
+ end
+
+ if strcmp(S_ws_viewer,'on')
+ f_redrawERP_mt_viewer();
+ else
+ f_redrawERP();
+ end
+
+ catch
+ f_redrawERP();
+ end
+ % observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+ end
+
+
+
+
+%---------------------------get the changed bin----------------------------
+ function onBinChanged( src, ~ )
+ erpworkingmemory('f_ERP_proces_messg','Bin and Channel Selection-select bin(s)');
+ observe_ERPDAT.Process_messg =1;
+
+ SelectedERP_Index= estudioworkingmemory('selectederpstudio');
+ if isempty(SelectedERP_Index)
+ SelectedERP_Index = observe_ERPDAT.CURRENTERP;
+ if isempty(SelectedERP_Index)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP_Index);
+ S_erpbinchan.geterpbinchan = S_erpplot.geterpbinchan;
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+
+
+ S_erpbinchan.geterpbinchan= estudioworkingmemory('geterpbinchan');
+ if isempty(S_erpbinchan.geterpbinchan)
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP_Index);
+ S_erpbinchan.geterpbinchan = S_erpplot.geterpbinchan;
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+
+
+ Bin_label_select = src.Value;
+ if isempty(Bin_label_select)
+ beep;
+ disp(['No bin was selected']);
+ return;
+ end
+
+ [~,y_bin_index_select] = find(Bin_label_select==1);
+ if isempty(y_bin_index_select) && numel(Bin_label_select) < numel(src.String)-1
+ if S_erpbinchan.geterpbinchan.checked_ERPset_Index(1) ==1% The number of bins varied across the selected erpsets
+ S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index} = Bin_label_select-1;
+ S_erpbinchan.geterpbinchan.bin_n(S_erpbinchan.geterpbinchan.Select_index) = numel(Bin_label_select);
+ else
+ for Numofselecterp = 1:numel(SelectedERP_Index)
+ S_erpbinchan.geterpbinchan.bins{Numofselecterp} = Bin_label_select-1;
+ S_erpbinchan.geterpbinchan.bin_n(Numofselecterp) = numel(Bin_label_select);
+ end
+ end
+ EStduio_gui_erp_bin_chan.BinRange.Value = Bin_label_select;
+
+ else% 'All' is selected and inlcuded
+ carray = src.String;
+ carray(1) = [];
+ if S_erpbinchan.geterpbinchan.checked_ERPset_Index(1) ==1% The number of bins varied across the selected erpsets
+ S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index} = [1:numel(carray)];
+ S_erpbinchan.geterpbinchan.bin_n(S_erpbinchan.geterpbinchan.Select_index) = numel(carray);
+ else
+ for Numofselecterp = 1:numel(SelectedERP_Index)
+ S_erpbinchan.geterpbinchan.bins{Numofselecterp} = [1:numel(carray)];
+ S_erpbinchan.geterpbinchan.bin_n(Numofselecterp) = numel(carray);
+ end
+ end
+ EStduio_gui_erp_bin_chan.BinRange.Value = 1;
+ end
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ observe_ERPDAT.ERP_bin = S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index};
+ observe_ERPDAT.Process_messg =2;
+ %%Plot waves
+ try
+ try
+ S_ws_geterpvalues = estudioworkingmemory('geterpvalues');
+ S_ws_viewer = S_ws_geterpvalues.Viewer;
+ catch
+ S_ws_viewer = 'off';
+ end
+
+ if strcmp(S_ws_viewer,'on')
+ f_redrawERP_mt_viewer();
+ else
+ f_redrawERP();
+ end
+
+ catch
+ f_redrawERP();
+ end
+ % observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+ end
+
+
+%----------displayed channel label will be midified after channels was selected--------
+ function ERP_chan_changed(~,~)
+ if observe_ERPDAT.Process_messg==0
+ return;
+ end
+ chanString = EStduio_gui_erp_bin_chan.ElecRange.String;
+ chanArray = observe_ERPDAT.ERP_chan;
+ if max(chanArray)> length(chanString)-1
+ EStduio_gui_erp_bin_chan.ElecRange.Value =1;
+ observe_ERPDAT.ERP_chan = [1:length(chanString)-1];
+ else
+ if max(chanArray)>length(chanString)-1
+ EStduio_gui_erp_bin_chan.ElecRange.Value =1;
+ observe_ERPDAT.ERP_chan = [1:length(chanString)-1];
+ else
+ if numel(chanArray) == length(chanString)-1
+ EStduio_gui_erp_bin_chan.ElecRange.Value =1;
+ else
+ EStduio_gui_erp_bin_chan.ElecRange.Value = chanArray+1;
+ end
+ end
+ end
+ end
+
+
+
+%----------displayed bin label will be midified after different channels was selected--------
+ function ERP_bin_changed(~,~)
+ if observe_ERPDAT.Process_messg==0
+ return;
+ end
+ binArray = observe_ERPDAT.ERP_bin;
+ binString = EStduio_gui_erp_bin_chan.BinRange.String;
+
+ if max(binArray)> length(binString)-1
+ EStduio_gui_erp_bin_chan.BinRange.Value =1;
+ observe_ERPDAT.ERP_bin = [1:length(binString)-1];
+ else
+ if max(binArray)>length(binString)-1
+ EStduio_gui_erp_bin_chan.BinRange.Value =1;
+ observe_ERPDAT.ERP_bin = [1:length(binString)-1];
+ else
+ if numel(binArray) == length(binString)-1
+ EStduio_gui_erp_bin_chan.BinRange.Value =1;
+ else
+ EStduio_gui_erp_bin_chan.BinRange.Value = binArray+1;
+ end
+ end
+ end
+ end
+
+
+%%--------Settting will be modified if the selected was changed------------
+ function Count_currentERPChanged(~,~)
+ try
+ ERPloadIndex = estudioworkingmemory('ERPloadIndex');
+ catch
+ ERPloadIndex =0;
+ end
+ if ERPloadIndex==1
+ ALLERPIN = evalin('base','ALLERP');
+ CURRENTERPIN = evalin('base','CURRENTERP');
+ observe_ERPDAT.ALLERP = ALLERPIN;
+ observe_ERPDAT.CURRENTERP =CURRENTERPIN;
+ try
+ observe_ERPDAT.ERP = ALLERPIN(CURRENTERPIN);
+ catch
+ observe_ERPDAT.ERP = ALLERPIN(end);
+ observe_ERPDAT.CURRENTERP =length(ALLERPIN);
+ end
+ end
+ Selectederp_Index= estudioworkingmemory('selectederpstudio');
+ if isempty(Selectederp_Index)
+ Selectederp_Index = observe_ERPDAT.CURRENTERP;
+ if isempty(Selectederp_Index)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index);
+ S_erpbinchan.geterpbinchan = S_erpplot.geterpbinchan;
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+
+
+ S_erpbinchan.geterpbinchan= estudioworkingmemory('geterpbinchan');
+ if isempty(S_erpbinchan.geterpbinchan)
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index);
+ S_erpbinchan.geterpbinchan = S_erpplot.geterpbinchan;
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+ if max(Selectederp_Index(:)) > length(observe_ERPDAT.ALLERP)
+ beep;
+ disp(['Max. index of selected ERPsets is greater than the length of ALLERP!!!']);
+ return;
+ end
+
+ %The channels and bins will be modified if the ERPset is changed
+ Chanlist = observe_ERPDAT.ERP.chanlocs;
+ Chanlist_name{1} = 'All';
+ for Numofchan = 1:length(Chanlist)
+ Chanlist_name{Numofchan+1} = strcat(num2str(Numofchan),'.',32,char(Chanlist(Numofchan).labels));
+ end
+ EStduio_gui_erp_bin_chan.ElecRange.String=Chanlist_name;
+
+ try
+ checked_ERPset_Index_bin_chan = S_erpbinchan.geterpbinchan.checked_ERPset_Index;
+ catch
+ checked_ERPset_Index_bin_chan = f_checkerpsets(observe_ERPDAT.ALLERP,Selectederp_Index);
+ end
+ if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded') || checked_ERPset_Index_bin_chan(2) ==2
+ EStduio_gui_erp_bin_chan.ElecRange.Enable = 'off';
+ else
+ EStduio_gui_erp_bin_chan.ElecRange.Enable = 'on';
+ end
+
+ EStduio_gui_erp_bin_chan.ElecRange.Min = 1;
+ EStduio_gui_erp_bin_chan.ElecRange.Max = length(Chanlist_name)+1;
+
+ chanArray_pv = EStduio_gui_erp_bin_chan.ElecRange.Value;
+ if numel(chanArray_pv)==1 && chanArray_pv ==1
+ EStduio_gui_erp_bin_chan.ElecRange.Value =1;
+ S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index} = 1:(length(Chanlist_name)-1);
+ else
+ if max(chanArray_pv-1)<= (length(Chanlist_name)-1)
+ S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index}= chanArray_pv-1;
+ else
+ S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index} = 1:(length(Chanlist_name)-1);
+ end
+ end
+
+ if numel(S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index}) == numel(Chanlist)
+ EStduio_gui_erp_bin_chan.ElecRange.Value =1;
+ observe_ERPDAT.ERP_chan = [1:numel(Chanlist)];
+ else
+ EStduio_gui_erp_bin_chan.ElecRange.Value = S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index}+1;
+ observe_ERPDAT.ERP_chan= S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index};
+ end
+
+ ChanShow = S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index};
+ S_erpbinchan.geterpbinchan.elec_n(S_erpbinchan.geterpbinchan.Select_index) = numel(ChanShow);
+ S_erpbinchan.geterpbinchan.first_elec(S_erpbinchan.geterpbinchan.Select_index) = ChanShow(1);
+
+ estudioworkingmemory('ChanShow',ChanShow);
+
+ %%Setting for display bins
+ BinNum = observe_ERPDAT.ERP.nbin;
+ BinName = observe_ERPDAT.ERP.bindescr;
+ brange = cell(BinNum+1,1);
+ brange(1) = {'ALL'};
+ for i = 1:BinNum
+ brange(i+1) = {strcat(num2str(i),'.',32,BinName{i})};
+ end
+ EStduio_gui_erp_bin_chan.BinRange.String=brange;
+ binArray_pv = EStduio_gui_erp_bin_chan.BinRange.Value;
+ if numel(binArray_pv)==1 && binArray_pv ==1
+ EStduio_gui_erp_bin_chan.BinRange.Value =1;
+ S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index} = 1:BinNum;
+ else
+ if max(binArray_pv-1)<= BinNum
+ S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index}= binArray_pv-1;
+ else
+ S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index} = 1:BinNum;
+ end
+ end
+
+ if numel(S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index}) == BinNum
+ EStduio_gui_erp_bin_chan.BinRange.Value =1;
+ else
+ EStduio_gui_erp_bin_chan.BinRange.Value =S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index};
+ end
+ if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded') || checked_ERPset_Index_bin_chan(1) ==1
+ EStduio_gui_erp_bin_chan.BinRange.Enable = 'off';
+ else
+ EStduio_gui_erp_bin_chan.BinRange.Enable = 'on';
+ end
+ EStduio_gui_erp_bin_chan.BinRange.Min = 1;
+ EStduio_gui_erp_bin_chan.BinRange.Max = length(brange)+1;
+
+ if numel(S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index}) == BinNum
+ EStduio_gui_erp_bin_chan.BinRange.Value =1;
+ observe_ERPDAT.ERP_bin = [1:BinNum];
+ else
+ EStduio_gui_erp_bin_chan.BinRange.Value = S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index}+1;
+ observe_ERPDAT.ERP_bin = S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index};
+ end
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+
+ end
+
+end
\ No newline at end of file
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_binoperation_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_binoperation_GUI.m
new file mode 100755
index 00000000..c56fd7d8
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_binoperation_GUI.m
@@ -0,0 +1,515 @@
+%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com
+%Center for Mind and Brain
+%University of California, Davis
+%Davis, CA, USA
+%Feb. 2022
+
+% ERPLAB Studio
+
+function varargout = f_ERP_binoperation_GUI(varargin)
+global observe_ERPDAT;
+% addlistener(observe_ERPDAT,'ALLERP_change',@allErpChanged);
+% addlistener(observe_ERPDAT,'ERP_change',@onErpChanged);
+% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange);
+addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged);
+
+
+gui_erp_bin_operation = struct();
+
+%-----------------------------Name the title----------------------------------------------
+% global ERP_bin_operation_gui;
+[version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+if nargin == 0
+ fig = figure(); % Parent figure
+ ERP_bin_operation_gui = uiextras.BoxPanel('Parent', fig, 'Title', 'ERP Bin Operations', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel
+elseif nargin == 1
+ ERP_bin_operation_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERP Bin Operations', 'Padding', 5,'BackgroundColor',ColorB_def);
+else
+ ERP_bin_operation_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERP Bin Operations', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def);
+end
+
+%-----------------------------Draw the panel-------------------------------------
+try
+ FonsizeDefault = varargin{2};
+catch
+ FonsizeDefault = [];
+end
+if isempty(FonsizeDefault)
+ FonsizeDefault = f_get_default_fontsize();
+end
+drawui_erp_bin_operation(FonsizeDefault);
+varargout{1} = ERP_bin_operation_gui;
+
+ function drawui_erp_bin_operation(FonsizeDefault)
+ FontSize_defualt = FonsizeDefault;
+
+ if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded')
+ Enable_label = 'off';
+ else
+ Enable_label = 'on';
+ end
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+ %%--------------------channel and bin setting----------------------
+ gui_erp_bin_operation.DataSelBox = uiextras.VBox('Parent', ERP_bin_operation_gui,'BackgroundColor',ColorB_def);
+
+
+ for ii = 1:100
+ dsnames{ii,1} = '';
+ end
+ gui_erp_bin_operation.erp_history_table = uiextras.HBox('Parent', gui_erp_bin_operation.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_bin_operation.edit_bineq = uitable( ...
+ 'Parent' , gui_erp_bin_operation.erp_history_table,...
+ 'Data' , dsnames, ...
+ 'ColumnWidth' , {1000}, ...
+ 'ColumnName' , [], ...
+ 'RowName' , []);
+ set(gui_erp_bin_operation.edit_bineq,'ColumnEditable',true(1,length(dsnames)),'FontSize',FontSize_defualt);
+
+ gui_erp_bin_operation.equation_selection = uiextras.HBox('Parent', gui_erp_bin_operation.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_bin_operation.eq_editor = uicontrol('Style','pushbutton','Parent',gui_erp_bin_operation.equation_selection,...
+ 'String','Eq. Advanced','callback',@eq_advanced,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F
+ gui_erp_bin_operation.eq_load = uicontrol('Style','pushbutton','Parent',gui_erp_bin_operation.equation_selection,...
+ 'String','Load Eq.','callback',@eq_load,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F
+ gui_erp_bin_operation.eq_clear = uicontrol('Style','pushbutton','Parent',gui_erp_bin_operation.equation_selection,...
+ 'String','Clear Eq.','callback',@eq_clear,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F
+ %%%----------------Mode-----------------------------------
+ gui_erp_bin_operation.mode_1 = uiextras.HBox('Parent', gui_erp_bin_operation.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_bin_operation.mode_modify_title = uicontrol('Style','text','Parent',gui_erp_bin_operation.mode_1 ,...
+ 'String','Mode:','FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F
+ gui_erp_bin_operation.mode_modify = uicontrol('Style','radiobutton','Parent',gui_erp_bin_operation.mode_1 ,...
+ 'String','Modify Existing ERPset','callback',@mode_modify,'Value',1,'FontSize',FontSize_defualt,'Enable',Enable_label,'BackgroundColor',ColorB_def); % 2F
+ gui_erp_bin_operation.mode_modify.String = 'Modify Existing ERPset (recursive updating)';
+ set(gui_erp_bin_operation.mode_1,'Sizes',[55 -1]);
+ %%--------------For create a new ERPset----------------------------
+ gui_erp_bin_operation.mode_2 = uiextras.HBox('Parent', gui_erp_bin_operation.DataSelBox,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_bin_operation.mode_2);
+ gui_erp_bin_operation.mode_create = uicontrol('Style','radiobutton','Parent',gui_erp_bin_operation.mode_2 ,...
+ 'String',{'', ''},'callback',@mode_create,'Value',0,'FontSize',FontSize_defualt,'Enable',Enable_label,'BackgroundColor',ColorB_def); % 2F
+ gui_erp_bin_operation.mode_create.String = 'Create New ERPset (independent transformations)';
+ set(gui_erp_bin_operation.mode_2,'Sizes',[55 -1]);
+ %%-----------------Run---------------------------------------------
+ gui_erp_bin_operation.run_title = uiextras.HBox('Parent', gui_erp_bin_operation.DataSelBox,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_bin_operation.run_title);
+ uicontrol('Style','pushbutton','Parent',gui_erp_bin_operation.run_title,...
+ 'String','?','callback',@binop_help,'FontSize',16,'Enable','on'); % 2F
+ uiextras.Empty('Parent', gui_erp_bin_operation.run_title);
+ gui_erp_bin_operation.run = uicontrol('Style','pushbutton','Parent',gui_erp_bin_operation.run_title,...
+ 'String','Run','callback',@apply_run,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F
+ uiextras.Empty('Parent', gui_erp_bin_operation.run_title);
+ set(gui_erp_bin_operation.run_title, 'Sizes',[15 105 30 105 15]);
+
+ gui_erp_bin_operation.note_title = uiextras.HBox('Parent', gui_erp_bin_operation.DataSelBox,'BackgroundColor',ColorB_def);
+
+ uicontrol('Style','text','Parent',gui_erp_bin_operation.note_title,...
+ 'String','Note: Operates on all bins and channels','FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F
+
+ set(gui_erp_bin_operation.DataSelBox,'Sizes',[130,30,35,35,30 30]);
+ end
+
+
+
+%%**************************************************************************%%
+%%--------------------------Sub function------------------------------------%%
+%%**************************************************************************%%
+
+% %%------------------help---------------------------------------------
+ function binop_help(~,~)%% It seems that it can be ignored
+ web('https://github.com/lucklab/erplab/wiki/ERP-Bin-Operations','-browser');
+ end
+
+
+%%-------------------Equation editor---------------------------------------
+ function eq_advanced(Source_editor,~)
+ def = erpworkingmemory('pop_binoperator');
+ if isempty(def)
+ def = { [], 1};
+ end
+ binopGUI = erpworkingmemory('binopGUI');
+ if gui_erp_bin_operation.mode_modify.Value ==1
+ binopGUI.emode =0;
+ else
+ binopGUI.emode =1;
+ end
+ erpworkingmemory('binopGUI',binopGUI);
+
+ ERP = observe_ERPDAT.ERP;
+ answer = binoperGUI(ERP, def);
+ if isempty(answer)
+ disp('User selected Cancel')
+ return
+ end
+
+ binopGUI = erpworkingmemory('binopGUI');
+ ModeValue = binopGUI.emode;
+ if ModeValue ==0
+ gui_erp_bin_operation.mode_modify.Value =1;
+ gui_erp_bin_operation.mode_create.Value = 0;
+ else
+ gui_erp_bin_operation.mode_modify.Value =0;
+ gui_erp_bin_operation.mode_create.Value = 1;
+ end
+ formulas = answer{1};
+ wbmsgon = answer{2};
+
+ def = {formulas, wbmsgon};
+ erpworkingmemory('pop_binoperator', def);
+ for ii = 1:100
+ dsnames{ii,1} = '';
+ end
+ if ~isempty(def{1,1})
+ Eqs = def{1,1};
+ for ii = 1:length(def{1,1})
+ dsnames{ii,1} = Eqs{ii};
+ end
+ gui_erp_bin_operation.edit_bineq.Data = dsnames;
+ set(gui_erp_bin_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000});
+ end
+
+ end
+
+%%-------------------Equation Load---------------------------------------
+ function eq_load(~,~)
+ [filename, filepath] = uigetfile({'*.txt';'*.*'},'Select a formulas-file');
+ if isequal(filename,0)
+ disp('User selected Cancel')
+ return
+ else
+ fullname = fullfile(filepath, filename);
+ disp(['f_ERP_binoperation_GUI(): For formulas-file, user selected ', fullname])
+ end
+
+ fid_formula = fopen( fullname );
+ try
+ formcell = textscan(fid_formula, '%s','delimiter', '\r');
+ formulas = char(formcell{:});
+ catch
+ beep;
+ msgboxText = ['ERP Bin Operations - Please, check your file:\n '...
+ fullname '\n'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if size(formulas,2)>256
+ beep;
+ msgboxText = ['ERP Bin Operations - Formulas length exceed 256 characters.\n'...
+ 'Be sure to press [Enter] after you have entered each formula.'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ fclose(fid_formula);
+ gui_erp_bin_operation.edit_bineq.Data = formcell{1,1};
+ set(gui_erp_bin_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000});
+ end
+
+%%-------------------Equation Clear---------------------------------------
+ function eq_clear(~,~)
+ for ii = 1:100
+ dsnames{ii,1} = '';
+ end
+ gui_erp_bin_operation.edit_bineq.Data = dsnames;
+ set(gui_erp_bin_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000});
+ end
+
+
+
+%%------------------Modify Existing ERPset---------------------------------------
+ function mode_modify(Source_editor,~)
+ gui_erp_bin_operation.mode_modify.Value = 1;
+ gui_erp_bin_operation.mode_create.Value = 0;
+
+
+ FormulaArrayIn = char(gui_erp_bin_operation.edit_bineq.Data);
+ if isempty(FormulaArrayIn)
+ val = 0;
+ def = erpworkingmemory('pop_binoperator');
+ FormulaArrayIn_default = def{1};
+ if ~isempty(FormulaArrayIn_default)
+ [val, formulaArray]= f_testsyntaxtype(FormulaArrayIn_default, 'recu');
+ def{1} = formulaArray;
+ erpworkingmemory('pop_binoperator',def);
+ end
+ else
+ [val, formulaArray]= f_testsyntaxtype(FormulaArrayIn, 'recu');
+ end
+ if val ==1
+ gui_erp_bin_operation.edit_bineq.Data =formulaArray;
+ set(gui_erp_bin_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000});
+ def = erpworkingmemory('pop_binoperator');
+ def{1} = formulaArray;
+ erpworkingmemory('pop_binoperator',def);
+ end
+
+ end
+
+%%------------------Create New ERPset---------------------------------------
+ function mode_create(Source_create,~)
+ gui_erp_bin_operation.mode_modify.Value = 0;
+ gui_erp_bin_operation.mode_create.Value = 1;
+
+
+ FormulaArrayIn = char(gui_erp_bin_operation.edit_bineq.Data);
+ if isempty(FormulaArrayIn)
+ val = 0;
+ def = erpworkingmemory('pop_binoperator');
+ try
+ FormulaArrayIn_default = def{1};
+ catch
+ for ii = 1:100
+ FormulaArrayIn_default{ii,1} = '';
+ end
+ end
+ if ~isempty(FormulaArrayIn_default)
+ [val, formulaArray]= f_testsyntaxtype(FormulaArrayIn_default, 'norecu');
+ def{1} = formulaArray;
+ erpworkingmemory('pop_binoperator',def);
+ end
+ else
+ [val, formulaArray]= f_testsyntaxtype(FormulaArrayIn, 'norecu');
+ end
+ if val ==1
+ gui_erp_bin_operation.edit_bineq.Data =formulaArray;
+ set(gui_erp_bin_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000});
+ def = erpworkingmemory('pop_binoperator');
+ def{1} = formulaArray;
+ erpworkingmemory('pop_binoperator',def);
+ end
+
+ end
+
+%%---------------------Run-------------------------------------------------
+ function apply_run(~,~)
+ pathName_def = erpworkingmemory('ERP_save_folder');
+ if isempty(pathName_def)
+ pathName_def =cd;
+ end
+
+ Selectederp_Index= estudioworkingmemory('selectederpstudio');
+ if isempty(Selectederp_Index)
+ Selectederp_Index = observe_ERPDAT.CURRENTERP;
+ if isempty(Selectederp_Index)
+ beep;
+ msgboxText = ['ERP Bin Operations - No ERPset was selected'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+
+
+ Eq_Data = gui_erp_bin_operation.edit_bineq.Data;
+
+ Formula_str = {};
+ count = 0;
+ for ii = 1:length(Eq_Data)
+ if ~isempty(Eq_Data{ii})
+ count = count +1;
+ Formula_str{count} = Eq_Data{ii};
+ end
+ end
+
+ if isempty(Formula_str)
+ beep;
+ msgboxText = ['ERP Bin Operations - You have not yet written a formula'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ %%check the format of equations
+ if gui_erp_bin_operation.mode_modify.Value
+ editormode = 0;
+ else
+ editormode = 1;
+ end
+ [option, recall, goeson] = checkformulas(cellstr(Formula_str), ['pop_binoperator'], editormode);
+ if goeson==0
+ return
+ end
+
+ %%%Create a new ERPset for the bin-operated ERPsets
+ Save_file_label = [];
+ if gui_erp_bin_operation.mode_create.Value
+ if numel(Selectederp_Index) > 1
+ Answer = f_ERP_save_multi_file(observe_ERPDAT.ALLERP,Selectederp_Index,'_binop');
+ if isempty(Answer)
+ beep;
+ disp('User selected Cancel');
+ return;
+ end
+
+ if ~isempty(Answer{1})
+ ALLERP_out = Answer{1};
+ Save_file_label = Answer{2};
+ end
+ elseif numel(Selectederp_Index)== 1
+ ALLERP_out = observe_ERPDAT.ALLERP;
+ ERP = observe_ERPDAT.ALLERP(Selectederp_Index);
+ ERP.filepath = pathName_def;
+ Answer = f_ERP_save_single_file(strcat(ERP.erpname,'_binop'),ERP.filename,Selectederp_Index);
+ if isempty(Answer)
+ beep;
+ disp('User selectd cancal');
+ return;
+ end
+ Save_file_label =0;
+ if ~isempty(Answer)
+ ERPName = Answer{1};
+ if ~isempty(ERPName)
+ ERP.erpname = ERPName;
+ end
+ fileName_full = Answer{2};
+ if isempty(fileName_full)
+ ERP.filename = ERP.erpname;
+ Save_file_label =0;
+ elseif ~isempty(fileName_full)
+
+ [pathstr, file_name, ext] = fileparts(fileName_full);
+ ext = '.erp';
+ if strcmp(pathstr,'')
+ pathstr = cd;
+ end
+ ERP.filename = [file_name,ext];
+ ERP.filepath = pathstr;
+ Save_file_label =1;
+ end
+ end
+ ALLERP_out(Selectederp_Index) = ERP;clear ERP;
+ end
+ elseif gui_erp_bin_operation.mode_modify.Value
+ ALLERP_out = observe_ERPDAT.ALLERP;
+ end
+
+ if isempty(Save_file_label)
+ Save_file_label =0;
+ end
+
+
+ try
+ erpworkingmemory('f_ERP_proces_messg','ERP Bin Operations');
+ observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started.
+ ALLERPCOM = evalin('base','ALLERPCOM');
+ for Numofselectederp = 1:numel(Selectederp_Index)%%Bin Operations for each selected ERPset
+ ERP = ALLERP_out(Selectederp_Index(Numofselectederp));
+ [ERP ERPCOM]= pop_binoperator( ERP, Formula_str, 'Warning', 'on', 'ErrorMsg', 'command', 'Saveas', 'off', 'History', 'gui');
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+
+ if gui_erp_bin_operation.mode_modify.Value%% If select "Modify Existing ERPset (recursive updating)"
+ ERP.erpname = strcat(ERP.erpname,'_binop');
+ observe_ERPDAT.ALLERP(Selectederp_Index(Numofselectederp)) = ERP;
+ observe_ERPDAT.ERP= observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ elseif gui_erp_bin_operation.mode_create.Value %% If select "Create New ERPset (independent transformations)"
+ observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP;
+ if Save_file_label==1
+ [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ALLERP_out(Selectederp_Index(Numofselectederp)).erpname,...
+ 'filename', ALLERP_out(Selectederp_Index(Numofselectederp)).filename, 'filepath',ALLERP_out(Selectederp_Index(Numofselectederp)).filepath);
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ end
+ end
+
+ end
+
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);
+ if gui_erp_bin_operation.mode_create.Value%%Save the labels of the selected ERPsets
+ try
+ Selected_ERP_afd = [length(observe_ERPDAT.ALLERP)-numel(Selectederp_Index)+1:length(observe_ERPDAT.ALLERP)];
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP)-numel(Selectederp_Index)+1;
+ catch
+ Selected_ERP_afd = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ end
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ estudioworkingmemory('selectederpstudio',Selected_ERP_afd);
+ end
+
+ assignin('base','ALLERPCOM',ALLERPCOM);
+ assignin('base','ERPCOM',ERPCOM);
+ erpworkingmemory('f_ERP_bin_opt',1);
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Process_messg =2;
+ return;
+ catch
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ Selected_ERP_afd =observe_ERPDAT.CURRENTERP;
+ estudioworkingmemory('selectederpstudio',Selected_ERP_afd);
+ erpworkingmemory('f_ERP_bin_opt',1);
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Process_messg =3;%%
+ return;
+ end
+ observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+ end
+
+
+
+
+%%--------Setting current ERPset/session history based on the current updated ERPset------------
+ function Count_currentERPChanged(~,~)
+ Selectederp_Index= estudioworkingmemory('selectederpstudio');
+ if isempty(Selectederp_Index)
+ Selectederp_Index = observe_ERPDAT.CURRENTERP;
+
+ if isempty(Selectederp_Index)
+ beep;
+ msgboxText = ['ERP Bin Operations - No ERPset was selected'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ checked_ERPset_Index = S_binchan.checked_ERPset_Index;
+ if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded')
+ checked_curr_index = 1;
+ else
+ checked_curr_index = 0;
+ end
+ if isempty(checked_ERPset_Index)
+ checked_ERPset_Index = f_checkerpsets(observe_ERPDAT.ALLERP,Selectederp_Index);
+ end
+ if checked_curr_index || any(checked_ERPset_Index(:))
+ Enable_label = 'off';
+ for ii = 1:100
+ if ii==1
+ dsnames{ii,1} = 'The number of bins and channles should be the same for the selected ERPset!';
+ else
+ dsnames{ii,1} = '';
+ end
+ end
+ gui_erp_bin_operation.edit_bineq.Data = dsnames;
+ set(gui_erp_bin_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000});
+ else
+ Enable_label = 'on';
+ binopDataor = gui_erp_bin_operation.edit_bineq.Data;
+ for ii = 1:100
+ binopDataorcell = char(binopDataor{ii,1});
+ if isempty(binopDataorcell)
+ dsnames{ii,1} = '';
+ else
+ dsnames{ii,1} = binopDataorcell;
+ end
+ end
+ gui_erp_bin_operation.edit_bineq.Data = dsnames;
+ set(gui_erp_bin_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000});
+ end
+ gui_erp_bin_operation.mode_modify.Enable=Enable_label;
+ gui_erp_bin_operation.mode_create.Enable=Enable_label;
+ gui_erp_bin_operation.eq_editor.Enable = Enable_label;
+ gui_erp_bin_operation.eq_load.Enable = Enable_label;
+ gui_erp_bin_operation.eq_clear.Enable = Enable_label;
+ gui_erp_bin_operation.run.Enable = Enable_label;
+
+ end
+end
\ No newline at end of file
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_chanoperation_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_chanoperation_GUI.m
new file mode 100755
index 00000000..77cc5603
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_chanoperation_GUI.m
@@ -0,0 +1,638 @@
+%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com
+%Center for Mind and Brain
+%University of California, Davis
+%Davis, CA, USA
+%Feb. 2022
+
+% ERPLAB Studio
+
+function varargout = f_ERP_chanoperation_GUI(varargin)
+global observe_ERPDAT;
+% addlistener(observe_ERPDAT,'ALLERP_change',@allErpChanged);
+% addlistener(observe_ERPDAT,'ERP_change',@onErpChanged);
+% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange);
+addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged);
+
+
+gui_erp_chan_operation = struct();
+
+%-----------------------------Name the title----------------------------------------------
+% global ERP_chan_operation_gui;
+try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+catch
+ ColorB_def = [0.95 0.95 0.95];
+end
+if nargin == 0
+ fig = figure(); % Parent figure
+ ERP_chan_operation_gui = uiextras.BoxPanel('Parent', fig, 'Title', 'ERP Channel Operations', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel
+elseif nargin == 1
+ ERP_chan_operation_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERP Channel Operations', 'Padding', 5,'BackgroundColor',ColorB_def);
+else
+ ERP_chan_operation_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERP Channel Operations', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def);
+end
+
+%-----------------------------Draw the panel-------------------------------------
+try
+ FonsizeDefault = varargin{2};
+catch
+ FonsizeDefault = [];
+end
+if isempty(FonsizeDefault)
+ FonsizeDefault = f_get_default_fontsize();
+end
+drawui_erp_bin_operation(FonsizeDefault);
+varargout{1} = ERP_chan_operation_gui;
+
+ function drawui_erp_bin_operation(FonsizeDefault)
+ try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+ catch
+ ColorB_def = [0.95 0.95 0.95];
+ end
+ FontSize_defualt = FonsizeDefault;
+ if isempty(FontSize_defualt)
+ FontSize_defualt = 12;
+ end
+ if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded')
+ Enable_label = 'off';
+ else
+ Enable_label = 'on';
+ end
+ %%--------------------channel and bin setting----------------------
+ gui_erp_chan_operation.DataSelBox = uiextras.VBox('Parent', ERP_chan_operation_gui);
+ for ii = 1:100
+ dsnames{ii,1} = '';
+ end
+ gui_erp_chan_operation.erp_history_table = uiextras.HBox('Parent', gui_erp_chan_operation.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_chan_operation.edit_bineq = uitable( ...
+ 'Parent' , gui_erp_chan_operation.erp_history_table,...
+ 'Data' , dsnames, ...
+ 'ColumnWidth' , {1000}, ...
+ 'ColumnName' , [], ...
+ 'RowName' , []);
+ set(gui_erp_chan_operation.edit_bineq,'ColumnEditable',true(1,length(dsnames)),'FontSize',FontSize_defualt);
+
+ gui_erp_chan_operation.equation_selection = uiextras.HBox('Parent', gui_erp_chan_operation.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_chan_operation.eq_editor = uicontrol('Style','pushbutton','Parent',gui_erp_chan_operation.equation_selection,...
+ 'String','Eq. Advanced','callback',@eq_advanced,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F
+ gui_erp_chan_operation.eq_load = uicontrol('Style','pushbutton','Parent',gui_erp_chan_operation.equation_selection,...
+ 'String','Load Eq.','callback',@eq_load,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F
+ gui_erp_chan_operation.eq_clear = uicontrol('Style','pushbutton','Parent',gui_erp_chan_operation.equation_selection,...
+ 'String','Clear Eq.','callback',@eq_clear,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F
+
+ gui_erp_chan_operation.asst_locaInfo = uiextras.HBox('Parent', gui_erp_chan_operation.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_chan_operation.ref_asst = uicontrol('Style','pushbutton','Parent',gui_erp_chan_operation.asst_locaInfo,...
+ 'String','Reference Asst','callback',@ref_asst,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F
+ gui_erp_chan_operation.locaInfor = uicontrol('Style','checkbox','Parent',gui_erp_chan_operation.asst_locaInfo,...
+ 'String','Load Eq.','callback',@loca_infor,'FontSize',FontSize_defualt,'Value',1,'Enable',Enable_label,'BackgroundColor',ColorB_def); % 2F
+ gui_erp_chan_operation.locaInfor.String = 'Try to Preserve Location Information';
+ set(gui_erp_chan_operation.asst_locaInfo,'Sizes',[105 180]);
+ %%%----------------Mode-----------------------------------
+ gui_erp_chan_operation.mode_1 = uiextras.HBox('Parent', gui_erp_chan_operation.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_chan_operation.mode_modify_title = uicontrol('Style','text','Parent',gui_erp_chan_operation.mode_1 ,...
+ 'String','Mode:','FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F
+ gui_erp_chan_operation.mode_modify = uicontrol('Style','radiobutton','Parent',gui_erp_chan_operation.mode_1 ,...
+ 'String','Modify Existing ERPset','callback',@mode_modify,'Value',1,'FontSize',FontSize_defualt,'Enable',Enable_label,'BackgroundColor',ColorB_def); % 2F
+ gui_erp_chan_operation.mode_modify.String = 'Modify Existing ERPset (recursive updating)';
+ set(gui_erp_chan_operation.mode_1,'Sizes',[55 -1]);
+ %%--------------For create a new ERPset----------------------------
+ gui_erp_chan_operation.mode_2 = uiextras.HBox('Parent', gui_erp_chan_operation.DataSelBox,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_chan_operation.mode_2,'BackgroundColor',ColorB_def);
+ gui_erp_chan_operation.mode_create = uicontrol('Style','radiobutton','Parent',gui_erp_chan_operation.mode_2 ,...
+ 'String',{'', ''},'callback',@mode_create,'Value',0,'FontSize',FontSize_defualt,'Enable',Enable_label,'BackgroundColor',ColorB_def); % 2F
+ gui_erp_chan_operation.mode_create.String = 'Create New ERPset (independent transformations)';
+ set(gui_erp_chan_operation.mode_2,'Sizes',[55 -1]);
+ %%-----------------Run---------------------------------------------
+ gui_erp_chan_operation.run_title = uiextras.HBox('Parent', gui_erp_chan_operation.DataSelBox,'BackgroundColor',ColorB_def);
+
+
+ uiextras.Empty('Parent', gui_erp_chan_operation.run_title,'BackgroundColor',ColorB_def);
+ uicontrol('Style','pushbutton','Parent',gui_erp_chan_operation.run_title,...
+ 'String','?','callback',@chanop_help,'FontSize',16,'Enable','on');
+ uiextras.Empty('Parent', gui_erp_chan_operation.run_title,'BackgroundColor',ColorB_def);
+ gui_erp_chan_operation.run = uicontrol('Style','pushbutton','Parent',gui_erp_chan_operation.run_title,...
+ 'String','Run','callback',@apply_run,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F
+ uiextras.Empty('Parent', gui_erp_chan_operation.run_title,'BackgroundColor',ColorB_def);
+ set(gui_erp_chan_operation.run_title,'Sizes',[15 105 30 105 15]);
+
+ gui_erp_chan_operation.note_title = uiextras.HBox('Parent', gui_erp_chan_operation.DataSelBox,'BackgroundColor',ColorB_def);
+ uicontrol('Style','text','Parent',gui_erp_chan_operation.note_title,...
+ 'String','Note: Operates on all bins and channels','FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F
+
+ set(gui_erp_chan_operation.DataSelBox,'Sizes',[130,30,35,35,35,30 30]);
+ end
+
+
+
+%%**************************************************************************%%
+%%--------------------------Sub function------------------------------------%%
+%%**************************************************************************%%
+
+% %%------------------Edit bin---------------------------------------------
+ function chanop_help(~,~)%% It seems that it can be ignored
+ web('https://github.com/lucklab/erplab/wiki/EEG-and-ERP-Channel-Operations','-browser');
+ end
+
+
+%%-------------------Equation editor---------------------------------------
+ function eq_advanced(Source_editor,~)
+ def = erpworkingmemory('pop_erpchanoperator');
+ if isempty(def)
+ def = { [], 1};
+ end
+ chanopGUI = erpworkingmemory('chanopGUI');
+ if gui_erp_chan_operation.mode_modify.Value==1
+ chanopGUI.emode=0;
+ else
+ chanopGUI.emode=1;
+ end
+ localInfor = gui_erp_chan_operation.locaInfor.Value;
+ chanopGUI.keeplocs = localInfor;
+ erpworkingmemory('chanopGUI',chanopGUI);
+
+ ERP = observe_ERPDAT.ERP;
+ answer = chanoperGUI(ERP, def);
+ if isempty(answer)
+ disp('User selected Cancel')
+ return
+ end
+ chanopGUI = erpworkingmemory('chanopGUI');
+ ModeValue = chanopGUI.emode;
+ if ModeValue==0
+ gui_erp_chan_operation.mode_modify.Value=1 ;
+ gui_erp_chan_operation.mode_create.Value = 0;
+ else
+ gui_erp_chan_operation.mode_modify.Value=0 ;
+ gui_erp_chan_operation.mode_create.Value = 1;
+ end
+ localInfor = chanopGUI.keeplocs;
+ if localInfor==1
+ gui_erp_chan_operation.locaInfor.Value=1;
+ else
+ gui_erp_chan_operation.locaInfor.Value=0;
+ end
+
+ formulas = answer{1};
+ wbmsgon = answer{2};
+ keeplocs = answer{3};
+ if keeplocs ==1
+ gui_erp_chan_operation.locaInfor.Value = 1;
+ else
+ gui_erp_chan_operation.locaInfor.Value = 0;
+ end
+
+ def = {formulas, wbmsgon};
+ erpworkingmemory('pop_erpchanoperator', def);
+ for ii = 1:1000
+ dsnames{ii,1} = '';
+ end
+
+ if ~isempty(def{1,1})
+ Eqs = def{1,1};
+ for ii = 1:length(def{1,1})
+ dsnames{ii,1} = Eqs{ii};
+ end
+ gui_erp_chan_operation.edit_bineq.Data = dsnames;
+ set(gui_erp_chan_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000});
+ end
+
+ end
+
+%%-------------------Equation Load---------------------------------------
+ function eq_load(~,~)
+ [filename, filepath] = uigetfile({'*.txt';'*.*'},'Select a formulas-file');
+ if isequal(filename,0)
+ disp('User selected Cancel')
+ return
+ else
+ fullname = fullfile(filepath, filename);
+ disp(['f_ERP_chanoperation_GUI(): For formulas-file, user selected ', fullname])
+ end
+
+ fid_formula = fopen( fullname );
+ try
+ formcell = textscan(fid_formula, '%s','delimiter', '\r');
+ formulas = char(formcell{:});
+ catch
+ beep;
+ msgboxText = ['ERP Channel Operations - Please, check your file:\n '...
+ fullname '\n'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if size(formulas,2)>256
+ beep;
+ msgboxText = ['ERP Channel Operations - Formulas length exceed 256 characters,'...
+ 'Be sure to press [Enter] after you have entered each formula.'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ fclose(fid_formula);
+ gui_erp_chan_operation.edit_bineq.Data = formcell{1,1};
+ set(gui_erp_chan_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000});
+ end
+
+%%-------------------Equation Clear---------------------------------------
+ function eq_clear(~,~)
+ for ii = 1:1000
+ dsnames{ii,1} = '';
+ end
+ gui_erp_chan_operation.edit_bineq.Data = dsnames;
+ set(gui_erp_chan_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000});
+ end
+
+%%-------------------Reference assist--------------------------------------
+ function ref_asst(~,~)
+ gui_erp_chan_operation.mode_modify.Value = 0;
+ gui_erp_chan_operation.mode_create.Value = 1;
+
+ try
+ ERPLAB = observe_ERPDAT.ERP;
+ nchan = ERPLAB.nchan;
+ catch
+ ERPLAB.chanlocs = [];
+ nchan = 1;
+ end
+ listch=[];
+ if isempty(ERPLAB.chanlocs)
+ for e=1:nchan
+ ERPLAB.chanlocs(e).labels = ['Ch' num2str(e)];
+ end
+ end
+ listch = cell(1,nchan);
+ for ch =1:nchan
+ listch{ch} = [num2str(ch) ' = ' ERPLAB.chanlocs(ch).labels ];
+ end
+
+ % open reference wizard
+ formulalist = f_rerefassistantGUI(nchan, listch);
+ if isempty(formulalist)
+ return;
+ end
+ formulas = char(gui_erp_chan_operation.edit_bineq.Data);
+ for ii = 1:1000
+ dsnames{ii,1} = '';
+ end
+
+ if gui_erp_chan_operation.mode_create.Value
+ formulalist = cellstr([formulalist{:}]);
+ for t=1:length(formulalist)
+ [expspliter parts] = regexp(formulalist, '=','match','split');
+ formulalist{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '[^n]*ch','nch','ignorecase')), strtrim(parts{t}{2}));
+ end
+ % formulalist = char(formulalist);
+ end
+
+ if isempty(formulas)
+ for ii = 1:length(formulalist)
+ dsnames{ii,1} = formulalist{ii};
+ end
+ gui_erp_chan_operation.edit_bineq.Data =dsnames;
+ else
+ formulas = cellstr(formulas);
+ count = 0;
+ for ii = 1:length(formulas)
+ if ~isempty(formulas{ii})
+ count = count+1;
+ dsnames{count,1} = formulas{ii};
+ end
+ end
+
+ for ii = 1:length(formulalist)
+ dsnames{count+ii,1} = formulalist{ii};
+ end
+ clear count;
+ gui_erp_chan_operation.edit_bineq.Data =dsnames;
+ end
+ set(gui_erp_chan_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000});
+
+ end
+
+%%--------------------Preserve location information------------------------
+ function loca_infor(source,~)
+ Value = source.Value;
+ gui_erp_chan_operation.locaInfor.Value = Value;
+ end
+
+
+
+%%------------------Modify Existing ERPset---------------------------------------
+ function mode_modify(Source_editor,~)
+ gui_erp_chan_operation.mode_modify.Value = 1;
+ gui_erp_chan_operation.mode_create.Value = 0;
+
+ FormulaArrayIn = gui_erp_chan_operation.edit_bineq.Data;
+ if isempty(FormulaArrayIn)
+ val = 0;
+ def = erpworkingmemory('pop_erpchanoperator');
+ FormulaArrayIn_default = def{1};
+ if ~isempty(FormulaArrayIn_default)
+ [val, formulaArray]= f_chan_testsyntaxtype(FormulaArrayIn_default, 'recu');
+ def{1} = formulaArray;
+ erpworkingmemory('pop_erpchanoperator',def);
+ end
+ else
+ [val, formulaArray]= f_chan_testsyntaxtype(FormulaArrayIn, 'recu');
+ end
+
+ if val ==1
+ for ii = 1:100
+ try
+ formulaArray{ii,1} = formulaArray{ii};
+ catch
+ formulaArray{ii,1} = '';
+ end
+ end
+ gui_erp_chan_operation.edit_bineq.Data =formulaArray;
+ set(gui_erp_chan_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000});
+ def = erpworkingmemory('pop_erpchanoperator');
+ def{1} = formulaArray;
+ erpworkingmemory('pop_erpchanoperator',def);
+ end
+
+ end
+
+%%------------------Create New ERPset---------------------------------------
+ function mode_create(Source_create,~)
+ gui_erp_chan_operation.mode_modify.Value = 0;
+ gui_erp_chan_operation.mode_create.Value = 1;
+ FormulaArrayIn = char(gui_erp_chan_operation.edit_bineq.Data);
+ if isempty(FormulaArrayIn)
+ val = 0;
+ def = erpworkingmemory('pop_erpchanoperator');
+ FormulaArrayIn_default = def{1};
+ if ~isempty(FormulaArrayIn_default)
+ [val, formulaArray]= f_chan_testsyntaxtype(FormulaArrayIn_default, 'norecu');
+ def{1} = formulaArray;
+ erpworkingmemory('pop_erpchanoperator',def);
+ else
+ for ii = 1:100
+ formulaArray{ii,1} = '';
+ end
+ end
+ else
+ [val, formulaArray]= f_chan_testsyntaxtype(FormulaArrayIn, 'norecu');
+ end
+ if val ==1
+ for ii = 1:100
+ try
+ formulaArray{ii,1} = formulaArray{ii};
+ catch
+ formulaArray{ii,1} = '';
+ end
+ end
+ gui_erp_chan_operation.edit_bineq.Data =formulaArray;
+ set(gui_erp_chan_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000});
+ def = erpworkingmemory('pop_erpchanoperator');
+ def{1} = formulaArray;
+ erpworkingmemory('pop_erpchanoperator',def);
+ end
+
+ end
+
+%%---------------------Run-------------------------------------------------
+ function apply_run(~,~)
+ pathName_def = erpworkingmemory('ERP_save_folder');
+ if isempty(pathName_def)
+ pathName_def =cd;
+ end
+
+ Selectederp_Index= estudioworkingmemory('selectederpstudio');
+ if isempty(Selectederp_Index)
+ Selectederp_Index = observe_ERPDAT.CURRENTERP;
+ if isempty(Selectederp_Index)
+ beep;
+ msgboxText = ['ERP Channel Operations -No ERPset was selected'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+
+
+ Eq_Data = gui_erp_chan_operation.edit_bineq.Data;
+
+ Formula_str = {};
+ count = 0;
+ for ii = 1:length(Eq_Data)
+ if ~isempty(Eq_Data{ii})
+ count = count +1;
+ Formula_str{count} = Eq_Data{ii};
+ end
+ end
+
+ if isempty(Formula_str)
+ beep;
+ msgboxText = ['ERP Channel Operations - You have not yet written a formula'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ %%check the format of equations
+ if gui_erp_chan_operation.mode_modify.Value
+ editormode = 0;
+ else
+ editormode = 1;
+ end
+ [option, recall, goeson] = checkformulas(cellstr(Formula_str), ['pop_erpchanoperator'], editormode);
+ if goeson==0
+ return;
+ end
+
+ %%%Create a new ERPset for the bin-operated ERPsets
+ Save_file_label = [];
+ if gui_erp_chan_operation.mode_create.Value
+
+ if numel(Selectederp_Index) > 1
+ Answer = f_ERP_save_multi_file(observe_ERPDAT.ALLERP,Selectederp_Index,'_chop');
+ if isempty(Answer)
+ beep;
+ disp('User selected Cancel');
+ return;
+ end
+ if ~isempty(Answer{1})
+ ALLERP_out = Answer{1};
+ Save_file_label = Answer{2};
+ end
+
+ elseif numel(Selectederp_Index)== 1
+ ALLERP_out = observe_ERPDAT.ALLERP;
+ ERP = observe_ERPDAT.ALLERP(Selectederp_Index);
+ ERP.filepath = pathName_def;
+ Answer = f_ERP_save_single_file(strcat(ERP.erpname,'_chop'),ERP.filename,Selectederp_Index);
+ if isempty(Answer)
+ beep;
+ disp('User selectd cancal');
+ return;
+ end
+ Save_file_label =0;
+ if ~isempty(Answer)
+ ERPName = Answer{1};
+ if ~isempty(ERPName)
+ ERP.erpname = ERPName;
+ end
+ fileName_full = Answer{2};
+ if isempty(fileName_full)
+ ERP.filename = ERP.erpname;
+ Save_file_label =0;
+ elseif ~isempty(fileName_full)
+
+ [pathstr, file_name, ext] = fileparts(fileName_full);
+ ext = '.erp';
+ if strcmp(pathstr,'')
+ pathstr = cd;
+ end
+ ERP.filename = [file_name,ext];
+ ERP.filepath = pathstr;
+ Save_file_label =1;
+ end
+
+ end
+ ALLERP_out(Selectederp_Index) = ERP;clear ERP;
+ end
+ elseif gui_erp_chan_operation.mode_modify.Value
+ ALLERP_out = observe_ERPDAT.ALLERP;
+ end
+
+ if isempty(Save_file_label)
+ Save_file_label =0;
+ end
+
+ if gui_erp_chan_operation.locaInfor.Value
+ keeplocs =1;
+ else
+ keeplocs =0;
+ end
+
+ try
+ erpworkingmemory('f_ERP_proces_messg','ERP Bin Operations');
+ observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started.
+ ALLERPCOM = evalin('base','ALLERPCOM');
+ for Numofselectederp = 1:numel(Selectederp_Index)%%Bin Operations for each selected ERPset
+ ERP = ALLERP_out(Selectederp_Index(Numofselectederp));
+ [ERP, ERPCOM] = pop_erpchanoperator(ERP, Formula_str, 'Warning', 'off', 'Saveas', 'off','ErrorMsg', 'command','KeepLocations',keeplocs, 'History', 'gui');
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ if gui_erp_chan_operation.mode_modify.Value%% If select "Modify Existing ERPset (recursive updating)"
+ ERP.erpname = strcat(ERP.erpname,'_chop');
+ observe_ERPDAT.ALLERP(Selectederp_Index(Numofselectederp)) = ERP;
+ observe_ERPDAT.ERP= observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ elseif gui_erp_chan_operation.mode_create.Value %% If select "Create New ERPset (independent transformations)"
+ observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP;
+ if Save_file_label==1
+ [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ALLERP_out(Selectederp_Index(Numofselectederp)).erpname,...
+ 'filename', ALLERP_out(Selectederp_Index(Numofselectederp)).filename, 'filepath',ALLERP_out(Selectederp_Index(Numofselectederp)).filepath);
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ end
+ end
+ end
+
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ if gui_erp_chan_operation.mode_create.Value%%Save the labels of the selected ERPsets
+ try
+ Selected_ERP_afd = [length(observe_ERPDAT.ALLERP)-numel(Selectederp_Index)+1:length(observe_ERPDAT.ALLERP)];
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP)-numel(Selectederp_Index)+1;
+ catch
+ Selected_ERP_afd = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ end
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ estudioworkingmemory('selectederpstudio',Selected_ERP_afd);
+ end
+ assignin('base','ALLERPCOM',ALLERPCOM);
+ assignin('base','ERPCOM',ERPCOM);
+ erpworkingmemory('f_ERP_bin_opt',1);
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Process_messg =2;
+ return;
+ catch
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ Selected_ERP_afd =observe_ERPDAT.CURRENTERP;
+ estudioworkingmemory('selectederpstudio',Selected_ERP_afd);
+ erpworkingmemory('f_ERP_bin_opt',1);
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Process_messg =3;%%
+ return;
+ end
+ observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+ end
+
+
+%%--------Setting current ERPset/session history based on the current updated ERPset------------
+ function Count_currentERPChanged(~,~)
+ Selectederp_Index= estudioworkingmemory('selectederpstudio');
+ if isempty(Selectederp_Index)
+ Selectederp_Index = observe_ERPDAT.CURRENTERP;
+ if isempty(Selectederp_Index)
+ beep;
+ msgboxText = ['ERP Channel Operations - No ERPset was selected'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ checked_ERPset_Index = S_binchan.checked_ERPset_Index;
+
+
+ if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded')
+ checked_curr_index = 1;
+ else
+ checked_curr_index = 0;
+ end
+
+ if isempty(checked_ERPset_Index)
+ checked_ERPset_Index = f_checkerpsets(observe_ERPDAT.ALLERP,Selectederp_Index);
+ end
+ if checked_curr_index || any(checked_ERPset_Index(:))
+ Enable_label = 'off';
+ for ii = 1:100
+ if ii==1
+ dsnames{ii,1} = 'The number of bins and channles should be the same for the selected ERPset!';
+ else
+ dsnames{ii,1} = '';
+ end
+ end
+ gui_erp_chan_operation.edit_bineq.Data = dsnames;
+ set(gui_erp_chan_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000});
+ else
+ Enable_label = 'on';
+ chanopDataor = gui_erp_chan_operation.edit_bineq.Data;
+ for ii = 1:100
+ chanopDataorcell = char(chanopDataor{ii,1});
+ if isempty(chanopDataorcell)
+ dsnames{ii,1} = '';
+ else
+ dsnames{ii,1} = chanopDataorcell;
+ end
+ end
+ gui_erp_chan_operation.edit_bineq.Data = dsnames;
+ set(gui_erp_chan_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000});
+ end
+ gui_erp_chan_operation.mode_modify.Enable=Enable_label;
+ gui_erp_chan_operation.mode_create.Enable=Enable_label;
+ gui_erp_chan_operation.eq_editor.Enable = Enable_label;
+ gui_erp_chan_operation.eq_load.Enable = Enable_label;
+ gui_erp_chan_operation.eq_clear.Enable = Enable_label;
+ gui_erp_chan_operation.run.Enable = Enable_label;
+ gui_erp_chan_operation.ref_asst.Enable = Enable_label;
+ gui_erp_chan_operation.locaInfor.Enable = Enable_label;
+
+ end
+
+end
\ No newline at end of file
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_erpsetsGUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_erpsetsGUI.m
new file mode 100755
index 00000000..5e3e3e3b
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_erpsetsGUI.m
@@ -0,0 +1,1515 @@
+% ERPset selector panel
+%
+% Author: Carter Luck and Guanghui ZHANG
+% Center for Mind and Brain
+% University of California, Davis,
+% Davis, CA
+% 2018 & 2022
+
+% ERPLAB Toolbox
+%
+
+%
+% Initial setup
+%
+function varargout = f_ERP_erpsetsGUI(varargin)
+global observe_ERPDAT;
+% addlistener(observe_ERPDAT,'ALLERP_change',@allErpChanged);
+% addlistener(observe_ERPDAT,'ERP_change',@drawui_CB);
+% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange);
+addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged);
+
+ERPsetops = struct();
+%---------Setting the parameter which will be used in the other panels-----------
+
+CurrentERPSet = evalin('base','CURRENTERP');
+
+if isempty(CurrentERPSet) || (CurrentERPSet> length(observe_ERPDAT.ALLERP))
+ CurrentERPSet =1;
+end
+
+
+estudioworkingmemory('selectederpstudio',CurrentERPSet);
+
+try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+catch
+ ColorB_def = [0.95 0.95 0.95];
+end
+datasets = []; % Local data structure
+% global box;
+if nargin == 0
+ fig = figure(); % Parent figure
+ box_erpset_gui = uiextras.BoxPanel('Parent', fig, 'Title', 'ERPsets', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel
+elseif nargin == 1
+ box_erpset_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERPsets', 'Padding', 5,'BackgroundColor',ColorB_def);
+else
+ box_erpset_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERPsets', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def);
+end
+
+
+getDatasets() % Get datasets from ALLERP
+
+datasets = sortdata(datasets);
+datasets = sortdata(datasets);
+% global selectedData;
+try
+ cerp = observe_ERPDAT.CURRENTERP;
+ i = observe_ERPDAT.ALLERP(1,cerp);
+ [r,~] = size(datasets);
+ for j = 1:r
+ if strcmp(i.erpname,cell2mat(datasets(j,1)))&&strcmp(i.filename,cell2mat(datasets(j,4)))&&strcmp(i.filepath,cell2mat(datasets(j,5)))
+ selectedData = j;
+ end
+ end
+catch
+ selectedData = 0;
+end
+
+
+sel_path = cd;
+estudioworkingmemory('ERP_save_folder',sel_path);
+% datasets = {'name', 1, 0, 'Users/***/Documents/Matlab/Test_data/', 'S1.erp';'name2', 2, 1;'name3', 3, 2;'name4', 4, 1;'name5', 5, 4}; % Create datasets. {'Name', datasetNumber, parentNumber, 'filename', 'filepath'}
+% Test erpname/filepath/filename against ALLERP to correlate
+% No duplicate dataset numbers. If a dataset's parent number is not a valid
+% dataset, the dataset will be cleared when dataset = sortdata(datasets) is
+% called. erpsetname must contain at least one non-numeric character.
+datasets = sortdata(datasets);
+
+
+try
+ FonsizeDefault = varargin{2};
+catch
+ FonsizeDefault = [];
+end
+if isempty(FonsizeDefault)
+ FonsizeDefault = f_get_default_fontsize();
+end
+drawui_erpset(FonsizeDefault);
+
+varargout{1} = box_erpset_gui;
+
+
+% Grab local structure from global ERP (update local structure instead of
+% replacing it)
+
+% Draw the ui
+ function drawui_erpset(FonsizeDefault)
+ try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+ catch
+ ColorB_def = [0.95 0.95 0.95];
+ end
+ [r, ~] = size(datasets); % Get size of array of datasets. r is # of datasets
+ % Sort the datasets!!!
+ datasets = sortdata(datasets);
+ vBox = uiextras.VBox('Parent', box_erpset_gui, 'Spacing', 5,'BackgroundColor',ColorB_def); % VBox for everything
+ panelshbox = uiextras.HBox('Parent', vBox, 'Spacing', 5,'BackgroundColor',ColorB_def);
+ % panelshbox = uix.ScrollingPanel('Parent', vBox);
+ panelsv2box = uiextras.VBox('Parent',panelshbox,'Spacing',5,'BackgroundColor',ColorB_def);
+
+
+ %%-----------------------ERPset display---------------------------------------
+ dsnames = {};
+ if size(datasets,1)==1
+ if strcmp(datasets{1},'No ERPset loaded')
+ dsnames = {''};
+ Edit_label = 'off';
+ else
+ dsnames{1} = strcat(num2str(cell2mat(datasets(1,2))),'.',32,datasets{1,1});
+ Edit_label = 'on';
+ end
+ else
+ for Numofsub = 1:size(datasets,1)
+ dsnames{Numofsub} = char(strcat(num2str(cell2mat(datasets(Numofsub,2))),'.',32,datasets{Numofsub,1}));
+ end
+ Edit_label = 'on';
+ end
+ SelectedERP= estudioworkingmemory('selectederpstudio');
+ if isempty(SelectedERP)
+ SelectedERP = observe_ERPDAT.CURRENTERP;
+ if isempty(SelectedERP)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+ ds_length = length(datasets);
+ if selectedData == 0
+ ERPsetops.butttons_datasets = uicontrol('Parent', panelsv2box, 'Style', 'listbox', 'min', 1,'max',...
+ ds_length,'String', dsnames,'Value',1,'Callback',@selectdata,'FontSize',FonsizeDefault);
+ else
+ ERPsetops.butttons_datasets = uicontrol('Parent', panelsv2box, 'Style', 'listbox', 'min', 1,'max',...
+ ds_length,'String', dsnames,'Value', SelectedERP,'Callback',@selectdata,'FontSize',FonsizeDefault);
+ end
+ set(vBox, 'Sizes', 150);
+
+ %%---------------------Options for ERPsets-----------------------------------------------------
+ ERPsetops.buttons2 = uiextras.HBox('Parent', vBox, 'Spacing', 5,'BackgroundColor',ColorB_def);
+ ERPsetops.dupeselected = uicontrol('Parent', ERPsetops.buttons2, 'Style', 'pushbutton', 'String', 'Duplicate', ...
+ 'Callback', @duplicateSelected,'Enable',Edit_label,'FontSize',FonsizeDefault);
+ ERPsetops.renameselected = uicontrol('Parent', ERPsetops.buttons2, 'Style', 'pushbutton', 'String', 'Rename',...
+ 'Callback', @renamedata,'Enable',Edit_label,'FontSize',FonsizeDefault);
+ ERPsetops.suffix = uicontrol('Parent', ERPsetops.buttons2, 'Style', 'pushbutton', 'String', 'Add Suffix',...
+ 'Callback', @add_suffix,'Enable',Edit_label,'FontSize',FonsizeDefault);
+
+
+ buttons3 = uiextras.HBox('Parent', vBox, 'Spacing', 5,'BackgroundColor',ColorB_def);
+ ERPsetops.importexport = uicontrol('Parent',buttons3, 'Style', 'pushbutton', 'String', 'Import',...
+ 'Callback', @imp_erp,'FontSize',FonsizeDefault);
+ ERPsetops.export = uicontrol('Parent',buttons3, 'Style', 'pushbutton', 'String', 'Export', 'Callback', @exp_erp,'Enable',Edit_label,'FontSize',FonsizeDefault);
+ ERPsetops.loadbutton = uicontrol('Parent', buttons3, 'Style', 'pushbutton', 'String', 'Load', ...
+ 'Callback', @load,'FontSize',FonsizeDefault);
+ ERPsetops.clearselected = uicontrol('Parent', buttons3, 'Style', 'pushbutton', 'String', 'Clear', 'Callback', @cleardata,'Enable',Edit_label,'FontSize',FonsizeDefault);
+ buttons4 = uiextras.HBox('Parent', vBox, 'Spacing', 5,'BackgroundColor',ColorB_def);
+ ERPsetops.savebutton = uicontrol('Parent', buttons4, 'Style', 'pushbutton', 'String', 'Save', 'Callback', @savechecked,'Enable',Edit_label,'FontSize',FonsizeDefault);
+ ERPsetops.saveasbutton = uicontrol('Parent', buttons4, 'Style', 'pushbutton', 'String', 'Save As...', 'Callback', @savecheckedas,'Enable',Edit_label,'FontSize',FonsizeDefault);
+ ERPsetops.dotstoggle = uicontrol('Parent', buttons4, 'Style', 'pushbutton', 'String', 'Current Folder', 'Callback', @toggledots,'Enable',Edit_label,'FontSize',FonsizeDefault);
+ set(buttons4,'Sizes',[70 70 115])
+ end
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%---------------------------------------------- Subfunctions --------------------------------------------%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%------------------duplicate the selected ERPsets-----------------------------
+ function duplicateSelected(source,~)%%The defualt channels and bins that come from "bin and channel" panel but user can select bins and channels.
+
+ erpworkingmemory('f_ERP_proces_messg','ERPsets>Duplicate');
+ observe_ERPDAT.Process_messg =1;
+
+ SelectedERP= ERPsetops.butttons_datasets.Value;
+ if isempty(SelectedERP)
+ SelectedERP = observe_ERPDAT.CURRENTERP;
+ if isempty(SelectedERP)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+ checked_ERPset_Index_bin_chan = [0 0 0 0 0 0 0];
+ try
+ S_geterpbinchan = estudioworkingmemory('geterpbinchan');
+ checked_ERPset_Index_bin_chan = S_geterpbinchan.checked_ERPset_Index;
+ catch
+ checked_ERPset_Index_bin_chan = f_checkerpsets(observe_ERPDAT.ALLERP,SelectedERP);
+ end
+
+ BinArray = [];
+ ChanArray = [];
+ try
+ S_geterpbinchan = estudioworkingmemory('geterpbinchan');
+ BinArray = S_geterpbinchan.bins{1};
+ ChanArray = S_geterpbinchan.elecs_shown{1};
+ catch
+ BinArray = [];
+ ChanArray = [];
+ end
+
+
+ try
+ for Numofselecterp = 1:numel(SelectedERP)
+ New_ERP = observe_ERPDAT.ALLERP(SelectedERP(Numofselecterp));
+
+ New_ERP.filename = '';
+ New_ERP.erpname = char(strcat(New_ERP.erpname, '_Duplicated'));
+ if checked_ERPset_Index_bin_chan(1)==1 || checked_ERPset_Index_bin_chan(2) ==2
+ BinArray = [1:New_ERP.nbin];
+ ChanArray = [1:New_ERP.nchan];
+ end
+ New_ERP = f_ERP_duplicate(New_ERP,length(observe_ERPDAT.ALLERP),BinArray,ChanArray);
+ if isempty(New_ERP)
+ beep;
+ disp('User selected cancal!');
+ return;
+ end
+
+ observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = New_ERP;
+
+ datasets = {};
+ getDatasets()
+ datasets = sortdata(datasets);
+
+
+ dsnames = {};
+ for Numofsub = 1:size(datasets,1)
+ dsnames{Numofsub} = char(strcat(num2str(cell2mat(datasets(Numofsub,2))),'.',32,datasets{Numofsub,1}));
+ end
+ %%Reset the display in ERPset panel
+ ERPsetops.butttons_datasets.String = dsnames;
+ ERPsetops.butttons_datasets.Min = 1;
+ ERPsetops.butttons_datasets.Max = length(datasets);
+ % ERPsetops.butttons_datasets.Value = observe_ERPDAT.CURRENTERP;
+ end
+ try
+ Selected_ERP_afd = [length(observe_ERPDAT.ALLERP)-numel(SelectedERP)+1:length(observe_ERPDAT.ALLERP)];
+ ERPsetops.butttons_datasets.Value = Selected_ERP_afd;
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP)-numel(SelectedERP)+1;
+ catch
+ Selected_ERP_afd = length(observe_ERPDAT.ALLERP);
+ ERPsetops.butttons_datasets.Value = Selected_ERP_afd;
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ end
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ SelectedERP =Selected_ERP_afd;
+ estudioworkingmemory('selectederpstudio',SelectedERP);
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_ERP_afd);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ observe_ERPDAT.Process_messg =2;
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ catch
+ ERPsetops.butttons_datasets.Value = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ SelectedERP =observe_ERPDAT.CURRENTERP;
+ estudioworkingmemory('selectederpstudio',SelectedERP);
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_ERP_afd);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ observe_ERPDAT.Process_messg =3;
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ return;
+ end
+ observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+ end
+
+
+
+%%-------------------Rename the selcted files------------------------------
+ function renamedata(~,~)
+ erpworkingmemory('f_ERP_proces_messg','ERPsets>Rename');
+ observe_ERPDAT.Process_messg =1;
+
+ SelectedERP= ERPsetops.butttons_datasets.Value;
+ if isempty(SelectedERP)
+ SelectedERP = observe_ERPDAT.CURRENTERP;
+ if isempty(SelectedERP)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+ for Numofselecterp = 1:length(SelectedERP)
+ try
+ ndsns = SelectedERP(Numofselecterp);
+ [r,~] = size(datasets);
+ for Numofsub = 1:r
+ if ismember(datasets{Numofsub,2},ndsns)
+
+ erpName = char(datasets{Numofsub,1});
+ new = f_ERP_rename_gui(erpName,SelectedERP(Numofselecterp));
+ if isempty(new)
+ beep;
+ disp(['User selected cancel']);
+ return;
+ end
+
+ datasets{Numofsub,1} = new{1,1};
+ clear k
+ [~,cerp] = size(observe_ERPDAT.ALLERP);
+ for k = 1:cerp
+ if strcmp(observe_ERPDAT.ALLERP(1,k).filepath,datasets{Numofsub,5}) && strcmp(observe_ERPDAT.ALLERP(1,k).filename,datasets{Numofsub,4})
+ observe_ERPDAT.ALLERP(1,k).erpname = cell2mat(new);
+ end
+ end
+ end
+ end
+ datasets = sortdata(datasets);
+
+ dsnames = {};
+ for Numofsub = 1:size(datasets,1)
+ dsnames{Numofsub} = char(strcat(num2str(datasets{Numofsub,2}),'.',32,datasets{Numofsub,1}));
+
+ end
+ ERPsetops.butttons_datasets.String = dsnames;
+ ERPsetops.butttons_datasets.Min = 1;
+ ERPsetops.butttons_datasets.Max = length(datasets);
+ observe_ERPDAT.Process_messg =2;
+ catch
+ datasets = sortdata(datasets);
+ dsnames = {};
+ for Numofsub = 1:size(datasets,1)
+ dsnames{Numofsub} = char(strcat(num2str(datasets{Numofsub,2}),'.',32,char(datasets{Numofsub,1})));
+ end
+ ERPsetops.butttons_datasets.String = dsnames;
+ ERPsetops.butttons_datasets.Min = 1;
+ ERPsetops.butttons_datasets.Max = length(datasets);
+ observe_ERPDAT.Process_messg =3;
+ end
+ end
+ end
+
+%%--------------------------------Add Suffix---------------------------------
+ function add_suffix(~,~)
+ erpworkingmemory('f_ERP_proces_messg','ERPsets>Add Suffix');
+ observe_ERPDAT.Process_messg =1;
+
+ SelectedERP= ERPsetops.butttons_datasets.Value;
+ if isempty(SelectedERP)
+ SelectedERP = observe_ERPDAT.CURRENTERP;
+ if isempty(SelectedERP)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+ if isempty(SelectedERP)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ new = f_ERP_suffix_gui('Suffix');
+ if ~isempty(new)
+ for Numofselecterp = 1:length(SelectedERP)
+ datasets{SelectedERP(Numofselecterp),1} = char(strcat(datasets{SelectedERP(Numofselecterp),1},'_',new{1}));
+
+ [~,cerp] = size(observe_ERPDAT.ALLERP);
+ for Numoferp = 1:cerp
+ if strcmp(observe_ERPDAT.ALLERP(1,Numoferp).filepath,char(datasets{SelectedERP(Numofselecterp),5})) && strcmp(observe_ERPDAT.ALLERP(1,Numoferp).filename,char(datasets{SelectedERP(Numofselecterp),4}))
+ observe_ERPDAT.ALLERP(1,Numoferp).erpname = char(datasets{SelectedERP(Numofselecterp),1});
+ end
+ end
+ end
+ observe_ERPDAT.Process_messg =2;
+ else
+ beep;
+ disp('User cancelled');
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ datasets = sortdata(datasets);
+ dsnames = {};
+ for Numofsub = 1:size(datasets,1)
+ dsnames{Numofsub} = char(strcat(num2str((datasets{Numofsub,2})),'.',32,char(datasets{Numofsub,1})));
+ end
+ ERPsetops.butttons_datasets.String = dsnames;
+ ERPsetops.butttons_datasets.Min = 1;
+ ERPsetops.butttons_datasets.Max = size(datasets,1);
+ end
+
+
+
+%----------------------- Import-----------------------------------
+ function imp_erp( ~, ~ )
+ erpworkingmemory('f_ERP_proces_messg','ERPsets>Import');
+ observe_ERPDAT.Process_messg =1;
+ %-----------Setting for import-------------------------------------
+ try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+ catch
+ ColorB_def = [0.7020 0.77 0.85];
+ end
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',ColorB_def);
+ [ind,tf] = listdlg('ListString',{'ERPSS Text','Universal Text','Neuroscan (*.arg)'},'SelectionMode','single',...
+ 'PromptString','Please select a type to import from...','Name','Import','OKString','Select');
+
+ set(0,'DefaultUicontrolBackgroundColor',[1 1 1]);
+
+ if isempty(ind)
+ beep;
+ disp(['User selected cancel']);
+ return;
+
+ end
+ ALLERPCOM = evalin('base','ALLERPCOM');
+
+ try
+ if tf%Import start
+ %%-------------------------------------------------------------------------------
+ %%-----------------------Import ERPSS text---------------------------------------
+ %%-------------------------------------------------------------------------------
+ if ind == 1
+ % pop_importerpss_studio();
+ answer = importERPSS_GUI; %(gui was modified)
+
+ if isempty(answer)
+ disp('User selected Cancel')
+ return
+ end
+
+ fname = answer{1}; % filename (+ whole path)
+ dformat = answer{2}; % data format
+ dtranspose = answer{3}; % transpose data (Fixed)
+ if dformat==0
+ dformatstr = 'explicit'; % points at columns
+ else
+ dformatstr = 'implicit'; % points at rows
+ end
+ if dtranspose==0
+ orienpoint = 'column'; % points at columns
+ else
+ orienpoint = 'row'; % points at rows
+ end
+
+ [ERP, ALLERP, ERPCOM] = pop_importerpss('Filename', fname, 'Format', dformatstr, 'Pointat', orienpoint, 'History', 'script');
+ ERP = erphistory(ERP, [], ERPCOM,1);
+
+ try
+ Selected_erpset = [length(ALLERP)-length(fname)+1:length(ALLERP)];
+ catch
+ beep;
+ disp('Fail to import the ERPsets, please try again or restart EStudio!');
+ return
+ end
+ ALLERP = f_erp_remv_Calibrate(ALLERP, Selected_erpset);
+ Answer = f_ERP_save_multi_file(ALLERP,Selected_erpset,'_erpss');
+ if isempty(Answer)
+ beep;
+ disp('User selected Cancel');
+ return;
+ end
+ Save_file_label = 0;
+ if ~isempty(Answer{1})
+ ALLERP_advance = Answer{1};
+ Save_file_label = Answer{2};
+ end
+ if Save_file_label==1
+ for Numoferpset = 1:length(Selected_erpset)
+ ERP = ALLERP_advance(Selected_erpset(Numoferpset));
+ [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath);
+ ERP = erphistory(ERP, [], ERPCOM,1);
+ end
+ end
+ observe_ERPDAT.ALLERP=ALLERP_advance; clear ALLERP_advance;clear ALLERP
+
+ else
+ %%------------------------------------------------------------------------
+ %%----------------------- Import Universal text-----------------------
+ %%------------------------------------------------------------------------
+ if ind == 2
+
+ def = erpworkingmemory('pop_importerp');
+ if isempty(def)
+ def = {'','','',0,1,0,0,1000,[-200 800]};
+ end
+ %
+ % Call GUI
+ %
+ getlista = importerpGUI(def);
+
+ if isempty(getlista)
+ disp('User selected Cancel')
+ return
+ end
+
+ filename = getlista{1};
+ filepath = getlista{2};
+ ftype = getlista{3};
+ includetime = getlista{4};
+ timeunit = getlista{5};
+ elabel = getlista{6};
+ transpose = getlista{7};
+ fs = getlista{8};
+ xlim = getlista{9};
+
+ erpworkingmemory('pop_importerp', {filename, filepath, ftype,includetime,timeunit,elabel,transpose,fs,xlim});
+
+ filetype = {'text'};
+ if includetime==0
+ inctimestr = 'off';
+ else
+ inctimestr = 'on';
+ end
+ if elabel==0
+ elabelstr = 'off';
+ else
+ elabelstr = 'on';
+ end
+ if transpose==0
+ orienpoint = 'column'; % points at columns
+ else
+ orienpoint = 'row'; % points at rows
+ end
+
+ %
+ % Somersault
+ %
+ [ERP, ERPCOM] = pop_importerp('Filename', filename, 'Filepath', filepath, 'Filetype', filetype, 'Time', inctimestr,...
+ 'Timeunit', timeunit, 'Elabel', elabelstr, 'Pointat', orienpoint, 'Srate', fs, 'Xlim', xlim, 'Saveas', 'off',...
+ 'History', 'gui');
+
+ % [ERP, ERPCOM] = pop_importerp();
+ if length(observe_ERPDAT.ALLERP)==1 && strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded')
+ Selected_erpset_indx = 1;
+ else
+ Selected_erpset_indx = length(observe_ERPDAT.ALLERP)+1;
+ end
+ try
+ filename = ERP.erpname;
+ catch
+ filename = strcat('Sub',num2str(Selected_erpset_indx),'-universal');
+ end
+ if isempty(filename)
+ filename = strcat('Sub',num2str(Selected_erpset_indx),'-universal');
+ end
+ ERP.erpname = filename;
+ %%------------------------------------------------------------------------
+ %%------------------------Import Neuroscan (.avg)----------------
+ %%------------------------------------------------------------------------
+ elseif ind == 3 %%
+ [filename, filepath] = uigetfile({'*.avg';'Neuroscan average file (*.avg)'},'Select a file (Neuroscan)', 'MultiSelect', 'on');
+ if ~iscell(filename) && ~ischar(filename) && filename==0
+ disp('User selected Cancel')
+ return
+ end
+
+ [ERP, ERPCOM]= pop_importavg(filename, filepath, 'Saveas','off','History', 'gui');
+
+ [pathstr, file_name, ext] = fileparts(filename{1,1});
+ ERP.erpname = file_name;
+ if length(observe_ERPDAT.ALLERP)==1 && strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded')
+ Selected_erpset_indx = 1;
+ else
+ Selected_erpset_indx = length(observe_ERPDAT.ALLERP)+1;
+ end
+ end
+ ERP = erphistory(ERP, [], ERPCOM,1);
+
+ Answer = f_ERP_save_single_file(ERP.erpname,ERP.filename,Selected_erpset_indx);
+ if isempty(Answer)
+ beep;
+ % disp('User selectd cancal');
+ return;
+ end
+
+ if ~isempty(Answer)
+ ERPName = Answer{1};
+ if ~isempty(ERPName)
+ ERP.erpname = ERPName;
+ end
+ fileName_full = Answer{2};
+ if isempty(fileName_full)
+ ERP.filename = ERP.erpname;
+ elseif ~isempty(fileName_full)
+
+ [pathstr, file_name, ext] = fileparts(fileName_full);
+ ext = '.erp';
+ if strcmp(pathstr,'')
+ pathstr = cd;
+ end
+ ERP.filename = [file_name,ext];
+ ERP.filepath = pathstr;
+ %%----------save the current sdata as--------------------
+ [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath);
+ ERP = erphistory(ERP, [], ERPCOM,1);
+ end
+ end
+ observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) =ERP;
+ end
+ end
+
+ [~, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);
+ assignin('base','ALLERPCOM',ALLERPCOM);
+ assignin('base','ERPCOM',ERPCOM);
+
+ ERPset_default_label = [];
+ count = 0;
+ for Numoferpset = 1:size(observe_ERPDAT.ALLERP,2)
+ if strcmp(observe_ERPDAT.ALLERP(Numoferpset).erpname,'No ERPset loaded')
+ count = count +1;
+ ERPset_default_label(count) = Numoferpset;
+ end
+ end
+
+ if ~isempty(ERPset_default_label)
+ observe_ERPDAT.ALLERP(ERPset_default_label)=[];
+ end
+
+ datasets = {};
+ getDatasets()
+ datasets = sortdata(datasets);
+
+ dsnames = {};
+ if size(datasets,1)==1
+ if strcmp(datasets{1},'No ERPset loaded')
+ dsnames = {''};
+ Edit_label = 'off';
+ else
+ dsnames{1} = strcat(num2str(cell2mat(datasets(1,2))),'.',32,datasets{1,1});
+ Edit_label = 'on';
+ end
+ else
+ for Numofsub = 1:size(datasets,1)
+ dsnames{Numofsub} = strcat(num2str(cell2mat(datasets(Numofsub,2))),'.',32,datasets{Numofsub,1});
+ end
+ Edit_label = 'on';
+ end
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(end);
+ observe_ERPDAT.Process_messg =2;
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ catch
+ observe_ERPDAT.Process_messg =3;
+ disp(['User selected cancel']);
+ return;
+ end
+ ERPsetops.butttons_datasets.Value = length(observe_ERPDAT.ALLERP);
+ ERPsetops.butttons_datasets.String = dsnames;
+ if strcmp(datasets{1},'No ERPset loaded')
+ Edit_label = 'off';
+ else
+ Edit_label = 'on';
+ end
+ ERPsetops.dupeselected.Enable=Edit_label;
+ ERPsetops.renameselected.Enable=Edit_label;
+ ERPsetops.suffix.Enable= Edit_label;
+ ERPsetops.clearselected.Enable=Edit_label;
+ ERPsetops.savebutton.Enable= Edit_label;
+ ERPsetops.saveasbutton.Enable=Edit_label;
+ ERPsetops.dotstoggle.Enable=Edit_label;
+ ERPsetops.butttons_datasets.Enable = Edit_label;
+ ERPsetops.export.Enable = Edit_label;
+
+ SelectedERP = observe_ERPDAT.CURRENTERP;
+ estudioworkingmemory('selectederpstudio',SelectedERP);
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ ERPsetops.butttons_datasets.Min=1;
+ if size(datasets,1)<=2
+ ERPsetops.butttons_datasets.Max=size(datasets,1)+1;
+ else
+ ERPsetops.butttons_datasets.Max=size(datasets,1);
+ end
+ observe_ERPDAT.Process_messg =2;
+ observe_ERPDAT.Count_ERP = observe_ERPDAT.Count_ERP+1;
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+ end
+
+
+
+%-----------------------Export-----------------------------------
+ function exp_erp( ~, ~ )
+ erpworkingmemory('f_ERP_proces_messg','ERPsets>Export');
+ observe_ERPDAT.Process_messg =1;
+
+ pathName = estudioworkingmemory('ERP_save_folder');
+ if isempty(pathName)
+ pathName = cd;
+ end
+ Selected_erpset= ERPsetops.butttons_datasets.Value;
+ if isempty(Selected_erpset)
+ Selected_erpset = observe_ERPDAT.CURRENTERP;
+ if isempty(Selected_erpset)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+ checked_ERPset_Index_bin_chan = [0 0 0 0 0 0 0];
+ try
+ S_geterpbinchan = estudioworkingmemory('geterpbinchan');
+ checked_ERPset_Index_bin_chan = S_geterpbinchan.checked_ERPset_Index;
+ catch
+ checked_ERPset_Index_bin_chan = f_checkerpsets(observe_ERPDAT.ALLERP,Selected_erpset);
+ end
+ BinArray = [];
+ ChanArray = [];
+ try
+ S_geterpbinchan = estudioworkingmemory('geterpbinchan');
+ BinArray = S_geterpbinchan.bins{1};
+ ChanArray = S_geterpbinchan.elecs_shown{1};
+ catch
+ BinArray = [];
+ ChanArray = [];
+ end
+ try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+ catch
+ ColorB_def = [0.7020 0.77 0.85];
+ end
+
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',ColorB_def);
+ [ind,tf] = listdlg('ListString',{'ERPSS Text','Universal Text'},'SelectionMode','single','PromptString','Please select a type to export to...','Name','Export ERP to','OKString','Ok');
+ set(0,'DefaultUicontrolBackgroundColor',[1 1 1]);
+ if isempty(ind)
+ beep;
+ disp(['User selected cancel']);
+ return;
+ end
+
+ ALLERPCOM = evalin('base','ALLERPCOM');
+ for Numoferpset = 1:length(Selected_erpset)
+
+ if Selected_erpset(Numoferpset) > length(observe_ERPDAT.ALLERP)
+ beep;
+ msgboxText = ['ERPsets>Export: Index of selected ERP is lager than the length of ALLERP'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ ERP_export_erp = observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset));
+ if checked_ERPset_Index_bin_chan(1) ==1 || checked_ERPset_Index_bin_chan(2) ==2
+ BinArray = [1:ERP_export_erp.nbin];
+ ChanArray = [1:ERP_export_erp.nchan];
+ end
+
+ if ind==1
+ try
+ ERP_export_erp.filename =fullfile(pathName,ERP_export_erp.filename);
+ Answer_erpss = f_erp2ascGUI(ERP_export_erp,BinArray,ChanArray);
+ if isempty(Answer_erpss)
+ return;
+ end
+ ERP = Answer_erpss{1};
+ FileName = Answer_erpss{2};
+
+ [observe_ERPDAT.ERP, ERPCOM] = pop_erp2asc(ERP,FileName,'History', 'gui');
+ [observe_ERPDAT.ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);
+ assignin('base','ALLERPCOM',ALLERPCOM);
+ assignin('base','ERPCOM',ERPCOM);
+ observe_ERPDAT.Process_messg =2;
+ catch
+ beep;
+ msgboxText = ['ERPsets>Export: cannot be saved as ERPs'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return
+ end
+ elseif ind ==2
+
+ try
+ ERP_export_erp.filename =fullfile(pathName,ERP_export_erp.filename);
+ ERP = ERP_export_erp;
+ def = estudioworkingmemory('f_export2textGUI');
+ if isempty(def)
+ def = {1,1000, 1, 1, 4, ''};
+ end
+
+ %
+ % Call GUI
+ %
+ def_x = def;
+ def_x{6} = ERP.filename;
+ answer_export = f_export2textGUI(ERP,def_x,BinArray,ChanArray);
+ if isempty(answer_export)
+ beep;
+ disp('User selected cancel');
+ return;
+ end
+ estudioworkingmemory('f_export2textGUI',answer_export);
+ istime = answer_export{1};
+ tunit = answer_export{2};
+ islabeled = answer_export{3};
+ transpa = answer_export{4};
+ prec = answer_export{5};
+
+ filename = answer_export{6};
+ ERP = answer_export{7};
+ binArray = [1:ERP.nbin];
+ if istime
+ time = 'on';
+ else
+ time = 'off';
+ end
+ if islabeled
+ elabel = 'on';
+ else
+ elabel = 'off';
+ end
+ if transpa
+ tra = 'on';
+ else
+ tra = 'off';
+ end
+ try
+ [ERP, ERPCOM] = pop_export2text(ERP, filename, binArray, 'time', time, 'timeunit', tunit, 'electrodes', elabel,...
+ 'transpose', tra, 'precision', prec, 'History', 'gui');
+ [observe_ERPDAT.ERP, ALLERPCOM] = erphistory(ERP_export_erp, ALLERPCOM, ERPCOM);
+ assignin('base','ALLERPCOM',ALLERPCOM);
+ assignin('base','ERPCOM',ERPCOM);
+ observe_ERPDAT.Process_messg =2;
+ catch
+ beep;
+ msgboxText = ['ERPsets>Export: Failed to save selected ERPsets'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ catch
+ observe_ERPDAT.Process_messg =3;
+ return;
+ end
+ end
+ end
+ %%%Export data end
+ end
+
+
+
+
+%%---------------------Load ERP--------------------------------------------
+ function load(~,~)
+ erpworkingmemory('f_ERP_proces_messg','ERPsets>Load');
+ observe_ERPDAT.Process_messg =1;
+
+ ALLERPCOM = evalin('base','ALLERPCOM');
+ [~,bc] = size(observe_ERPDAT.ALLERP);
+ try
+ [filename, filepath] = uigetfile({'*.erp','ERP (*.erp)';...
+ '*.mat','ERP (*.mat)'}, ...
+ 'Load ERP', ...
+ 'MultiSelect', 'on');
+ if isequal(filename,0)
+ disp('User selected Cancel');
+ return;
+ end
+
+ if numel(findobj('tag', 'erpsets')) > 0
+ [ERP, ALLERP, ERPCOM] = pop_loaderp('filename', filename, 'filepath', filepath, 'Warning', 'on', 'UpdateMainGui', 'on', 'multiload', 'off',...
+ 'History', 'gui');
+ else
+ [ERP, ALLERP, ERPCOM] = pop_loaderp('filename', filename, 'filepath', filepath, 'Warning', 'on', 'UpdateMainGui', 'off', 'multiload', 'off',...
+ 'History', 'gui'); %If eeglab is not open, don't update
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ end
+ catch
+ return;
+ end
+
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);
+ assignin('base','ALLERPCOM',ALLERPCOM);
+ assignin('base','ERPCOM',ERPCOM);
+ observe_ERPDAT.ALLERP = ALLERP;
+ observe_ERPDAT.ERP = ERP;
+ ERPset_default_label = [];
+ if ~isequal([1,bc], size(observe_ERPDAT.ALLERP))
+ count = 0;
+ for Numoferpset = 1:size(observe_ERPDAT.ALLERP,2)
+ if strcmp(observe_ERPDAT.ALLERP(Numoferpset).erpname,'No ERPset loaded')
+ count = count +1;
+ ERPset_default_label(count) = Numoferpset;
+ end
+ end
+ if ~isempty(ERPset_default_label)
+ observe_ERPDAT.ALLERP(ERPset_default_label)=[];
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(end);
+ observe_ERPDAT.CURRENTERP = size(observe_ERPDAT.ALLERP,2);
+ end
+ end
+ datasets = {};
+ getDatasets()
+ datasets = sortdata(datasets);
+ % drawui_erpset();
+
+ dsnames = {};
+ if size(datasets,1)==1
+ if strcmp(datasets{1},'No ERPset loaded')
+ dsnames = {''};
+ Edit_label = 'off';
+ else
+
+ dsnames{1} = strcat(num2str(cell2mat(datasets(1,2))),'.',32,datasets{1,1});
+
+ Edit_label = 'on';
+ end
+ else
+ for Numofsub = 1:size(datasets,1)
+ dsnames{Numofsub} = strcat(num2str(cell2mat(datasets(Numofsub,2))),'.',32,datasets{Numofsub,1});
+ end
+ Edit_label = 'on';
+ end
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(end);
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+
+ ERPsetops.butttons_datasets.Value = observe_ERPDAT.CURRENTERP;
+ ERPsetops.butttons_datasets.String = dsnames;
+
+ if strcmp(datasets{1},'No ERPset loaded')
+ Edit_label = 'off';
+ else
+ Edit_label = 'on';
+ end
+
+ ERPsetops.dupeselected.Enable=Edit_label;
+ ERPsetops.renameselected.Enable=Edit_label;
+ ERPsetops.suffix.Enable= Edit_label;
+ ERPsetops.clearselected.Enable=Edit_label;
+ ERPsetops.savebutton.Enable= Edit_label;
+ ERPsetops.saveasbutton.Enable=Edit_label;
+ ERPsetops.dotstoggle.Enable=Edit_label;
+ ERPsetops.butttons_datasets.Enable = Edit_label;
+ ERPsetops.export.Enable = Edit_label;
+
+
+ SelectedERP = observe_ERPDAT.CURRENTERP;
+ estudioworkingmemory('selectederpstudio',SelectedERP);
+
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+
+ ERPsetops.butttons_datasets.Min=1;
+ if size(datasets,1)<=2
+ ERPsetops.butttons_datasets.Max=size(datasets,1)+1;
+ else
+ ERPsetops.butttons_datasets.Max=size(datasets,1);
+ end
+
+ observe_ERPDAT.Process_messg =2;
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+ end
+
+
+
+%%----------------------Clear the selected ERPsets-------------------------
+ function cleardata(source,~)
+ erpworkingmemory('f_ERP_proces_messg','ERPsets>Clear');
+ observe_ERPDAT.Process_messg =1;
+
+ % global ERPCOM;
+ SelectedERP = ERPsetops.butttons_datasets.Value;
+ ERPset_remained = setdiff(1:size(datasets,1),SelectedERP);
+
+ if isempty(ERPset_remained)
+ if numel(findobj('tag', 'erpsets')) > 0
+ [observe_ERPDAT.ERP, observe_ERPDAT.ALLERP, ERPCOM] = pop_loaderp('filename', 'dummy.erp', 'Warning', 'on','multiload', 'off',...
+ 'History', 'implicit');
+ else
+ [observe_ERPDAT.ERP, observe_ERPDAT.ALLERP, ERPCOM] = pop_loaderp('filename', 'dummy.erp', 'Warning', 'on','multiload', 'off',...
+ 'History', 'implicit'); %If eeglab is not open, don't update
+ end
+ %Reset the datasets%%%%%
+
+ datasets = {};
+ datasets{1} = observe_ERPDAT.ALLERP(end).erpname;
+ datasets{2} = 1;
+ datasets{3} = 0;
+ datasets{4} = observe_ERPDAT.ALLERP(end).filename;
+ datasets{5} = observe_ERPDAT.ALLERP(end).filepath;
+
+ observe_ERPDAT.ALLERP = observe_ERPDAT.ALLERP(end);
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(end);
+ observe_ERPDAT.CURRENTERP = 1;
+ assignin('base','ERP',observe_ERPDAT.ERP)
+ else
+ observe_ERPDAT.ALLERP = observe_ERPDAT.ALLERP(ERPset_remained);
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(end);
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ datasets = {};
+ getDatasets();
+ end
+
+ datasets = sortdata(datasets);
+
+ dsnames = {};
+ for Numofsub = 1:size(datasets,1)
+ dsnames{Numofsub} = strcat(num2str(cell2mat(datasets(Numofsub,2))),'.',32,datasets{Numofsub,1});
+ end
+
+ if strcmp(datasets{1},'No ERPset loaded') && length(observe_ERPDAT.ALLERP)==1
+ dsnames = {''};
+ Edit_label = 'off';
+ else
+ Edit_label = 'on';
+ end
+
+ ERPsetops.butttons_datasets.String = dsnames;
+ ERPsetops.butttons_datasets.Value = observe_ERPDAT.CURRENTERP;
+ ERPsetops.dupeselected.Enable=Edit_label;
+ ERPsetops.renameselected.Enable=Edit_label;
+ ERPsetops.suffix.Enable= Edit_label;
+ ERPsetops.clearselected.Enable=Edit_label;
+ ERPsetops.savebutton.Enable= Edit_label;
+ ERPsetops.saveasbutton.Enable=Edit_label;
+ ERPsetops.dotstoggle.Enable=Edit_label;
+ ERPsetops.butttons_datasets.Min =1;
+ ERPsetops.butttons_datasets.Max =length(dsnames)+1;
+ ERPsetops.butttons_datasets.Enable = Edit_label;
+ ERPsetops.export.Enable = Edit_label;
+
+ SelectedERP = observe_ERPDAT.CURRENTERP;
+ estudioworkingmemory('selectederpstudio',SelectedERP);
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ observe_ERPDAT.Process_messg =2;
+
+ observe_ERPDAT.Count_ERP = observe_ERPDAT.Count_ERP+1;
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+ end
+
+
+%-------------------------- Save selected ERPsets-------------------------------------------
+ function savechecked(source,~)
+ erpworkingmemory('f_ERP_proces_messg','ERPsets>Save');
+ observe_ERPDAT.Process_messg =1;
+
+ pathName = estudioworkingmemory('ERP_save_folder');
+ if isempty(pathName)
+ pathName = cd;
+ end
+
+ Selected_erpset= estudioworkingmemory('selectederpstudio');
+ if isempty(Selected_erpset)
+ Selected_erpset = observe_ERPDAT.CURRENTERP;
+ if isempty(Selected_erpset)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+
+ try
+ ALLERPCOM = evalin('base','ALLERPCOM');
+ catch
+ ALLERPCOM = [];
+ assignin('base','ALLERPCOM',ALLERPCOM);
+ end
+
+ try
+ for Numoferpset = 1:length(Selected_erpset)
+
+ if Selected_erpset(Numoferpset) > length(observe_ERPDAT.ALLERP)
+ beep;
+ disp(['Index of selected ERP is lager than the length of ALLERP!!!']);
+ return;
+ end
+ ERP = observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset));
+ FileName = ERP.filename;
+
+ if isempty(FileName)
+ FileName =ERP.erpname;
+ end
+ [pathx, filename, ext] = fileparts(FileName);
+ filename = [filename '.erp'];
+ [observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset)), issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', filename, 'filepath',pathName);
+ [~, ALLERPCOM] = erphistory(observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset)), ALLERPCOM, ERPCOM);
+
+ end
+
+ observe_ERPDAT.Process_messg =2;
+ catch
+ beep;
+ observe_ERPDAT.Process_messg =3;
+ disp(['ERPsets>Save: Cannot save the selected ERPsets.']);
+ return;
+
+ end
+ end
+
+
+%------------------------- Save as-----------------------------------------
+ function savecheckedas(~,~)
+ erpworkingmemory('f_ERP_proces_messg','ERPsets>Save As');
+ observe_ERPDAT.Process_messg =1;
+
+ pathName = estudioworkingmemory('ERP_save_folder');
+ if isempty(pathName)
+ pathName = cd;
+ end
+
+ Selected_erpset= estudioworkingmemory('selectederpstudio');
+ if isempty(Selected_erpset)
+ Selected_erpset = observe_ERPDAT.CURRENTERP;
+ if isempty(Selected_erpset)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+
+
+ try
+ ALLERPCOM = evalin('base','ALLERPCOM');
+ catch
+ ALLERPCOM = [];
+ assignin('base','ALLERPCOM',ALLERPCOM);
+ end
+
+ for Numoferpset = 1:length(Selected_erpset)
+ if Selected_erpset(Numoferpset) > length(observe_ERPDAT.ALLERP)
+ beep;
+ disp('Index of selected ERP is lager than the length of ALLERP!!!');
+ return;
+ end
+
+ ERP = observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset));
+
+ [pathstr, namedef, ext] = fileparts(char(ERP.filename));
+ [erpfilename, erppathname, indxs] = uiputfile({'*.erp','ERP (*.erp)';...
+ '*.mat','ERP (*.erp)'}, ...
+ ['Save "',ERP.erpname,'" as'],...
+ fullfile(pathName,namedef));
+
+ if isequal(erpfilename,0)
+ disp('User selected Cancel')
+ return
+ end
+
+ [pathx, filename, ext] = fileparts(erpfilename);
+ [pathstr, erpfilename, ext] = fileparts(erpfilename) ;
+
+ if indxs==1
+ ext = '.erp';
+ elseif indxs==2
+ ext = '.mat';
+ else
+ ext = '.erp';
+ end
+ erpFilename = char(strcat(erpfilename,ext));
+ [observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset)), issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', erpFilename,...
+ 'filepath',erppathname);
+ [~, ALLERPCOM] = erphistory(observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset)), ALLERPCOM, ERPCOM);
+
+ end
+ observe_ERPDAT.Process_messg =2;
+
+ end
+
+
+%---------------- Enable/Disable dot structure-----------------------------
+ function toggledots(~,~)
+ pathName = erpworkingmemory('ERP_save_folder');
+ if isempty(pathName)
+ pathName =cd;
+ end
+ title = 'Select one forlder for saving files in following procedures';
+ sel_path = uigetdir(pathName,title);
+
+ if isequal(sel_path,0)
+ sel_path = cd;
+ end
+ userpath(sel_path);
+ cd(sel_path);
+ erpworkingmemory('ERP_save_folder',sel_path);
+ end
+
+
+%-----------------select the ERPset of interest--------------------------
+ function selectdata(source,~)
+ erpworkingmemory('f_ERP_proces_messg','ERPsets-select ERPset(s)');
+ observe_ERPDAT.Process_messg =1;
+
+ Selected_ERPsetlabel = source.Value;
+ estudioworkingmemory('selectederpstudio',Selected_ERPsetlabel);
+
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_ERPsetlabel);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+
+ Current_ERP_selected=Selected_ERPsetlabel(1);
+ observe_ERPDAT.CURRENTERP = Current_ERP_selected;
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_ERP_selected);
+
+ checked_ERPset_Index_bin_chan = S_erpplot.geterpbinchan.checked_ERPset_Index;
+
+ msgboxText = {};
+ if checked_ERPset_Index_bin_chan(1) ==1
+ msgboxText = ['Number of bins across ERPsets is different!'];
+ elseif checked_ERPset_Index_bin_chan(2)==2
+ msgboxText = ['Number of channels across ERPsets is different!'];
+ elseif checked_ERPset_Index_bin_chan(3) ==3
+ msgboxText = ['Type of data across ERPsets is different!'];
+ elseif checked_ERPset_Index_bin_chan(4)==4
+ msgboxText = ['Number of samples across ERPsets is different!'];
+ elseif checked_ERPset_Index_bin_chan(5)==5
+ msgboxText = ['Start time of epoch across ERPsets is different!'];
+ end
+ if ischar(msgboxText)
+ if checked_ERPset_Index_bin_chan(1) ==1 && checked_ERPset_Index_bin_chan(2) ==0
+ question = [ '%s\n See details at command window.\n\n',...
+ ' (a). "Bins" will be deactive on "Bins and Channel Selection".\n\n',...
+ ' (b). "Plot Scalp Maps" panel will be deactive.\n\n',...
+ ' (c). "Selected bin and chan" will be deactive on "Baseline correction & Linear detrend".\n\n',...
+ ' (d). "ERP Channel Operations" panel will be deactive.\n\n',...
+ ' (e). "ERP Bin Operations" panel will be deactive.\n\n',...
+ ' (f). "Covert Voltage to CSD" panel will be deactive.\n\n',...
+ ' (g). "Save values" will be deactive on "ERP Measurement Tool".\n\n',...
+ ' (h). "Average across ERPsets" will be deactive.\n\n'];
+ elseif checked_ERPset_Index_bin_chan(1) ==0 && checked_ERPset_Index_bin_chan(2) ==2
+
+ question = [ '%s\n See details at command window.\n\n',...
+ ' (a). "Channels" will be deactive on "Bins and Channel Selection".\n\n',...
+ ' (b). "Plot Scalp Maps" panel will be deactive.\n\n',...
+ ' (c). "Selected bin and chan" will be deactive on "Baseline correction & Linear detrend".\n\n',...
+ ' (d). "ERP Channel Operations" panel will be deactive.\n\n',...
+ ' (e). "ERP Bin Operations" panel will be deactive.\n\n',...
+ ' (f). "Covert Voltage to CSD" panel will be deactive.\n\n',...
+ ' (g). "Save values" will be deactive on "ERP Measurement Tool".\n\n',...
+ ' (h). "Average across ERPsets" will be deactive.\n\n'];
+ elseif checked_ERPset_Index_bin_chan(1) ==1 && checked_ERPset_Index_bin_chan(2) ==2
+ msgboxText = ['Both the number of channels and the number of bins vary across ERPsets!'];
+ question = [ '%s\n See details at command window.\n\n',...
+ ' (a). "Channels" and "Bins" will be deactive on "Bins and Channel Selection".\n\n',...
+ ' (b). "Plot Scalp Maps" panel will be deactive.\n\n',...
+ ' (c). "Selected bin and chan" will be deactive on "Baseline correction & Linear detrend".\n\n',...
+ ' (d). "ERP Channel Operations" panel will be deactive.\n\n',...
+ ' (e). "ERP Bin Operations" panel will be deactive.\n\n',...
+ ' (f). "Covert Voltage to CSD" panel will be deactive.\n\n',...
+ ' (g). "Save values" will be deactive on "ERP Measurement Tool".\n\n',...
+ ' (h). "Average across ERPsets" will be deactive.\n\n'];
+ else
+ msgboxText = [];
+ question = [ ];
+
+ end
+ if ~isempty(question)
+ BackERPLABcolor = [1 0.9 0.3];
+ title = 'EStudio: ERPsets';
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor)
+ button = questdlg(sprintf(question, msgboxText), title,'OK','OK');
+ set(0,'DefaultUicontrolBackgroundColor',oldcolor);
+ end
+ end
+
+ observe_ERPDAT.Process_messg =2;
+ observe_ERPDAT.Count_ERP = observe_ERPDAT.Count_ERP+1;
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ if numel(source.Value)==1
+ observe_ERPDAT.ERP_chan = [1:observe_ERPDAT.ERP.nchan];
+ observe_ERPDAT.ERP_bin = [1:observe_ERPDAT.ERP.nbin];
+ end
+ observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+ end
+
+
+
+% called datasets = sortdata(datasets), sorts datasets in order based on
+% parents
+ function varargout = sortdata(data)
+ cinds = [];
+ ndata = {}; % Sorted data
+ it = 1; % Iterator for row
+ for i = data' % Iterate thru all datasets
+ if cell2mat(i(3)) == 0 % Find base datasets (child of 0 means it's not reliant on another dataset)
+ [~, ic] = size(cinds);
+ cinds(1, ic+1) = cell2mat(i(2)); % Append dataset number to list of current indexes
+ ndata(it,:) = i'; % Put it in
+ it = it + 1;
+ end
+ end
+
+ cond = true;
+ while cond
+ ninds = []; % Reset new indexes
+ for i = data' % Iterate thru all data
+ for j = cinds % Iterate thru all parents
+ if cell2mat(i(3)) == j % Check to see if every datapoint is a child of the current layer
+ [~, nic] = size(ninds);
+ ninds(1, nic+1) = cell2mat(i(2)); % Append dataset number to the next round of parents
+ [ndr, ~] = size(ndata);
+ for v = 1:ndr
+ if cell2mat(ndata(v, 2)) == j
+ ndata(v+2:end+1,:) = ndata(v+1:end,:);
+ ndata(v+1,:) = i';
+ end
+ end
+ end
+ end
+ end
+ [~, nic] = size(ninds);
+ if nic == 0 % If we've gone thru all of them, there should be no new indexes
+ cond = false;
+ end
+ clear cinds
+ cinds = ninds; % Start again with ninds
+ end
+ varargout{1} = ndata;
+ end
+
+% Gets [ind, erp] for input ds where ds is a dataset structure, ind is the
+% index of the corresponding ERP, and ERP is the corresponding ERP
+% structure.
+ function varargout = ds2erp(ds)
+ [~,cvtc] = size(observe_ERPDAT.ALLERP);
+ for z = 1:cvtc
+ fp1 = observe_ERPDAT.ALLERP(1,z).filepath;
+ fp2 = cell2mat(ds(5));
+ fp1(regexp(fp1,'[/]')) = [];
+ fp2(regexp(fp2,'[/]')) = [];
+ if strcmp(observe_ERPDAT.ALLERP(1,z).erpname,cell2mat(ds(1)))&&strcmp(fp1,fp2)
+ varargout{1} = z;
+ varargout{2} = observe_ERPDAT.ALLERP(1,z);
+ end
+
+ end
+
+ end
+
+
+
+%%%--------------Up this panel--------------------------------------
+ function Count_currentERPChanged(~,~)
+
+ Selected_ERP= estudioworkingmemory('selectederpstudio');
+ if isempty(Selected_ERP)
+ Selected_ERP = observe_ERPDAT.CURRENTERP;
+ if isempty(Selected_ERP)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_ERP);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+
+ [chk, msgboxText] = f_ERP_chckerpindex(observe_ERPDAT.ALLERP, Selected_ERP);
+ if chk==1
+ Selected_ERP = observe_ERPDAT.CURRENTERP;
+ if isempty(Selected_ERP)
+ msgboxText = 'No ERPset was imported!!!';
+ title = 'EStudio: f_ERP_binoperation_GUI error.';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_ERP);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ estudioworkingmemory('selectederpstudio',Selected_ERP);
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ return;
+ end
+ ERPfilter_label = erpworkingmemory('ERPfilter');
+ def_baseline = erpworkingmemory('f_ERP_BLS_Detrend');
+ ERP_bin_opertion = erpworkingmemory('f_ERP_bin_opt');
+ ERP_simulation = erpworkingmemory('ERP_simulation');
+ if isempty(ERPfilter_label)
+ ERPfilter_label =1;
+ end
+ if isempty(def_baseline)
+ def_baseline{3} =1;
+ end
+ if isempty(ERP_bin_opertion)
+ ERP_bin_opertion =1;
+ end
+ if isempty(ERP_simulation)
+ ERP_simulation =1;
+ end
+ if ERPfilter_label ==1 || def_baseline{3}==1 || ERP_bin_opertion==1 || ERP_simulation==1
+ erpworkingmemory('ERPfilter',0);
+ def_baseline{3} = 0;
+ erpworkingmemory('f_ERP_BLS_Detrend',def_baseline);
+ erpworkingmemory('f_ERP_bin_opt',0);
+ erpworkingmemory('ERP_simulation',0);
+ datasets = {};
+ getDatasets()
+ datasets = sortdata(datasets);
+ dsnames = {};
+ if size(datasets,1)==1
+ if strcmp(datasets{1},'No ERPset loaded')
+ dsnames = {''};
+ Edit_label = 'off';
+ else
+ dsnames{1} = strcat(num2str(cell2mat(datasets(1,2))),'.',32,datasets{1,1});
+ Edit_label = 'on';
+ end
+ else
+ for Numofsub = 1:size(datasets,1)
+ dsnames{Numofsub} = strcat(num2str(cell2mat(datasets(Numofsub,2))),'.',32,datasets{Numofsub,1});
+ end
+ Edit_label = 'on';
+ end
+ ERPsetops.butttons_datasets.String = dsnames;
+ ERPsetops.butttons_datasets.Value = Selected_ERP;
+ if strcmp(datasets{1},'No ERPset loaded')
+ Edit_label = 'off';
+ else
+ Edit_label = 'on';
+ end
+ ERPsetops.dupeselected.Enable=Edit_label;
+ ERPsetops.renameselected.Enable=Edit_label;
+ ERPsetops.suffix.Enable= Edit_label;
+ ERPsetops.clearselected.Enable=Edit_label;
+ ERPsetops.savebutton.Enable= Edit_label;
+ ERPsetops.saveasbutton.Enable=Edit_label;
+ ERPsetops.dotstoggle.Enable=Edit_label;
+ ERPsetops.butttons_datasets.Enable = Edit_label;
+ ERPsetops.export.Enable = Edit_label;
+ estudioworkingmemory('selectederpstudio',Selected_ERP);
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_ERP);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ ERPsetops.butttons_datasets.Min=1;
+ ERPsetops.butttons_datasets.Max=size(datasets,1)+1;
+ end
+ ERPsetops.butttons_datasets.Value = Selected_ERP;
+ observe_ERPDAT.Count_ERP = observe_ERPDAT.Count_ERP+1;
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ end
+
+%----------------------Get the information of the updated ERPsets----------
+ function getDatasets()
+ if isempty(datasets)
+ datasets = {};
+ end
+ [s,~] = size(datasets);
+ del = [];
+ for i = 1:s
+ cond = false;
+ for j = observe_ERPDAT.ALLERP
+ if strcmp(j.filename, datasets{i,4}) && strcmp(j.filepath, datasets{i,5}) && strcmp(i.erpname, datasets{j,1})
+ cond = true;
+ end
+ end
+ if ~cond
+ del(end+1) = i;
+ end
+ end
+ for i = del
+ datasets(del,:) = [];
+ end
+ for i = observe_ERPDAT.ALLERP
+ cond = false;
+ [s,~] = size(datasets);
+ for j = 1:s
+ if strcmp(i.filename, datasets{j,4}) && strcmp(i.filepath, datasets{j,5}) && strcmp(i.erpname, datasets{j,1});
+ cond = true;
+ end
+ end
+ if ~cond
+ datasets{end+1,1} = i.erpname;
+ [r,~] = size(datasets);
+ datasets{end,2} = r;
+ datasets{end,3} = 0;
+ datasets{end,4} = i.filename;
+ datasets{end,5} = i.filepath;
+ end
+ end
+ end
+
+% function onErpChanged(~,~)
+% assignin('base','ERP',observe_ERPDAT.ERP);
+% end
+
+
+end
\ No newline at end of file
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_filtering_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_filtering_GUI.m
new file mode 100755
index 00000000..d54847ab
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_filtering_GUI.m
@@ -0,0 +1,1423 @@
+%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com
+%Center for Mind and Brain
+%University of California, Davis
+%Davis, CA, USA
+%Feb. 2022
+
+% ERPLAB Studio
+
+function varargout = f_ERP_filtering_GUI(varargin)
+
+gui_erp_filtering = struct();
+% global gui_erp_filtering;
+global observe_ERPDAT;
+% addlistener(observe_ERPDAT,'ALLERP_change',@erpschange);
+% addlistener(observe_ERPDAT,'ERP_change',@drawui_CB);
+% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange);
+addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged);
+
+%%---------------------------gui-------------------------------------------
+try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+catch
+ ColorB_def = [0.95 0.95 0.95];
+end
+if nargin == 0
+ fig = figure(); % Parent figure
+ ERP_filtering_box = uiextras.BoxPanel('Parent', fig, 'Title', 'Filtering', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel
+elseif nargin == 1
+ ERP_filtering_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Filtering', 'Padding', 5,'BackgroundColor',ColorB_def);
+else
+ ERP_filtering_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Filtering', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def);
+end
+
+
+
+try
+ FonsizeDefault = varargin{2};
+catch
+ FonsizeDefault = [];
+end
+if isempty(FonsizeDefault)
+ FonsizeDefault = f_get_default_fontsize();
+end
+erp_filtering_gui(FonsizeDefault);
+
+varargout{1} = ERP_filtering_box;
+%%********************Draw the GUI for ERP measurement tool*****************
+ function erp_filtering_gui(FonsizeDefault)
+ try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+ catch
+ ColorB_def = [0.95 0.95 0.95];
+ end
+ if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded')
+ Enable_label = 'off';
+ else
+ Enable_label = 'on';
+ end
+
+ try
+ nchan = observe_ERPDAT.ERP.nchan;
+ fs = observe_ERPDAT.ERP.srate;
+ catch
+ nchan =1;
+ end
+ defx = {0 30 2 1:nchan 1 'butter' 0 []};
+ def = erpworkingmemory('pop_filterp');
+ if isempty(def)
+ def = defx;
+ end
+ if fs <=0
+ fs =256;
+ end
+ locutoff = def{1}; % for high pass filter
+ hicutoff = def{2}; % for low pass filter
+ filterorder = def{3};
+ chanArray = def{4};
+ filterallch = def{5};
+ fdesign = def{6};
+ remove_dc = def{7};
+
+ typef = 0;
+ if strcmpi(fdesign,'butter') % 0 means Butterworth
+ if filterorder> 8
+ filterorder =2;
+ end
+ else
+ filterorder = 2;
+ end
+
+ if locutoff >= fs/2 || locutoff<=0
+ locutoff = floor(fs/2)-1;
+ end
+
+
+ if hicutoff>=fs/2 || hicutoff<=0
+ hicutoff = floor(fs/2)-1;
+ end
+
+ if isempty(locutoff)
+ locutoff = 0;
+ end
+
+ if isempty(hicutoff)
+ hicutoff = 0;
+ end
+
+ locutoff = 0;
+ hicutoff = 20;
+ highpass_toggle_value = 1;
+ lowpass_toggle_value =1;
+ hp_halfamp_enable = 'on';
+ lp_halfamp_Enable = 'on';
+ hp_halfpow_string = '---';
+ lp_halfpow_string = '---';
+ Apply_ERP_filter_enable = 'on';
+ Advance_ERP_filter_enable = 'on';
+ hp_tog_enable = 'on';
+ lp_tog_enable = 'on';
+
+ if ~strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded')
+
+ %%High-pass filtering
+ [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder, hicutoff,locutoff,fs);
+ if locutoff > 0 && hicutoff ==0
+ highpass_toggle_value = 1;
+ hp_halfamp_enable = 'on';
+ lowpass_toggle_value = 0;
+ lp_halfamp_Enable = 'off';
+ hp_halfpow_string =num2str(roundn(frec3dB(1),-2));
+ lp_halfpow_string ='---';
+ end
+ %%Low pass filtering
+ if hicutoff > 0 && locutoff ==0
+ highpass_toggle_value = 0;
+ hp_halfamp_enable = 'off';
+ lowpass_toggle_value = 1;
+ lp_halfamp_Enable = 'on';
+ lp_halfpow_string =num2str(roundn(frec3dB,-2));
+ hp_halfpow_string ='---';
+ end
+ %%Band pass filtering or notch filtering
+ if locutoff >0 && hicutoff>0
+ highpass_toggle_value = 1;
+ hp_halfamp_enable = 'on';
+ hp_halfpow_string =num2str(roundn(frec3dB(2),-2));
+ lowpass_toggle_value = 1;
+ lp_halfamp_Enable = 'on';
+ lp_halfpow_string =num2str(roundn(frec3dB(1),-2));
+ end
+ else
+ hp_halfamp_enable = 'off';
+ lp_halfamp_Enable = 'off';
+ Apply_ERP_filter_enable = 'off';
+ Advance_ERP_filter_enable = 'off';
+
+ lp_tog_enable = 'off';
+ hp_tog_enable = 'off';
+ hp_halfpow_string ='--';
+ lp_halfpow_string ='---';
+ end
+ gui_erp_filtering.filtering = uiextras.VBox('Parent',ERP_filtering_box,'BackgroundColor',ColorB_def);
+
+ %%-----------------------------Setting for bin and chan--------------------
+ gui_erp_filtering.bin_chan_title = uiextras.HBox('Parent',gui_erp_filtering.filtering,'BackgroundColor',ColorB_def);
+ uicontrol('Style','text','Parent',gui_erp_filtering.bin_chan_title,'String','Bin and Chan Selection:','FontWeight','bold',...
+ 'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ gui_erp_filtering.filter_bin_chan_option = uiextras.HBox('Parent', gui_erp_filtering.filtering,'Spacing',1,'BackgroundColor',ColorB_def);
+
+ gui_erp_filtering.all_bin_chan = uicontrol('Style', 'radiobutton','Parent', gui_erp_filtering.filter_bin_chan_option,...
+ 'String','All (Recommended)','callback',@All_bin_chan,'Value',1,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ gui_erp_filtering.Selected_bin_chan = uicontrol('Style', 'radiobutton','Parent', gui_erp_filtering.filter_bin_chan_option,...
+ 'String','Selected bin & chan','callback',@Selected_bin_chan,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ set(gui_erp_filtering.filter_bin_chan_option, 'Sizes',[130 170]);
+
+
+ %%--------------------------Setting for IIR filter------------------------------
+ gui_erp_filtering.IIR_title = uiextras.HBox('Parent',gui_erp_filtering.filtering,'BackgroundColor',ColorB_def);
+ uicontrol('Style','text','Parent',gui_erp_filtering.IIR_title,'String','Setting for IIR Butterworth:',...
+ 'FontWeight','bold','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+
+ gui_erp_filtering.filt_grid = uiextras.Grid('Parent',gui_erp_filtering.filtering,'BackgroundColor',ColorB_def);
+ % first column
+ uiextras.Empty('Parent',gui_erp_filtering.filt_grid); % 1A
+ gui_erp_filtering.hp_tog = uicontrol('Style','checkbox','Parent',gui_erp_filtering.filt_grid,'String','High Pass',...
+ 'callback',@highpass_toggle,'Value',0,'Enable','off','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 1B
+ gui_erp_filtering.lp_tog = uicontrol('Style','checkbox','Parent',gui_erp_filtering.filt_grid,'String','Low Pass',...
+ 'callback',@lowpass_toggle,'Value',1,'Enable','off','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 1C
+
+
+ % second column
+ uicontrol('Style','text','Parent',gui_erp_filtering.filt_grid,'String','Half Amp.','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 2A
+ gui_erp_filtering.hp_halfamp = uicontrol('Style','edit','Parent',gui_erp_filtering.filt_grid,...
+ 'callback',@hp_halfamp,'Enable','off','FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % 2B
+ if strcmp(hp_halfamp_enable,'off');
+ if typef<2
+ gui_erp_filtering.hp_halfamp.String = '0';
+ else
+ gui_erp_filtering.hp_halfamp.String = '60';
+ end
+
+ else
+ gui_erp_filtering.hp_halfamp.String = num2str(locutoff);
+ end
+ gui_erp_filtering.lp_halfamp = uicontrol('Style','edit','Parent',gui_erp_filtering.filt_grid,...
+ 'callback',@lp_halfamp,'Enable',lp_halfamp_Enable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % 2C
+ if strcmp(lp_halfamp_Enable,'off')
+ gui_erp_filtering.lp_halfamp.String = '20';
+ else
+ gui_erp_filtering.lp_halfamp.String = num2str(hicutoff);
+ end
+ % third column
+ uicontrol('Style','text','Parent',gui_erp_filtering.filt_grid,'String','Half Power','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 3A
+ gui_erp_filtering.hp_halfpow = uicontrol('Style','text','Parent',gui_erp_filtering.filt_grid,...
+ 'String',hp_halfpow_string,'Enable','off','BackgroundColor','y','FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % 3B
+
+ gui_erp_filtering.lp_halfpow = uicontrol('Style','text','Parent',gui_erp_filtering.filt_grid,...
+ 'String',lp_halfpow_string,'Enable','off','BackgroundColor','y','FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % 3C
+
+ % fourth column
+ uiextras.Empty('Parent',gui_erp_filtering.filt_grid); % 4A
+ uicontrol('Style','text','Parent',gui_erp_filtering.filt_grid,'String','Hz','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 4B
+ uicontrol('Style','text','Parent',gui_erp_filtering.filt_grid,'String','Hz','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 4C
+ set(gui_erp_filtering.filt_grid, 'ColumnSizes',[90 70 70 40],'RowSizes',[20 -1 -1]);
+
+
+ gui_erp_filtering.rolloff_row = uiextras.HBox('Parent', gui_erp_filtering.filtering,'BackgroundColor',ColorB_def);
+ uicontrol('Style','text','Parent',gui_erp_filtering.rolloff_row,'String','Roll-Off','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 1D
+ Roll_off = {'12','24','36','48'};
+ gui_erp_filtering.roll_off = uicontrol('Style','popupmenu','Parent',gui_erp_filtering.rolloff_row,'String',Roll_off,...
+ 'callback',@ERP_filtering_rolloff,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % 2D
+ if filterorder ==2
+ gui_erp_filtering.roll_off.Value = 1;
+ elseif filterorder ==4
+ gui_erp_filtering.roll_off.Value = 2;
+
+ elseif filterorder ==6
+ gui_erp_filtering.roll_off.Value = 3;
+
+ elseif filterorder ==8
+ gui_erp_filtering.roll_off.Value = 4;
+ end
+ uicontrol('Style','text','Parent',gui_erp_filtering.rolloff_row,'String','dB/Octave','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 3D
+
+
+ gui_erp_filtering.REMOVE_DC = uiextras.HBox('Parent', gui_erp_filtering.filtering,'BackgroundColor',ColorB_def);
+ gui_erp_filtering.DC_remove = uicontrol('Style','checkbox','Parent', gui_erp_filtering.REMOVE_DC,...
+ 'String','Remove DC Offset','Value',0,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);%,'callback',@remove_dc
+ % uiextras.Empty('Parent',gui_erp_filtering.REMOVE_DC);
+
+ gui_erp_filtering.filt_buttons = uiextras.HBox('Parent', gui_erp_filtering.filtering,'BackgroundColor',ColorB_def);
+ % uiextras.Empty('Parent', gui_erp_filtering.filt_buttons);
+ uicontrol('Style','pushbutton','Parent',gui_erp_filtering.filt_buttons,'String','?',...
+ 'callback',@ERP_filter_help,'Enable','on','FontSize',16,'BackgroundColor',[1 1 1]);
+ gui_erp_filtering.advanced = uicontrol('Style','pushbutton','Parent',gui_erp_filtering.filt_buttons,'String','Advanced',...
+ 'callback',@advanced_ERP_filter,'Enable',Advance_ERP_filter_enable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]);
+
+ gui_erp_filtering.apply = uicontrol('Style','pushbutton','Parent',gui_erp_filtering.filt_buttons,'String','Run',...
+ 'callback',@ERP_filter_apply,'Enable',Apply_ERP_filter_enable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]);
+ set( gui_erp_filtering.filtering,'Sizes',[20 20 20 80 20 20 30]);
+
+ end
+
+
+
+%%****************************************************************************************************************************************
+%%******************* Subfunctions ***************************************************************************************************
+%%****************************************************************************************************************************************
+
+%%---------------------help-----------------------------
+
+ function ERP_filter_help(~,~)
+ web('https://github.com/lucklab/erplab/wiki/Filtering','-browser');
+
+ end
+%%----------------------all bin and all chan-------------------------------
+ function All_bin_chan(~,~)
+ gui_erp_filtering.all_bin_chan.Value = 1;
+ gui_erp_filtering.Selected_bin_chan.Value = 0;
+ end
+
+%%----------------------selected bin and all chan-------------------------------
+ function Selected_bin_chan(~,~)
+ gui_erp_filtering.all_bin_chan.Value = 0;
+ gui_erp_filtering.Selected_bin_chan.Value = 1;
+ end
+
+
+
+%%--------------------------------High-pass filtering toggle------------------
+ function highpass_toggle(source,~)
+ try
+ fs = observe_ERPDAT.ERP.srate;
+ catch
+ return;
+ end
+ locutoff = 0.1;
+ try
+ filterorder = 2*gui_erp_filtering.roll_off.Value;
+ catch
+ filterorder =2;
+ gui_erp_filtering.roll_off.Value=1;
+ end
+ typef = 0;
+
+ if source.Value == 0
+ gui_erp_filtering.hp_halfamp.Enable ='off';
+ gui_erp_filtering.hp_halfpow.Enable ='off';
+ gui_erp_filtering.hp_halfamp.String = '0';
+ gui_erp_filtering.hp_halfpow.String = '---';
+ if gui_erp_filtering.lp_tog.Value ==0
+ gui_erp_filtering.roll_off.Enable = 'off';
+ end
+ else
+ [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder,0,locutoff,fs);
+ gui_erp_filtering.hp_tog.Value =1;
+ gui_erp_filtering.hp_halfamp.Enable ='on';
+ gui_erp_filtering.hp_halfamp.String = num2str(locutoff);
+ gui_erp_filtering.hp_halfpow.String = num2str(frec3dB(1));
+ gui_erp_filtering.hp_halfpow.Enable ='off';
+ gui_erp_filtering.hp_halfpow.String = num2str(frec3dB);
+ gui_erp_filtering.roll_off.Enable = 'on';
+ end
+
+ end
+
+
+%%--------------------------------Low-pass filtering toggle------------------
+ function lowpass_toggle(source,~)
+
+ try
+ fs = observe_ERPDAT.ERP.srate;
+ catch
+ return;
+ end
+
+ typef = 0;
+ try
+ filterorder = 2*gui_erp_filtering.roll_off.Value;
+ catch
+ filterorder =2;
+ gui_erp_filtering.roll_off.Value=1;
+ end
+
+ hicutoff = floor((fs/2-1)*5/10);
+ if source.Value == 0
+ gui_erp_filtering.lp_halfamp.Enable ='off';
+ gui_erp_filtering.lp_halfpow.Enable ='off';
+ gui_erp_filtering.lp_halfamp.String = '0';
+ gui_erp_filtering.lp_halfpow.String = '---';
+ if gui_erp_filtering.hp_tog.Value ==0
+ gui_erp_filtering.roll_off.Enable = 'off';
+ end
+ else
+ [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder, hicutoff,0, fs);
+ gui_erp_filtering.lp_tog.Value =1;
+ gui_erp_filtering.lp_halfamp.Enable ='on';
+ gui_erp_filtering.lp_halfamp.String = num2str(hicutoff);
+ gui_erp_filtering.lp_halfpow.String = num2str(frec3dB);
+ gui_erp_filtering.lp_halfpow.Enable ='off';
+ gui_erp_filtering.roll_off.Enable = 'on';
+ end
+
+ end
+
+
+
+%%---------------------Half amplitude for high pass filtering--------------
+ function hp_halfamp(Source,~)
+ try
+ fs = observe_ERPDAT.ERP.srate;
+ catch
+ return;
+ end
+
+ typef = 0;
+ try
+ filterorder = 2*gui_erp_filtering.roll_off.Value;
+ catch
+ filterorder =2;
+ gui_erp_filtering.roll_off.Value=1;
+ end
+
+ valueh = str2num(Source.String);
+ if length(valueh)~=1
+ beep;
+ msgboxText = ['Filtring - Invalid input for high-pass filter cutoff'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if valueh>=fs/2
+ beep;
+ msgboxText = ['Filtring - The high-pass filter cutoff should be smaller than',32,num2str(fs/2),'Hz'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if valueh<0.001
+ beep;
+ msgboxText = ['Filtring - We strongly recommend the high-pass filter cutoff is larger than 0.001Hz'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ valuel = 0;
+ [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder, valuel, valueh, fs);
+ gui_erp_filtering.hp_halfamp.Enable ='on';
+ gui_erp_filtering.hp_halfamp.String = num2str(valueh);
+ gui_erp_filtering.hp_halfpow.String = num2str(frec3dB);
+ gui_erp_filtering.hp_halfpow.Enable ='off';
+ end
+
+
+
+%%---------------------Half amplitude for low pass filtering---------------
+ function lp_halfamp(Source,~)
+
+ try
+ fs = observe_ERPDAT.ERP.srate;
+ catch
+ return;
+ end
+ try
+ filterorder = 2*gui_erp_filtering.roll_off.Value;
+ catch
+ filterorder =2;
+ gui_erp_filtering.roll_off.Value=1;
+ end
+ valuel = str2num(Source.String);
+ if length(valuel)~=1 || isempty(valuel)
+ beep;
+ msgboxText = ['Filtring - Invalid input for low-pass filter cutoff'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if valuel>=fs/2
+ beep;
+ msgboxText = ['Filtring - The low-pass filter cutoff should be smaller than',32,num2str(fs/2),'Hz'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if valuel<0.001
+ beep;
+ msgboxText = ['Filtring - We strongly recommend the low-pass filter cutoff is larger than 0.001Hz'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ %if the valueh is between 0.1 and fs/2 Hz
+ typef = 0;
+ valueh = 0;
+ [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder, valuel, valueh, fs);
+ gui_erp_filtering.lp_halfamp.Enable ='on';
+ gui_erp_filtering.lp_halfamp.String = num2str(valuel);
+ gui_erp_filtering.lp_halfpow.String = num2str(frec3dB(1));
+ gui_erp_filtering.lp_halfpow.Enable ='off';
+
+ end
+
+
+%%----------------------------Setting for roll-off-------------------------
+ function ERP_filtering_rolloff(Source,~)
+ Source_value = Source.Value;
+
+ try
+ nchan = observe_ERPDAT.ERP.nchan;
+ fs = observe_ERPDAT.ERP.srate;
+ catch
+ return;
+ end
+ filterorder = 2*Source_value;
+ typef = 0;
+ valuel = str2num(gui_erp_filtering.lp_halfamp.String);%% for low-pass filter
+ valueh = str2num(gui_erp_filtering.hp_halfamp.String);%%for high-pass filter
+
+ if gui_erp_filtering.lp_tog.Value ==1
+
+ if length(valuel)~=1 || isempty(valuel)
+ beep;
+ msgboxText = ['Filtring - Invalid input for low-pass filter cutoff'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if valuel>=fs/2
+ beep;
+ msgboxText = ['Filtring - The low-pass filter cutoff should be smaller than',32,num2str(fs/2),'Hz'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if gui_erp_filtering.hp_tog.Value ==0
+ if valuel<0.001
+ beep;
+ msgboxText = ['Filtring - We strongly recommend the low-pass filter cutoff is larger than 0.001Hz'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+
+ end
+
+ if gui_erp_filtering.hp_tog.Value ==1
+ if length(valueh)~=1
+ beep;
+ msgboxText = ['Filtring - Invalid input for high-pass filter cutoff'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if valueh>=fs/2
+ beep;
+ msgboxText = ['Filtring - The high-pass filter cutoff should be smaller than',32,num2str(fs/2),'Hz'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if gui_erp_filtering.lp_tog.Value ==0
+ if valueh<0.001
+ beep;
+ msgboxText = ['Filtring - We strongly recommend the high-pass filter cutoff is larger than 0.001Hz'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+
+ end
+
+ if gui_erp_filtering.hp_tog.Value ==1 && gui_erp_filtering.lp_tog.Value ==1
+ if valueh >0 && valueh >0 && valueh >=valuel
+ beep;
+ msgboxText = ['Filtring - The lowest bandpass cuttoff is the highest bandpass cuttoff'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if valueh==0 && valuel==0
+ beep;
+ msgboxText = ['Filtring - Either Lowest bandpass cuttoff or the highest bandpass cuttoff or both is larger than 0.01Hz'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+
+ if valuel> 0 && valueh ==0
+ [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder, valuel, 0, fs);
+ gui_erp_filtering.lp_halfpow.String = num2str(frec3dB);
+ elseif valuel== 0 && valueh > 0
+ [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder,0, valueh,fs);
+ gui_erp_filtering.hp_halfpow.String = num2str(frec3dB);
+ elseif valuel> 0 && valueh > 0
+ [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder,valuel, valueh,fs);
+ gui_erp_filtering.lp_halfpow.String = num2str(frec3dB(1));
+ gui_erp_filtering.hp_halfpow.String = num2str(frec3dB(2));
+ end
+ end
+
+%-----------------------change for ALLERPs---------------------------------
+% function erpschange(~,~)
+%
+%
+% end
+
+
+%%------------------Setting for apply option--------------------------------
+ function ERP_filter_apply(~,~)
+ try
+ nchan = observe_ERPDAT.ERP.nchan;
+ fs = observe_ERPDAT.ERP.srate;
+ catch
+ return;
+ end
+
+ defx = {0 30 2 1:nchan 1 'butter' 0 []};
+ def = erpworkingmemory('pop_filterp');
+ if isempty(def)
+ def = defx;
+ end
+
+ remove_dc = gui_erp_filtering.DC_remove.Value;
+ filterorder = 2*gui_erp_filtering.roll_off.Value;
+ locutoff = str2num(gui_erp_filtering.hp_halfamp.String);%%
+ hicutoff = str2num(gui_erp_filtering.lp_halfamp.String);
+
+ if isempty(locutoff)
+ locutoff =0;
+ end
+ if isempty(hicutoff)
+ hicutoff =0;
+ end
+
+ if gui_erp_filtering.lp_tog.Value ==1
+
+ if length(hicutoff)~=1 || isempty(hicutoff)
+ beep;
+ msgboxText = ['Filtring - Invalid input for low-pass filter cutoff'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if hicutoff>=fs/2
+ beep;
+ msgboxText = ['Filtring - The low-pass filter cutoff should be smaller than',32,num2str(fs/2),'Hz'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if gui_erp_filtering.hp_tog.Value ==0
+ if hicutoff<0.001
+ beep;
+ msgboxText = ['Filtring - We strongly recommend the low-pass filter cutoff is larger than 0.001Hz'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+
+ end
+
+ if gui_erp_filtering.hp_tog.Value ==1
+ if length(locutoff)~=1
+ beep;
+ msgboxText = ['Filtring - Invalid input for high-pass filter cutoff'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if locutoff>=fs/2
+ beep;
+ msgboxText = ['Filtring - The high-pass filter cutoff should be smaller than',32,num2str(fs/2),'Hz'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if gui_erp_filtering.lp_tog.Value ==0
+ if locutoff<0.001
+ beep;
+ msgboxText = ['Filtring - We strongly recommend the high-pass filter cutoff is larger than 0.001Hz'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+
+ end
+
+ if gui_erp_filtering.hp_tog.Value ==1 && gui_erp_filtering.lp_tog.Value ==1
+ if locutoff==0 && hicutoff==0
+ beep;
+ msgboxText = ['Filtring - Either Lowest bandpass cuttoff or the highest bandpass cuttoff or both is larger than 0.01Hz'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+
+ if remove_dc==1
+ rdc = 'on';
+ else
+ rdc = 'off';
+ end
+ filterallch = def{5};
+
+ if filterallch
+ chanArray = 1:nchan;
+ end
+
+
+ fdesign = 'butter';
+ if ~strcmpi(fdesign, 'notch') && locutoff==0 && hicutoff>0 % Butter (IIR) and FIR%% low-pass filter
+ ftype = 'lowpass';
+ cutoff = hicutoff;
+ elseif ~strcmpi(fdesign, 'notch') && locutoff>0 && hicutoff==0 % Butter (IIR) and FIR
+ ftype = 'highpass';
+ cutoff = locutoff;
+ elseif ~strcmpi(fdesign, 'notch') && locutoff>0 && hicutoff>0 && locutoff0 && hicutoff>0 && locutoff>hicutoff% Butter (IIR) and FIR
+ ftype = 'simplenotch';
+ cutoff = [locutoff hicutoff];
+ elseif ~strcmpi(fdesign, 'notch') && locutoff==0 && hicutoff==0 % Butter (IIR) and FIR
+ msgboxText = 'I beg your pardon?';
+ title = 'EStudio: f_ERP_filtering_GUI() !';
+ errorfound(msgboxText, title);
+ return;
+ else
+ beep;
+ msgboxText = ['Filtring - Invalid type of filter'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+
+ end
+
+ erpworkingmemory('pop_filterp', {locutoff,hicutoff,filterorder,chanArray,filterallch,fdesign,remove_dc});
+
+ Selected_erpset = estudioworkingmemory('selectederpstudio');
+ if isempty(Selected_erpset)
+ Selected_erpset = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ estudioworkingmemory('selectederpstudio',Selected_erpset);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ checked_ERPset_Index_bin_chan =S_binchan.checked_ERPset_Index;
+
+ %%-------------loop start for filtering the selected ERPsets-----------------------------------
+
+ erpworkingmemory('f_ERP_proces_messg','Filtering');
+ observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started.
+ ALLERPCOM = evalin('base','ALLERPCOM');
+
+ try
+ FilterMethod = 'filtered';
+ if numel(Selected_erpset)>1
+
+ Answer = f_ERP_save_multi_file(observe_ERPDAT.ALLERP,Selected_erpset,FilterMethod);
+ if isempty(Answer)
+ beep;
+ disp('User selected Cancel');
+ return;
+ end
+
+ if ~isempty(Answer{1})
+ ALLERP_advance = Answer{1};
+ Save_file_label = Answer{2};
+ end
+
+ elseif numel(Selected_erpset)==1
+ Save_file_label =0;
+ ALLERP_advance = observe_ERPDAT.ALLERP;
+ end
+
+ BinArray = [];
+ ChanArray = [];
+ for Numoferp = 1:numel(Selected_erpset)
+ if Selected_erpset(Numoferp)> length(observe_ERPDAT.ALLERP)
+ beep;
+ msgboxText = ['Filtring - No corresponding ERP exists in ALLEERP'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ break;
+ end
+
+ if (checked_ERPset_Index_bin_chan(1)==1 || checked_ERPset_Index_bin_chan(2)==2) && gui_erp_filtering.Selected_bin_chan.Value ==1
+ if checked_ERPset_Index_bin_chan(1) ==1
+ msgboxText = ['Number of bins across the selected ERPsets is different!'];
+ elseif checked_ERPset_Index_bin_chan(2)==2
+ msgboxText = ['Number of channels across the selected ERPsets is different!'];
+ elseif checked_ERPset_Index_bin_chan(1)==1 && checked_ERPset_Index_bin_chan(2)==2
+ msgboxText = ['Number of channels and bins vary across the selected ERPsets'];
+ end
+ question = [ '%s\n\n "All" will be active instead of "Selected bin and chan".'];
+ title = 'EStudio: Filtering';
+ button = questdlg(sprintf(question, msgboxText), title,'OK','OK');
+ BinArray = [];
+ ChanArray = [];
+ end
+
+ ERP = ALLERP_advance(Selected_erpset(Numoferp));
+ if (checked_ERPset_Index_bin_chan(1)==0 && checked_ERPset_Index_bin_chan(2)==0) && gui_erp_filtering.Selected_bin_chan.Value ==1
+ try
+ BinArray = S_binchan.bins{1};
+ ChanArray = S_binchan.elecs_shown{1};
+ [chk, msgboxText] = f_ERP_chckbinandchan(ERP, BinArray, [],1);
+ if chk(1)==1
+ BinArray = [1:ERP.nbin];
+ end
+ [chk, msgboxText] = f_ERP_chckbinandchan(ERP,[], ChanArray,2);
+ if chk(2)==1
+ ChanArray = [1:ERP.nchan];
+ end
+
+ catch
+ BinArray = [1:ERP.nbin];
+ ChanArray = [1:ERP.nchan];
+ end
+ end
+
+ if gui_erp_filtering.all_bin_chan.Value == 1
+ BinArray = [1:ERP.nbin];
+ ChanArray = [1:ERP.nchan];
+ end
+ ERP_AF = ERP;
+ %%Only the slected bin and chan were selected to remove baseline and detrending and others are remiained.
+ [ERP, ERPCOM] = pop_filterp(ERP, chanArray, 'Filter',ftype, 'Design', fdesign, 'Cutoff', cutoff, 'Order', filterorder, 'RemoveDC', rdc,...
+ 'Saveas', 'off', 'History', 'gui');
+
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ if Numoferp==1
+ [~, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);
+ end
+ if ~isempty(BinArray)&& ~isempty(ChanArray)
+ try
+ ERP_AF.bindata(ChanArray,:,BinArray) = ERP.bindata(ChanArray,:,BinArray);
+ ERP.bindata = ERP_AF.bindata;
+ catch
+ ERP = ERP;
+ end
+ end
+
+ if numel(Selected_erpset) ==1
+ Answer = f_ERP_save_single_file(char(strcat(ERP.erpname,'_',FilterMethod)),ERP.filename,Selected_erpset(Numoferp));
+ if isempty(Answer)
+ disp('User selected cancel.');
+ return;
+ end
+
+ if ~isempty(Answer)
+ ERPName = Answer{1};
+ if ~isempty(ERPName)
+ ERP.erpname = ERPName;
+ end
+ fileName_full = Answer{2};
+ if isempty(fileName_full)
+ ERP.filename = '';
+ ERP.saved = 'no';
+ elseif ~isempty(fileName_full)
+
+ [pathstr, file_name, ext] = fileparts(fileName_full);
+
+ if strcmp(pathstr,'')
+ pathstr = cd;
+ end
+ ERP.filename = [file_name,ext];
+ ERP.filepath = pathstr;
+ ERP.saved = 'yes';
+ %%----------save the current sdata as--------------------
+ [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath);
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ end
+ end
+ end
+ observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP;
+ if Save_file_label
+ [pathstr, file_name, ext] = fileparts(ERP.filename);
+ ERP.filename = [file_name,'.erp'];
+ [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath);
+ % [~, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ end
+
+
+ end
+ %%close the wait bar
+ % [~, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);
+ assignin('base','ALLERPCOM',ALLERPCOM);
+ assignin('base','ERPCOM',ERPCOM);
+ erpworkingmemory('ERPfilter',1);
+ try
+ Selected_ERP_afd = [length(observe_ERPDAT.ALLERP)-numel(Selected_erpset)+1:length(observe_ERPDAT.ALLERP)];
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP)-numel(Selected_erpset)+1;
+ catch
+ Selected_ERP_afd = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ end
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+
+ estudioworkingmemory('selectederpstudio',Selected_ERP_afd);
+
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+
+ observe_ERPDAT.Process_messg =2;
+ catch
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ Selected_ERP_afd =observe_ERPDAT.CURRENTERP;
+ estudioworkingmemory('selectederpstudio',Selected_ERP_afd);
+ erpworkingmemory('ERPfilter',1);
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Process_messg =3;%%There is erros in processing procedure
+ return;
+ end
+ observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+ end
+
+%%-------------------Setting for advance option---------------------------
+ function advanced_ERP_filter(~,~)
+
+ try
+ nchan = observe_ERPDAT.ERP.nchan;
+ fs = observe_ERPDAT.ERP.srate;
+ catch
+ fs = 256;
+ nchan = 30;
+ end
+ defx = {0 30 2 1:nchan 1 'butter' 0 []};
+ def = erpworkingmemory('pop_filterp');
+
+ if isempty(def)
+ def = defx;
+ else
+ def{4} = def{4}(ismember_bc2(def{4},1:nchan));
+ end
+
+ def{1} = str2num(gui_erp_filtering.hp_halfamp.String);
+ def{2} = str2num(gui_erp_filtering.lp_halfamp.String);
+ if gui_erp_filtering.hp_tog.Value ==1
+ if isempty(def{1}) || def{1} ==0
+ def{1} = 0.01;
+ end
+ end
+ if gui_erp_filtering.lp_tog.Value ==1
+ if isempty(def{2}) || def{2} ==0
+ def{2} = floor((fs/2-1)*5/10);
+ end
+ end
+
+ def{7} = gui_erp_filtering.DC_remove.Value;
+ def{8} = [];
+ fdesign = 'butter';
+ def{3} = 2*gui_erp_filtering.roll_off.Value;
+ def{6} = fdesign;
+
+ Selected_erpset = estudioworkingmemory('selectederpstudio');
+ if isempty(Selected_erpset)
+ Selected_erpset = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ estudioworkingmemory('selectederpstudio',Selected_erpset);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ checked_ERPset_Index_bin_chan =S_binchan.checked_ERPset_Index;
+
+ BinArray = [];
+ ChanArray =[];
+
+ if checked_ERPset_Index_bin_chan(1) ==1 || checked_ERPset_Index_bin_chan(2) ==2
+ BinArray = [];
+ ChanArray =[];
+ def{5} =1;
+ else
+ try
+ BinArray = S_binchan.bins{1};
+ ChanArray = S_binchan.elecs_shown{1};
+ [chk, msgboxText] = f_ERP_chckbinandchan(observe_ERPDAT.ERP, BinArray, [],1);
+ if chk(1)==1
+ BinArray = [1:observe_ERPDAT.ERP.nbin];
+ end
+ [chk, msgboxText] = f_ERP_chckbinandchan(observe_ERPDAT.ERP,[], ChanArray,2);
+ if chk(2)==1
+ ChanArray = [1:observe_ERPDAT.ERP.nchan];
+ end
+
+ catch
+ BinArray = [1:observe_ERPDAT.ERP.nbin];
+ ChanArray = [1:observe_ERPDAT.ERP.nchan];
+ end
+ def{5} =0;
+ end
+
+
+ if (checked_ERPset_Index_bin_chan(1)==1 && checked_ERPset_Index_bin_chan(2)==2)
+ BinArray = [];
+ ChanArray = [];
+ end
+
+ if (checked_ERPset_Index_bin_chan(1)==0 && checked_ERPset_Index_bin_chan(2)==0) && gui_erp_filtering.all_bin_chan.Value
+ BinArray = [];
+ ChanArray = [];
+ end
+
+ def{9} = BinArray;
+ def{4} = ChanArray;
+ %%call the GUI for advance option
+ answer = f_basicfilterGUI2(observe_ERPDAT.ERP, def);
+ if isempty(answer)
+ beep;
+ disp('User selected Cancel')
+ return;
+ end
+
+ defx = {answer{1},answer{2},answer{3},answer{4},answer{5},answer{6},answer{7},answer{8}};
+ erpworkingmemory('pop_filterp',defx);
+ % erpworkingmemory('filterp_advanced', 1);
+
+ locutoff = answer{1}; % for high pass filter
+ hicutoff = answer{2}; % for low pass filter
+ filterorder = answer{3};
+ ChanArray = answer{4};
+ filterallch = answer{5};
+ fdesign = answer{6};
+ remove_dc = answer{7};
+ BinArray = answer{9};
+
+ if checked_ERPset_Index_bin_chan(1) ==1 || checked_ERPset_Index_bin_chan(2) ==2
+ BinArray = [];
+ ChanArray =[];
+ end
+
+ if locutoff >= fs/2 || locutoff< 0
+ locutoff = floor(fs/2)-1;
+ end
+ if hicutoff>=fs/2 || hicutoff< 0
+ hicutoff = floor(fs/2)-1;
+ end
+
+ if isempty(locutoff)
+ locutoff = 0;
+ end
+
+ if isempty(hicutoff)
+ hicutoff = 0;
+ end
+ %%-----------setting for IIR butter----------------------
+ if strcmpi(fdesign,'butter')
+ typef = 0;
+ gui_erp_filtering.roll_off.Value = filterorder/2;
+ gui_erp_filtering.roll_off.String = {'12','24','36','48'}';
+ gui_erp_filtering.roll_off.Enable = 'on';
+ gui_erp_filtering.DC_remove.Value = remove_dc;
+ %%High-pass filtering
+ [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder, hicutoff,locutoff,fs);
+ if locutoff > 0 && (isempty(hicutoff) || hicutoff ==0 )
+ gui_erp_filtering.hp_tog.Value = 1;
+ gui_erp_filtering.hp_tog.Enable ='on';
+ gui_erp_filtering.lp_tog.Value = 0;
+ gui_erp_filtering.lp_tog.Enable ='on';
+
+ gui_erp_filtering.hp_halfamp.String = num2str(locutoff);
+ gui_erp_filtering.hp_halfamp.Enable = 'on';
+
+ gui_erp_filtering.lp_halfamp.String = num2str(hicutoff);
+ gui_erp_filtering.lp_halfamp.Enable = 'off';
+ gui_erp_filtering.hp_halfpow.String = num2str(roundn(frec3dB(1),-2));
+ gui_erp_filtering.lp_halfpow.String = '---';
+ end
+ %%Low pass filtering
+ if hicutoff > 0 && (isempty(locutoff) || locutoff ==0)
+ gui_erp_filtering.lp_tog.Value = 1;
+ gui_erp_filtering.lp_tog.Enable ='on';
+ gui_erp_filtering.hp_tog.Value = 0;
+ gui_erp_filtering.hp_tog.Enable ='on';
+ gui_erp_filtering.lp_halfamp.String = num2str(hicutoff);
+ gui_erp_filtering.lp_halfamp.Enable = 'on';
+ gui_erp_filtering.hp_halfamp.String = num2str(locutoff);
+ gui_erp_filtering.hp_halfamp.Enable = 'off';
+ gui_erp_filtering.lp_halfpow.String = num2str(roundn(frec3dB(1),-2));
+ gui_erp_filtering.hp_halfpow.String = '---';
+
+ end
+ %%Band pass filtering or notch filtering
+ if locutoff >0 && hicutoff>0
+ gui_erp_filtering.hp_tog.Value = 1;
+ gui_erp_filtering.hp_tog.Enable ='on';
+ gui_erp_filtering.lp_tog.Value = 1;
+ gui_erp_filtering.lp_tog.Enable ='on';
+ gui_erp_filtering.hp_halfamp.String = num2str(locutoff);
+ gui_erp_filtering.hp_halfamp.Enable = 'on';
+ gui_erp_filtering.lp_halfamp.String = num2str(hicutoff);
+ gui_erp_filtering.lp_halfamp.Enable = 'on';
+ gui_erp_filtering.hp_halfpow.String = num2str(roundn(frec3dB(2),-2));
+ gui_erp_filtering.lp_halfpow.String = num2str(roundn(frec3dB(1),-2));
+ end
+ end%%setting end for IIR butter filter
+ %%*************Filter the selected ERPsets***************************
+ if remove_dc==1
+ rdc = 'on';
+ else
+ rdc = 'off';
+ end
+ filterallch = def{5};
+ if ~strcmpi(fdesign, 'notch') && locutoff==0 && hicutoff>0 % Butter (IIR) and FIR%% low-pass filter
+ ftype = 'lowpass';
+ cutoff = hicutoff;
+ elseif ~strcmpi(fdesign, 'notch') && locutoff>0 && hicutoff==0 % Butter (IIR) and FIR
+ ftype = 'highpass';
+ cutoff = locutoff;
+ elseif ~strcmpi(fdesign, 'notch') && locutoff>0 && hicutoff>0 && locutoff0 && hicutoff>0 && locutoff>hicutoff% Butter (IIR) and FIR
+ ftype = 'simplenotch';
+ cutoff = [locutoff hicutoff];
+ elseif strcmpi(fdesign, 'notch') && locutoff==hicutoff % Parks-McClellan Notch
+ ftype = 'PMnotch';
+ cutoff = hicutoff;
+
+ elseif ~strcmpi(fdesign, 'notch') && locutoff==0 && hicutoff==0 % Butter (IIR) and FIR
+ msgboxText = 'I beg your pardon?';
+ title = 'EStudio: f_ERP_filtering_GUI() !';
+ errorfound(msgboxText, title);
+ return;
+ else
+ beep;
+ msgboxText = ['Filtring - Invalid type of filter'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+
+ if strcmpi(fdesign, 'notch') && locutoff==hicutoff
+ if 3*filterorder>=length(observe_ERPDAT.ERP.times)
+ beep;
+ msgboxText = ['Filtring -The length of the data must be more than three times the filter order'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+
+
+ %%-------------loop start for filtering the selected ERPsets-----------------------------------
+ erpworkingmemory('f_ERP_proces_messg','Filtering (Advanced)');
+ observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started.
+ ALLERPCOM = evalin('base','ALLERPCOM');
+ try
+ Suffix_label = 1;
+ FilterMethod_str = char(strcat('filtered'));
+ if numel(Selected_erpset)>1
+ Answer = f_ERP_save_multi_file(observe_ERPDAT.ALLERP,Selected_erpset,FilterMethod_str);
+ if isempty(Answer)
+ beep;
+ disp('User selected Cancel');
+ return;
+ end
+
+ if ~isempty(Answer{1})
+ ALLERP_advance = Answer{1};
+ Save_file_label = Answer{2};
+ end
+
+ elseif numel(Selected_erpset)==1
+ Save_file_label =0;
+ ALLERP_advance = observe_ERPDAT.ALLERP;
+ end
+
+ for Numoferp = 1:numel(Selected_erpset)
+
+ if Selected_erpset(Numoferp)> length(observe_ERPDAT.ALLERP)
+ beep;
+ msgboxText = ['Filtring - No corresponding ERP exists in ALLEERP'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ break;
+ end
+
+ if (checked_ERPset_Index_bin_chan(1)==1 || checked_ERPset_Index_bin_chan(2)==2) && gui_erp_filtering.Selected_bin_chan.Value ==1
+ if checked_ERPset_Index_bin_chan(1) ==1
+ msgboxText = ['Number of bins across the selected ERPsets is different!'];
+ elseif checked_ERPset_Index_bin_chan(2)==2
+ msgboxText = ['Number of channels across the selected ERPsets is different!'];
+ elseif checked_ERPset_Index_bin_chan(1)==1 && checked_ERPset_Index_bin_chan(2)==2
+ msgboxText = ['Number of channels and bins vary across the selected ERPsets'];
+ end
+ question = [ '%s\n\n "All" will be active instead of "Selected bin and chan".'];
+ title = 'EStudio: Filtering';
+ button = questdlg(sprintf(question, msgboxText), title,'OK','OK');
+ BinArray = [];
+ ChanArray = [];
+ end
+
+ if (checked_ERPset_Index_bin_chan(1)==0 && checked_ERPset_Index_bin_chan(2)==0) && gui_erp_filtering.Selected_bin_chan.Value ==1
+ try
+ BinArray = S_binchan.bins{1};
+ ChanArray = S_binchan.elecs_shown{1};
+ catch
+ BinArray = [1:ERP.nbin];
+ ChanArray = [1:ERP.nchan];
+ end
+ end
+
+
+ ERP = ALLERP_advance(Selected_erpset(Numoferp));
+ ERP_before_bl = ERP;
+
+ [ERP, ERPCOM] = pop_filterp(ERP, [1:ERP.nchan], 'Filter',ftype, 'Design', fdesign, 'Cutoff', cutoff, 'Order', filterorder, 'RemoveDC', rdc,...
+ 'Saveas', 'off', 'History', 'gui');
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ if Numoferp ==1
+ [~, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);
+ end
+ %%Only the slected bin and chan were selected to remove baseline and detrending and others are remiained.
+ if ~isempty(BinArray) && ~isempty(ChanArray)
+ try
+ ERP_before_bl.bindata(ChanArray,:,BinArray) = ERP.bindata(ChanArray,:,BinArray);
+ ERP.bindata = ERP_before_bl.bindata;
+ catch
+ ERP = ERP;
+ end
+ end
+ %%Rename single file------------------------------------
+ if numel(Selected_erpset) ==1
+ Answer = f_ERP_save_single_file(char(strcat(ERP.erpname,'_',FilterMethod_str)),ERP.filename,Selected_erpset(Numoferp));
+ if isempty(Answer)
+ disp('User selected Cancel');
+ return;
+ end
+
+ if ~isempty(Answer)
+ ERPName = Answer{1};
+ if ~isempty(ERPName)
+ ERP.erpname = ERPName;
+ end
+ fileName_full = Answer{2};
+ if isempty(fileName_full)
+ ERP.filename = '';
+ ERP.saved = 'no';
+ elseif ~isempty(fileName_full)
+ [pathstr, file_name, ext] = fileparts(fileName_full);
+ if strcmp(pathstr,'')
+ pathstr = cd;
+ end
+ ERP.filename = [file_name,ext];
+ ERP.filepath = pathstr;
+ ERP.saved = 'yes';
+ %%----------save the current sdata as--------------------
+ [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath);
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ end
+ end
+ end
+
+ if Save_file_label
+ [pathstr, file_name, ext] = fileparts(ERP.filename);
+ ERP.filename = [file_name,'.erp'];
+ ERP.saved = 'yes';
+ [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath);
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ else
+
+ ERP.filename = '';
+ ERP.saved = 'no';
+ end
+ observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP;
+ end
+
+ % [~, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);
+ assignin('base','ALLERPCOM',ALLERPCOM);
+ assignin('base','ERPCOM',ERPCOM);
+ erpworkingmemory('ERPfilter',1);
+
+ try
+ Selected_ERP_afd = [length(observe_ERPDAT.ALLERP)-numel(Selected_erpset)+1:length(observe_ERPDAT.ALLERP)];
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP)-numel(Selected_erpset)+1;
+ catch
+ Selected_ERP_afd = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ end
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ estudioworkingmemory('selectederpstudio',Selected_ERP_afd);
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Process_messg =2;
+ catch
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ Selected_ERP_afd =observe_ERPDAT.CURRENTERP;
+ estudioworkingmemory('selectederpstudio',Selected_ERP_afd);
+ erpworkingmemory('ERPfilter',1);
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+
+ observe_ERPDAT.Process_messg =3;
+ return;
+ end
+ observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+ end
+
+
+%%-------------------Setting for the whole panel of fitering based on ALLERP and CURRENTERP--------------
+ function Count_currentERPChanged(~,~)
+ if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded') || strcmp(observe_ERPDAT.ERP.datatype,'EFFT')
+ gui_erp_filtering.apply.Enable = 'off';
+ gui_erp_filtering.advanced.Enable = 'off';
+ gui_erp_filtering.roll_off.Enable = 'off';
+ gui_erp_filtering.hp_halfamp.Enable = 'off';
+ gui_erp_filtering.lp_halfamp.Enable = 'off';
+ gui_erp_filtering.hp_tog.Enable = 'off';
+ gui_erp_filtering.lp_tog.Enable = 'off';
+ gui_erp_filtering.all_bin_chan.Enable = 'off';
+ gui_erp_filtering.Selected_bin_chan.Enable = 'off';
+ else
+
+ gui_erp_filtering.all_bin_chan.Enable = 'on';
+ gui_erp_filtering.Selected_bin_chan.Enable = 'on';
+ locutoff = str2num(gui_erp_filtering.hp_halfamp.String);%%for high pass filter
+ hicutoff = str2num(gui_erp_filtering.lp_halfamp.String);%% for low pass filter
+
+ if isempty(locutoff)
+ locutoff =0;
+ gui_erp_filtering.hp_halfamp.String = '0';
+ end
+ if isempty(hicutoff)
+ hicutoff = 0;
+ gui_erp_filtering.lp_halfamp.String = '0';
+ end
+ fs = observe_ERPDAT.ERP.srate;
+ if fs <=0
+ fs = 256;
+ end
+ typef = 0;
+ filterorder = 2*gui_erp_filtering.roll_off.Value;
+ [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder, hicutoff,locutoff,fs);
+ if locutoff > 0 && hicutoff ==0
+ highpass_toggle_value = 1;
+ hp_halfamp_enable = 'on';
+ lowpass_toggle_value = 0;
+ lp_halfamp_Enable = 'off';
+ hp_halfpow_string =num2str(roundn(frec3dB(1),-2));
+ lp_halfpow_string ='---';
+ end
+ %%Low pass filtering
+ if hicutoff > 0 && locutoff ==0
+ highpass_toggle_value = 0;
+ hp_halfamp_enable = 'off';
+ lowpass_toggle_value = 1;
+ lp_halfamp_Enable = 'on';
+ lp_halfpow_string =num2str(roundn(frec3dB,-2));
+ hp_halfpow_string ='---';
+ end
+ %%Band pass filtering or notch filtering
+ if locutoff >0 && hicutoff>0
+ highpass_toggle_value = 1;
+ hp_halfamp_enable = 'on';
+ hp_halfpow_string =num2str(roundn(frec3dB(2),-2));
+ lowpass_toggle_value = 1;
+ lp_halfamp_Enable = 'on';
+ lp_halfpow_string =num2str(roundn(frec3dB(1),-2));
+ end
+
+ if locutoff==0 && hicutoff==0
+ highpass_toggle_value = 0;
+ hp_halfamp_enable = 'off';
+ hp_halfpow_string ='0';
+ lowpass_toggle_value = 0;
+ lp_halfamp_Enable = 'off';
+ lp_halfpow_string ='0';
+ end
+
+ gui_erp_filtering.apply.Enable = 'on';
+ gui_erp_filtering.advanced.Enable = 'on';
+ gui_erp_filtering.roll_off.Enable = 'on';
+ gui_erp_filtering.hp_halfpow.String = hp_halfpow_string;
+ gui_erp_filtering.lp_halfpow.String = lp_halfpow_string;
+ gui_erp_filtering.hp_halfamp.Enable = hp_halfamp_enable;
+ gui_erp_filtering.lp_halfamp.Enable = lp_halfamp_Enable;
+ gui_erp_filtering.hp_tog.Value = highpass_toggle_value;
+ gui_erp_filtering.lp_tog.Value = lowpass_toggle_value;
+
+ gui_erp_filtering.hp_tog.Enable = 'on';
+ gui_erp_filtering.lp_tog.Enable = 'on';
+
+ try
+ S_ws = evalin('base','S');
+ Selected_erpset = S_ws.geterpset.selectederp;
+ catch
+ Selected_erpset = observe_ERPDAT.CURRENTERP;
+ end
+
+ Check_Selected_erpset = [0 0 0 0 0 0 0];
+ if numel(Selected_erpset)>1
+ try
+ S_ws = evalin('base','S');
+ Check_Selected_erpset = S_binchan.checked_ERPset_Index;
+ catch
+ Check_Selected_erpset = f_checkerpsets(observe_ERPDAT.ALLERP,Selected_erpset);
+ end
+ end
+ if Check_Selected_erpset(1) ==1 || Check_Selected_erpset(2) == 2
+ gui_erp_filtering.Selected_bin_chan.Value =0;
+ gui_erp_filtering.Selected_bin_chan.Enable = 'off';
+ gui_erp_filtering.all_bin_chan.Value = 1;
+ gui_erp_filtering.all_bin_chan.Enable = 'on';
+ end
+
+ end
+ end
+
+
+end
+%Progem end: ERP Measurement tool
\ No newline at end of file
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_grandaverageGUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_grandaverageGUI.m
new file mode 100755
index 00000000..99e0061d
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_grandaverageGUI.m
@@ -0,0 +1,481 @@
+%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com
+%Center for Mind and Brain
+%University of California, Davis
+%Davis, CA, USA
+%Feb. 2022
+
+% ERPLAB Studio
+
+function varargout = f_ERP_grandaverageGUI(varargin)
+global observe_ERPDAT;
+addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged);
+
+
+gui_erp_grdavg = struct();
+
+%-----------------------------Name the title----------------------------------------------
+% global ERP_grdavg_gui;
+[version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+if nargin == 0
+ fig = figure(); % Parent figure
+ ERP_grdavg_gui = uiextras.BoxPanel('Parent', fig, 'Title', 'Average across ERPsets ', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel
+elseif nargin == 1
+ ERP_grdavg_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Average across ERPsets ', 'Padding', 5,'BackgroundColor',ColorB_def);
+else
+ ERP_grdavg_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Average across ERPsets ', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def);
+end
+
+%-----------------------------Draw the panel-------------------------------------
+try
+ FonsizeDefault = varargin{2};
+catch
+ FonsizeDefault = [];
+end
+if isempty(FonsizeDefault)
+ FonsizeDefault = f_get_default_fontsize();
+end
+drawui_erp_bin_operation(FonsizeDefault)
+varargout{1} = ERP_grdavg_gui;
+
+ function drawui_erp_bin_operation(FonsizeDefault)
+ FontSize_defualt = FonsizeDefault;
+
+ if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded')
+ Enable_label = 'off';
+ else
+ Enable_label = 'on';
+ end
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+ %%--------------------channel and bin setting----------------------
+ gui_erp_grdavg.DataSelBox = uiextras.VBox('Parent', ERP_grdavg_gui,'BackgroundColor',ColorB_def);
+
+ %%Parameters
+ gui_erp_grdavg.weigavg_title = uiextras.HBox('Parent', gui_erp_grdavg.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_grdavg.weigavg = uicontrol('Style','checkbox','Parent', gui_erp_grdavg.weigavg_title,...
+ 'String','Use weighted average based on trial numbers','Value',0,...
+ 'callback',@checkbox_weigavg,'FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F
+
+ gui_erp_grdavg.excldnullbin_title = uiextras.HBox('Parent', gui_erp_grdavg.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_grdavg.excldnullbin = uicontrol('Style','checkbox','Parent', gui_erp_grdavg.excldnullbin_title,...
+ 'String','','Value',0,'Enable','off','FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F
+ gui_erp_grdavg.excldnullbin.String = 'Exclude any null bin from non-weighted averaing (recommended)';
+
+
+ gui_erp_grdavg.jacknife_title = uiextras.HBox('Parent', gui_erp_grdavg.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_grdavg.jacknife = uicontrol('Style','checkbox','Parent', gui_erp_grdavg.jacknife_title,...
+ 'String','','Value',0,'FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F
+ gui_erp_grdavg.jacknife.String = 'Include Jackknife subaverages (creates multiple ERPsets)';
+
+
+ gui_erp_grdavg.warn_title = uiextras.HBox('Parent', gui_erp_grdavg.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_grdavg.warn = uicontrol('Style','checkbox','Parent', gui_erp_grdavg.warn_title,...
+ 'String','','Value',0,'callback',@checkbox_warn,'FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F
+ gui_erp_grdavg.warn.String = 'Warning if any subjects who exceed the epoch rejection threshold (%) ';
+ gui_erp_grdavg.warn_edit = uicontrol('Style','edit','Parent', gui_erp_grdavg.warn_title,...
+ 'String','','callback',@warn_edit,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F
+ % set(gui_erp_grdavg.hr_title,'Sizes',[210,50]);
+ set(gui_erp_grdavg.warn_title,'Sizes',[220,70]);
+
+
+ gui_erp_grdavg.cmpsd_title = uiextras.HBox('Parent', gui_erp_grdavg.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_grdavg.cmpsd = uicontrol('Style','checkbox','Parent', gui_erp_grdavg.cmpsd_title,...
+ 'String','Compute point-by-point SEM','Value',1,'FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F
+
+
+ gui_erp_grdavg.cbdatq_title = uiextras.HBox('Parent', gui_erp_grdavg.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_grdavg.cbdatq = uicontrol('Style','checkbox','Parent', gui_erp_grdavg.cbdatq_title,...
+ 'String','','Value',1,'callback',@checkbox_cbdatq,'FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F
+ gui_erp_grdavg.cbdatq.String = 'Combine data quality measures ';
+
+ gui_erp_grdavg.cbdatq_def = uicontrol('Style','radiobutton','Parent', gui_erp_grdavg.cbdatq_title,...
+ 'String','defaults','Value',1,'callback',@cbdatq_def,'FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F
+
+ gui_erp_grdavg.cbdatq_custom = uicontrol('Style','radiobutton','Parent', gui_erp_grdavg.cbdatq_title,...
+ 'String','custom combo','Value',0,'callback',@cbdatq_custom,'FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F
+ gui_erp_grdavg.cbdatq_custom.String = 'custom combo ';
+ set(gui_erp_grdavg.cbdatq_title,'Sizes',[120 70 70]);
+
+ gui_erp_grdavg.cbdatq_custom_option_title = uiextras.HBox('Parent', gui_erp_grdavg.DataSelBox,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_grdavg.cbdatq_custom_option_title);
+ gui_erp_grdavg.cbdatq_custom_op = uicontrol('Style','pushbutton','Parent', gui_erp_grdavg.cbdatq_custom_option_title,...
+ 'String','set custom DQ combo','callback',@cbdatq_custom_op,'Enable','off','FontSize',FontSize_defualt,'BackgroundColor',[1 1 1]); % 2F
+
+ gui_erp_grdavg.location_title = uiextras.HBox('Parent', gui_erp_grdavg.DataSelBox,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent',gui_erp_grdavg.location_title);
+ uicontrol('Style','pushbutton','Parent',gui_erp_grdavg.location_title,...
+ 'String','?','callback',@tool_link,'FontSize',16,'BackgroundColor',[1 1 1],'Max',10); % 2F
+ uiextras.Empty('Parent',gui_erp_grdavg.location_title);
+ gui_erp_grdavg.run = uicontrol('Style','pushbutton','Parent',gui_erp_grdavg.location_title,...
+ 'String','Run','callback',@apply_run,'FontSize',FontSize_defualt,'Enable',Enable_label);
+ uiextras.Empty('Parent',gui_erp_grdavg.location_title);
+ set(gui_erp_grdavg.location_title,'Sizes',[20 95 30 95 20]);
+
+ set(gui_erp_grdavg.DataSelBox,'Sizes',[25,30,30,30,25,30,25,30]);
+ end
+
+
+
+%%**************************************************************************%%
+%%--------------------------Sub function------------------------------------%%
+%%**************************************************************************%%
+
+
+
+%%---------------checkbox for weighted average-----------------------------
+ function checkbox_weigavg(source,~)
+ if ~source.Value
+ set(gui_erp_grdavg.excldnullbin,'Enable','on','Value',0);
+ else
+ set(gui_erp_grdavg.excldnullbin,'Enable','off','Value',0);
+ end
+ end
+
+%%-------------------checkbox for warning----------------------------------
+ function checkbox_warn(source,~)
+ if ~source.Value
+ gui_erp_grdavg.warn_edit.Enable = 'off';
+ else
+ gui_erp_grdavg.warn_edit.Enable = 'on';
+ end
+ end
+
+
+%%%%----------------checkbox for combining data quality measures-----------
+ function checkbox_cbdatq(source,~)
+ checkad = source.Value;
+ if checkad
+ gui_erp_grdavg.cbdatq_custom.Value = 0;
+ gui_erp_grdavg.cbdatq_def.Value = 1;
+ gui_erp_grdavg.cbdatq_custom_op.Enable = 'off';
+ gui_erp_grdavg.cbdatq_def.Enable = 'on';
+ gui_erp_grdavg.cbdatq_custom.Enable = 'on';
+ else
+ gui_erp_grdavg.cbdatq_custom.Enable = 'off';
+ gui_erp_grdavg.cbdatq_def.Enable = 'off';
+ gui_erp_grdavg.cbdatq_custom_op.Enable = 'off';
+ end
+ end
+%%%%----------------default setting for combining data quality measures----
+ function cbdatq_def(~,~)
+ gui_erp_grdavg.cbdatq_custom.Value = 0;
+ gui_erp_grdavg.cbdatq_def.Value = 1;
+ gui_erp_grdavg.cbdatq_custom_op.Enable = 'off';
+ end
+
+%%%%----------------Custom setting for combining data quality measures----
+ function cbdatq_custom(~,~)
+ gui_erp_grdavg.cbdatq_custom.Value = 1;
+ gui_erp_grdavg.cbdatq_def.Value = 0;
+ gui_erp_grdavg.cbdatq_custom_op.Enable = 'on';
+ end
+
+%%-----------------define the epoch rejection threshold (%) ----------------------------
+ function warn_edit(source,~)
+ rejection_peft = str2num(source.String);
+ if isempty(rejection_peft)
+ gui_erp_grdavg.warn_edit.String = '';
+ beep;
+ msgboxText = ['Average across ERPsets - Invalid artifact detection proportion.\n'...
+ 'Please, enter a number between 0 and 100.'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if rejection_peft<0 || rejection_peft>100
+ gui_erp_grdavg.warn_edit.String = '';
+ beep;
+ msgboxText = ['Average across ERPsets - Invalid artifact detection proportion.\n'...
+ 'Please, enter a number between 0 and 100.'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+
+%%-----------Setting for custom DQ combo----------------------------------
+ function cbdatq_custom_op(~,~)
+
+ GAv_combo_defaults.measures = [1, 2, 3]; % Use first 3 DQ measures
+ GAv_combo_defaults.methods = [2, 2, 2]; % Use the 2nd combo method, Root-Mean Square, for each
+ GAv_combo_defaults.measure_names = {'Baseline Measure - SD';'Point-wise SEM'; 'aSME'};
+ GAv_combo_defaults.method_names = {'Pool ERPSETs, GrandAvg mean','Pool ERPSETs, GrandAvg RMS'};
+ GAv_combo_defaults.str = {'Baseline Measure - SD, GrandAvg RMS';'Point-wise SEM, GrandAvg RMS'; 'aSME GrandAvg RMS'};
+ custom_spec = grandaverager_DQ(GAv_combo_defaults);
+ estudioworkingmemory('grandavg_custom_DQ',custom_spec);
+ end
+%%---------------------CSD tool link-------------------------------------
+ function tool_link(~,~)
+ web('https://github.com/lucklab/erplab/wiki/Averaging-Across-ERPSETS-_-Creating-Grand-Averages','-browser');
+ end
+
+
+%%---------------------Run-------------------------------------------------
+ function apply_run(~,~)
+ pathName_def = erpworkingmemory('ERP_save_folder');
+ if isempty(pathName_def)
+ pathName_def =cd;
+ end
+
+ Selectederp_Index= estudioworkingmemory('selectederpstudio');
+ if isempty(Selectederp_Index)
+ Selectederp_Index = observe_ERPDAT.CURRENTERP;
+ if isempty(Selectederp_Index)
+ beep;
+ msgboxText = ['Average across ERPsets - No ERPset was selected'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+
+
+ if numel(Selectederp_Index)<2
+ beep;
+ msgboxText = ['Average across ERPsets - Two ERPsets,at least,were selected'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ optioni = 0; %1 means from a filelist, 0 means from erpsets menu
+
+ erpset = Selectederp_Index;
+ if gui_erp_grdavg.warn.Value
+ artcrite = str2num(gui_erp_grdavg.warn_edit.String);
+ else
+ artcrite = 100;
+ end
+
+ if isempty(artcrite) || artcrite<0 || artcrite>100
+ beep;
+ msgboxText = ['Average across ERPsets - Invalid artifact detection proportion.\n'...
+ 'Please, enter a number between 0 and 100.'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ %%Send message to Message panel
+ erpworkingmemory('f_ERP_proces_messg','Average across ERPsets');
+ observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started.
+
+ Weightedg = gui_erp_grdavg.weigavg.Value;
+ wavg = gui_erp_grdavg.warn.Value; % 0;1
+ excnullbin = gui_erp_grdavg.excldnullbin.Value; % 0;1
+ stderror = gui_erp_grdavg.cmpsd.Value; % 0;1
+ jk = gui_erp_grdavg.jacknife.Value; % 0;1
+ if jk
+ Answer = f_ERP_save_single_file(strcat('_jackknife'),'',length(observe_ERPDAT.ALLERP)+1);
+ else
+ Answer = f_ERP_save_single_file(strcat('grand'),'',length(observe_ERPDAT.ALLERP)+1);
+ end
+ if isempty(Answer)
+ beep;
+ disp('User selectd cancal');
+ return;
+ end
+ erpName_new = '';
+ fileName_new = '';
+ pathName_new = pathName_def;
+ Save_file_label =0;
+ if ~isempty(Answer)
+ ERPName = Answer{1};
+ if ~isempty(ERPName)
+ erpName_new = ERPName;
+ end
+ fileName_full = Answer{2};
+ if isempty(fileName_full)
+ fileName_new = '';
+ Save_file_label =0;
+ elseif ~isempty(fileName_full)
+
+ [pathstr, file_name, ext] = fileparts(fileName_full);
+ ext = '.erp';
+ if strcmp(pathstr,'')
+ pathstr = pathName_def;
+ end
+ fileName_new = [file_name,ext];
+ pathName_new = pathstr;
+ Save_file_label =1;
+ end
+ end
+
+ if jk
+ jkerpname = erpName_new;
+ jkfilename =fileName_new ;
+ else
+ jkerpname = ''; % erpname for JK grand averages
+ jkfilename = ''; % filename for JK grand averages
+ end
+
+
+ GAv_combo_defaults.measures = [1, 2, 3]; % Use first 3 DQ measures
+ GAv_combo_defaults.methods = [2, 2, 2]; % Use the 2nd combo method, Root-Mean Square, for each
+ GAv_combo_defaults.measure_names = {'Baseline Measure - SD';'Point-wise SEM'; 'aSME'};
+ GAv_combo_defaults.method_names = {'Pool ERPSETs, GrandAvg mean','Pool ERPSETs, GrandAvg RMS'};
+ GAv_combo_defaults.str = {'Baseline Measure - SD, GrandAvg RMS';'Point-wise SEM, GrandAvg RMS'; 'aSME GrandAvg RMS'};
+ if ~gui_erp_grdavg.cbdatq.Value
+ dq_option = 0; % data quality combine option. 0 - off, 1 - on/default, 2 - on/custom
+ elseif gui_erp_grdavg.cbdatq.Value && gui_erp_grdavg.cbdatq_def.Value
+ dq_option = 1;
+
+ dq_spec = GAv_combo_defaults;
+ elseif gui_erp_grdavg.cbdatq.Value && gui_erp_grdavg.cbdatq_custom.Value
+ dq_option = 2;
+ dq_spec = estudioworkingmemory('grandavg_custom_DQ');
+ if isempty(dq_spec)
+ dq_spec = GAv_combo_defaults;
+ end
+ end
+
+ if stderror==1
+ stdsstr = 'on';
+ else
+ stdsstr = 'off';
+ end
+ if excnullbin==1
+ excnullbinstr = 'on'; % exclude null bins.
+ else
+ excnullbinstr = 'off';
+ end
+ if wavg==1
+ wavgstr = 'on';
+ else
+ wavgstr = 'off';
+ end
+ if Weightedg
+ Weightedstr = 'on';
+ else
+ Weightedstr = 'off';
+ end
+
+ ALLERPCOM = evalin('base','ALLERPCOM');
+ try
+ ALLERP = observe_ERPDAT.ALLERP;
+ if jk==1 % Jackknife
+
+ [ALLERP, ERPCOM] = pop_jkgaverager(ALLERP, 'Erpsets', erpset, 'Criterion', artcrite,...
+ 'SEM', stdsstr, 'Weighted', Weightedstr, 'Erpname', jkerpname, 'Filename', jkfilename,...
+ 'DQ_flag',dq_option,'DQ_spec',dq_spec,'Warning', wavgstr);
+ Selected_ERP_afd = setdiff([1:length(ALLERP)],[1:length(observe_ERPDAT.ALLERP)]);
+ observe_ERPDAT.ALLERP = ALLERP;
+ observe_ERPDAT.CURRENTERP = Selected_ERP_afd(1);
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ estudioworkingmemory('selectederpstudio',Selected_ERP_afd);
+
+ if Save_file_label==1
+ for Numofselectederp =1:numel(Selected_ERP_afd)
+ ERP_save = observe_ERPDAT.ALLERP(Selected_ERP_afd(Numofselectederp));
+ ERP_save.filepath = pathName_new;
+ [ERP, issave, ERPCOM] = pop_savemyerp(ERP_save, 'erpname', ERP_save.erpname, 'filename', ERP_save.erpname, 'filepath',ERP_save.filepath);
+ end
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ end
+
+ else
+ [ERP, ERPCOM] = pop_gaverager(ALLERP, 'Erpsets', erpset,'Criterion', artcrite, 'SEM', stdsstr,...
+ 'ExcludeNullBin', excnullbinstr,'Weighted', Weightedstr, 'Saveas', 'off',...
+ 'DQ_flag',dq_option,'DQ_spec',dq_spec,'Warning', wavgstr, 'History', 'gui');
+ ERP.erpname = erpName_new;
+ ERP.filename = fileName_new;
+ ERP.filepath = pathName_new;
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);
+ % [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP;
+ Selected_ERP_afd = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ estudioworkingmemory('selectederpstudio',Selected_ERP_afd);
+ if Save_file_label==1
+ [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath);
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ end
+ end
+
+ assignin('base','ALLERPCOM',ALLERPCOM);
+ assignin('base','ERPCOM',ERPCOM);
+ erpworkingmemory('f_ERP_bin_opt',1);
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Process_messg =2;
+ catch
+ msgboxText = ['Please check all the parameters are correct!!!'];
+ title = 'EStudio: "Average across ERPsets" panel.';
+ errorfound(sprintf(msgboxText), title);
+ observe_ERPDAT.Process_messg =3;
+ return;
+ end
+ observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+ end
+
+
+%%--------Setting current ERPset/session history based on the current updated ERPset------------
+ function Count_currentERPChanged(~,~)
+ Selectederp_Index= estudioworkingmemory('selectederpstudio');
+ if isempty(Selectederp_Index)
+ Selectederp_Index = observe_ERPDAT.CURRENTERP;
+
+ if isempty(Selectederp_Index)
+ beep;
+ msgboxText = ['Average across ERPsets - No ERPset was selected'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ checked_ERPset_Index = S_binchan.checked_ERPset_Index;
+
+
+ if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded')
+ checked_curr_index = 1;
+ else
+ checked_curr_index = 0;
+ end
+
+ if isempty(checked_ERPset_Index)
+ checked_ERPset_Index = f_checkerpsets(observe_ERPDAT.ALLERP,Selectederp_Index);
+ end
+ if checked_curr_index || any(checked_ERPset_Index(:))
+ Enable_label = 'off';
+ else
+ Enable_label = 'on';
+ end
+ gui_erp_grdavg.weigavg.Enable = Enable_label;
+ if gui_erp_grdavg.weigavg.Value
+ gui_erp_grdavg.excldnullbin.Enable = 'off';
+ end
+ gui_erp_grdavg.excldnullbin.Enable = Enable_label;
+ gui_erp_grdavg.jacknife.Enable = Enable_label;
+ gui_erp_grdavg.warn.Enable = Enable_label;
+ gui_erp_grdavg.warn_edit.Enable = Enable_label;
+ if gui_erp_grdavg.warn.Value
+ gui_erp_grdavg.warn_edit.Enable ='on';
+ else
+ gui_erp_grdavg.warn_edit.Enable ='off';
+ end
+ gui_erp_grdavg.cbdatq.Enable = Enable_label;
+ gui_erp_grdavg.cbdatq_def.Enable = Enable_label;
+ gui_erp_grdavg.cbdatq_custom.Enable = Enable_label;
+ if gui_erp_grdavg.cbdatq.Value && gui_erp_grdavg.cbdatq_custom.Value
+ gui_erp_grdavg.cbdatq_custom_op.Enable = 'on';
+ elseif gui_erp_grdavg.cbdatq.Value==0
+ gui_erp_grdavg.cbdatq_custom_op.Enable = 'off';
+ gui_erp_grdavg.cbdatq_custom.Enable = 'off';
+ gui_erp_grdavg.cbdatq_def.Enable = 'off';
+ end
+
+ gui_erp_grdavg.advanced.Enable = Enable_label;
+ gui_erp_grdavg.run.Enable = Enable_label;
+ end
+end
\ No newline at end of file
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_history_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_history_GUI.m
new file mode 100755
index 00000000..0b6cd3d7
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_history_GUI.m
@@ -0,0 +1,222 @@
+%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com
+%Center for Mind and Brain
+%University of California, Davis
+%Davis, CA, USA
+%Feb. 2022
+
+% ERPLAB Studio
+
+function varargout = f_ERP_history_GUI(varargin)
+global observe_ERPDAT;
+% addlistener(observe_ERPDAT,'ALLERP_change',@allErpChanged);
+% addlistener(observe_ERPDAT,'ERP_change',@onErpChanged);
+% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange);
+addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged);
+
+
+gui_erp_history = struct();
+
+%-----------------------------Name the title----------------------------------------------
+% global box_erp_history;
+
+try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+catch
+ ColorB_def = [0.95 0.95 0.95];
+end
+
+if nargin == 0
+ fig = figure(); % Parent figure
+ box_erp_history = uiextras.BoxPanel('Parent', fig, 'Title', 'History', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel
+elseif nargin == 1
+ box_erp_history = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'History', 'Padding', 5,'BackgroundColor',ColorB_def);
+else
+ box_erp_history = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'History', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def);
+end
+
+%-----------------------------Draw the panel-------------------------------------
+try
+ FonsizeDefault = varargin{2};
+catch
+ FonsizeDefault = [];
+end
+if isempty(FonsizeDefault)
+ FonsizeDefault = f_get_default_fontsize();
+end
+drawui_erp_history(FonsizeDefault);
+varargout{1} = box_erp_history;
+
+ function drawui_erp_history(FonsizeDefault)
+ try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+ catch
+ ColorB_def = [0.95 0.95 0.95];
+ end
+ %%--------------------channel and bin setting----------------------
+ gui_erp_history.DataSelBox = uiextras.VBox('Parent', box_erp_history,'BackgroundColor',ColorB_def);
+ gui_erp_history.erp_history_title = uiextras.HBox('Parent', gui_erp_history.DataSelBox,'BackgroundColor',ColorB_def);
+
+
+ gui_erp_history.erp_h_all = uicontrol('Style','radiobutton','Parent',gui_erp_history.erp_history_title,'String','Current ERPset',...
+ 'callback',@ERP_H_ALL,'Value',1,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 2F
+ gui_erp_history.erp_h_EEG = uicontrol('Style','radiobutton','Parent', gui_erp_history.erp_history_title,'String','Current session',...
+ 'callback',@ERP_H_EEG,'Value',0,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 2F
+
+ % gui_erp_history.erp_h_erp = uicontrol('Style','radiobutton','Parent', gui_erp_history.erp_history_title,'String','ERP','callback',@ERP_H_ERP,'Value',0); % 2F
+
+ try
+ ERP_history = observe_ERPDAT.ERP.history;
+ catch
+ ERP_history = [];
+ end
+ if isempty(ERP_history)
+ ERP_history = char('No history exist in the current ERPset');
+ end
+ [~, total_len] = size(ERP_history);
+ if total_len <500
+ total_len =1000;
+ end
+ gui_erp_history.erp_history_table = uiextras.HBox('Parent', gui_erp_history.DataSelBox);
+ gui_erp_history.uitable = uitable( ...
+ 'Parent' , gui_erp_history.erp_history_table,...
+ 'Data' , strsplit(ERP_history(1,:), '\n')', ...
+ 'ColumnWidth' , {total_len+2}, ...
+ 'ColumnName' , {'Function call'}, ...
+ 'RowName' , []);
+ set( gui_erp_history.DataSelBox,'Heights',[40 -1]);
+ end
+
+
+
+%%**************************************************************************%%
+%%--------------------------Sub function------------------------------------%%
+%%**************************************************************************%%
+
+
+%--------History for both EEG and ERP data processing procedure------------
+ function ERP_H_ALL(~,~)
+ Source_value = 1;
+ set(gui_erp_history.erp_h_all,'Value',Source_value);
+ set(gui_erp_history.erp_h_EEG,'Value',~Source_value);
+
+ %adding the relared history in dispaly panel
+ hiscp_empty =0;
+ try
+ ERP_history = observe_ERPDAT.ERP.history;
+ catch
+ ERP_history = [];
+ end
+ % if isempty(ERP_history)
+ % hiscp_empty =1;
+ % ERP_history = {'No history exist in the current ERPset'};
+ % end
+ %
+ % if hiscp_empty
+ % set(gui_erp_history.uitable,'Data', ERP_history);
+ % else
+ % set(gui_erp_history.uitable,'Data', strsplit(ERP_history(1,:), '\n')');
+ % end
+
+ if isempty(ERP_history)
+ ERP_history = char('No history exist in the current ERPset');
+ end
+ ERP_history_display = {};
+ for Numofrow = 1:size(ERP_history,1)
+ ERP_history_display = [ERP_history_display,strsplit(ERP_history(Numofrow,:), '\n')];
+ end
+ set(gui_erp_history.uitable,'Data', ERP_history_display');
+ set(gui_erp_history.DataSelBox,'Heights',[40 -1]);
+ set(gui_erp_history.DataSelBox,'Heights',[40 -1]);
+
+ end
+
+
+ function ERP_H_EEG(~,~)
+ Source_value = 1;
+ set(gui_erp_history.erp_h_all,'Value',~Source_value);
+ set(gui_erp_history.erp_h_EEG,'Value',Source_value);
+ %adding the relared history in dispaly panel
+ try
+ ERP_history = evalin('base','ALLERPCOM');
+ ERP_history = ERP_history';
+ catch
+ ERP_history = {'No command history was found in the current session'};
+ end
+ if isempty(ERP_history)
+ ERP_history = {'No command history was found in the current session'};
+ end
+
+ set(gui_erp_history.uitable,'Data',ERP_history);
+ set(gui_erp_history.DataSelBox,'Heights',[40 -1]);
+ end
+
+
+
+%%----------------------ALLERPsets change-----------------------------------------
+ function allErpChanged(~,~)
+
+ end
+
+
+%%--------Setting current ERPset/session history based on the current updated ERPset------------
+ function Count_currentERPChanged(~,~)
+% try
+% ERPloadIndex = estudioworkingmemory('ERPloadIndex');
+% catch
+% ERPloadIndex =0;
+% end
+% if ERPloadIndex==1
+% ALLERPIN = evalin('base','ALLERP');
+% CURRENTERPIN = evalin('base','CURRENTERP');
+% observe_ERPDAT.ALLERP = ALLERPIN;
+% observe_ERPDAT.CURRENTERP =CURRENTERPIN;
+% try
+% observe_ERPDAT.ERP = ALLERPIN(CURRENTERPIN);
+% catch
+% observe_ERPDAT.ERP = ALLERPIN(end);
+% observe_ERPDAT.CURRENTERP =length(ALLERPIN);
+% end
+% end
+
+
+ %check which option was selected and then update the related
+ %information based on the current ERPset.
+ if gui_erp_history.erp_h_all.Value ==1
+
+ try
+ ERP_history = observe_ERPDAT.ERP.history;
+ catch
+ ERP_history = [];
+ end
+ if isempty(ERP_history)
+ ERP_history = char('No history exist in the current ERPset');
+ end
+ ERP_history_display = {};
+ for Numofrow = 1:size(ERP_history,1)
+ ERP_history_display = [ERP_history_display,strsplit(ERP_history(Numofrow,:), '\n')];
+ end
+ set(gui_erp_history.uitable,'Data', ERP_history_display');
+ set(gui_erp_history.DataSelBox,'Heights',[40 -1]);
+ else%% ALLERPCOM for current session
+
+ try
+ ERP_history = evalin('base','ALLERPCOM');
+ ERP_history = ERP_history';
+ set(gui_erp_history.uitable,'Data',ERP_history);
+ catch
+ ERP_history = {'No command history was found in the current section'};
+ set(gui_erp_history.uitable,'Data',ERP_history);
+ end
+ if isempty(ERP_history)
+ ERP_history = {'No command history was found in the current section'};
+ set(gui_erp_history.uitable,'Data',ERP_history);
+ end
+
+ set(gui_erp_history.DataSelBox,'Heights',[40 -1]);
+ end
+
+ end
+
+
+
+end
\ No newline at end of file
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_meas_basecorr.fig b/studio_functions/GUIs/ERP Tab/f_ERP_meas_basecorr.fig
new file mode 100755
index 00000000..41be9233
Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_ERP_meas_basecorr.fig differ
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_meas_basecorr.m b/studio_functions/GUIs/ERP Tab/f_ERP_meas_basecorr.m
new file mode 100755
index 00000000..ec7c1b53
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_meas_basecorr.m
@@ -0,0 +1,276 @@
+function varargout = f_ERP_meas_basecorr(varargin)
+% F_ERP_MEAS_BASECORR MATLAB code for f_ERP_meas_basecorr.fig
+% F_ERP_MEAS_BASECORR, by itself, creates a new F_ERP_MEAS_BASECORR or raises the existing
+% singleton*.
+%
+% H = F_ERP_MEAS_BASECORR returns the handle to a new F_ERP_MEAS_BASECORR or the handle to
+% the existing singleton*.
+%
+% F_ERP_MEAS_BASECORR('CALLBACK',hObject,eventData,handles,...) calls the local
+% function named CALLBACK in F_ERP_MEAS_BASECORR.M with the given input arguments.
+%
+% F_ERP_MEAS_BASECORR('Property','Value',...) creates a new F_ERP_MEAS_BASECORR or raises the
+% existing singleton*. Starting from the left, property value pairs are
+% applied to the GUI before f_ERP_meas_basecorr_OpeningFcn gets called. An
+% unrecognized property name or invalid value makes property application
+% stop. All inputs are passed to f_ERP_meas_basecorr_OpeningFcn via varargin.
+%
+% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
+% instance to run (singleton)".
+%
+% See also: GUIDE, GUIDATA, GUIHANDLES
+
+% Edit the above text to modify the response to help f_ERP_meas_basecorr
+
+% Last Modified by GUIDE v2.5 23-Aug-2022 09:26:55
+
+% Begin initialization code - DO NOT EDIT
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @f_ERP_meas_basecorr_OpeningFcn, ...
+ 'gui_OutputFcn', @f_ERP_meas_basecorr_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+% End initialization code - DO NOT EDIT
+
+
+% --- Executes just before f_ERP_meas_basecorr is made visible.
+function f_ERP_meas_basecorr_OpeningFcn(hObject, eventdata, handles, varargin)
+% Choose default command line output for f_ERP_meas_basecorr
+
+try
+ Baseline_method = varargin{1}; %% 1. long; 0 wide
+ % latency= varargin{2};
+catch
+ Baseline_method = 'pre'; %% 1. long; 0 wide
+ % latency= '';
+end
+% handles.latency = latency;
+handles.output = [];
+% erpmenu = findobj('tag', 'erpsets');
+% handles.pathName = pathName;
+% if ~isempty(erpmenu)
+% handles.menuerp = get(erpmenu);
+% set(handles.menuerp.Children, 'Enable','off');
+% end
+
+erplab_studio_default_values;
+version = erplabstudiover;
+set(handles.gui_chassis,'Name', ['EStudio ' version ' - ERP Measurement Tool'])
+
+
+set(handles.current_erp_label,'String', ['ERP Measurement Tool: Baseline Period in ms'],...
+ 'FontWeight','Bold', 'FontSize', 16);
+if length(Baseline_method)==2
+ set(handles.edit_custom, 'String', num2str(Baseline_method));
+
+else
+
+ if strcmpi(Baseline_method,'pre')
+ set(handles.radiobutton_pre, 'Value', 1);
+ set(handles.radiobutton_post, 'Value', 0);%radiobutton_whole
+ set(handles.radiobutton_whole, 'Value', 0);
+ set(handles.radiobutton_custom, 'Value', 0);
+ set(handles.edit_custom, 'Enable', 'off');
+ set(handles.radiobutton_none, 'Value', 0);
+ elseif strcmpi(Baseline_method,'post')
+ set(handles.radiobutton_pre, 'Value', 0);
+ set(handles.radiobutton_post, 'Value', 1);%radiobutton_whole
+ set(handles.radiobutton_whole, 'Value', 0);
+ set(handles.radiobutton_custom, 'Value', 0);
+ set(handles.edit_custom, 'Enable', 'off');
+ set(handles.radiobutton_none, 'Value', 0);
+ elseif strcmpi(Baseline_method,'whole')
+ set(handles.radiobutton_pre, 'Value', 0);
+ set(handles.radiobutton_post, 'Value', 0);%radiobutton_whole
+ set(handles.radiobutton_whole, 'Value', 1);
+ set(handles.radiobutton_custom, 'Value', 0);
+ set(handles.edit_custom, 'Enable', 'off');
+ set(handles.radiobutton_none, 'Value', 0);
+ elseif strcmpi(Baseline_method,'none')
+ set(handles.radiobutton_pre, 'Value', 0);
+ set(handles.radiobutton_post, 'Value', 0);%radiobutton_whole
+ set(handles.radiobutton_whole, 'Value', 0);
+ set(handles.radiobutton_custom, 'Value', 0);
+ set(handles.edit_custom, 'Enable', 'off');
+ set(handles.radiobutton_none, 'Value', 1);
+ else
+ set(handles.radiobutton_pre, 'Value', 0);
+ set(handles.radiobutton_post, 'Value', 0);%radiobutton_whole
+ set(handles.radiobutton_whole, 'Value', 0);
+ set(handles.radiobutton_custom, 'Value', 0);
+ set(handles.edit_custom, 'Enable', 'off');
+ set(handles.radiobutton_none, 'Value', 1);
+ end
+end
+% set(handles.edit_custom, 'String', pathName);
+%
+% % Color GUI
+% %
+handles = painterplabstudio(handles);
+%
+% %
+% % Set font size
+% %
+handles = setfonterplabestudio(handles);
+
+% Update handles structure
+guidata(hObject, handles);
+
+
+% UIWAIT makes savemyerpGUI wait for user response (see UIRESUME)
+uiwait(handles.gui_chassis);
+
+
+
+
+% --- Outputs from this function are returned to the command line.
+function varargout = f_ERP_meas_basecorr_OutputFcn(hObject, eventdata, handles)
+varargout{1} = handles.output;
+delete(handles.gui_chassis);
+pause(0.1)
+
+
+function edit_custom_Callback(hObject, eventdata, handles)
+
+Baseline = str2num(handles.String);
+if isempty(Baseline) || length(Baseline) ==1
+ msgboxText = {'Invalid Baseline range!';'Please enter two numeric values'};
+ title = 'EStudio: f_ERP_meas_basecorr() error: Baseline Period setting';
+ errorfound(msgboxText, title);
+ return;
+end
+
+
+
+
+% --- Executes during object creation, after setting all properties.
+function edit_custom_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+% --- Executes on button press in radiobutton_pre.
+function radiobutton_pre_Callback(hObject, eventdata, handles)
+set(handles.radiobutton_pre, 'Value', 1);
+set(handles.radiobutton_post, 'Value', 0);%radiobutton_whole
+set(handles.radiobutton_whole, 'Value', 0);
+set(handles.radiobutton_custom, 'Value', 0);
+set(handles.radiobutton_none, 'Value', 0);
+set(handles.edit_custom, 'Enable', 'off');
+
+
+% --- Executes on button press in radiobutton_post.
+function radiobutton_post_Callback(hObject, eventdata, handles)
+set(handles.radiobutton_pre, 'Value', 0);
+set(handles.radiobutton_post, 'Value', 1);%radiobutton_whole
+set(handles.radiobutton_whole, 'Value', 0);
+set(handles.radiobutton_custom, 'Value', 0);
+set(handles.radiobutton_none, 'Value', 0);
+set(handles.edit_custom, 'Enable', 'off');
+
+
+% --- Executes on button press in pushbutton_Cancel.
+function pushbutton_Cancel_Callback(hObject, eventdata, handles)
+handles.output = [];
+beep;
+disp('User selected Cancel')
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+
+% --- Executes on button press in pushbutton4_okay.
+function pushbutton4_okay_Callback(hObject, eventdata, handles)
+
+if handles.radiobutton_none.Value
+ Baseline_corre = 'none';
+elseif handles.radiobutton_pre.Value
+ Baseline_corre = 'pre';
+elseif handles.radiobutton_post.Value
+ Baseline_corre = 'post';
+elseif handles.radiobutton_whole.Value
+ Baseline_corre = 'whole';
+elseif handles.radiobutton_custom.Value
+
+ Baseline_corre = str2num(handles.edit_custom.String);
+ if isempty(Baseline_corre) || length(Baseline_corre) ==1
+ msgboxText = {'Invalid Baseline range!';'Please enter two numeric values'};
+ title = 'EStudio: f_ERP_meas_basecorr() error: Baseline Period setting';
+ errorfound(msgboxText, title);
+ return;
+ elseif Baseline_corre(1)>=Baseline_corre(2)
+ msgboxText = ['EStudio says: The first latency should be smaller than the seocnd one.'];
+ title = 'EStudio: f_ERP_meas_basecorr() error: Baseline Period setting';
+ errorfound(sprintf(msgboxText), title);
+ return;
+ end
+ Baseline_corre = handles.edit_custom.String;
+else
+ Baseline_corre = 'none';
+
+end
+
+handles.output = Baseline_corre;
+% Update handles structure
+guidata(hObject, handles);
+
+uiresume(handles.gui_chassis);
+
+
+
+
+% -----------------------------------------------------------------------
+function gui_chassis_CloseRequestFcn(hObject, eventdata, handles)
+
+if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting')
+ %The GUI is still in UIWAIT, us UIRESUME
+ handles.output = '';
+ %Update handles structure
+ guidata(hObject, handles);
+ uiresume(handles.gui_chassis);
+else
+ % The GUI is no longer waiting, just close it
+ delete(handles.gui_chassis);
+end
+
+
+% --- Executes on button press in radiobutton_whole.
+function radiobutton_whole_Callback(hObject, eventdata, handles)
+set(handles.radiobutton_pre, 'Value', 0);
+set(handles.radiobutton_post, 'Value', 0);%radiobutton_whole
+set(handles.radiobutton_whole, 'Value', 1);
+set(handles.radiobutton_custom, 'Value', 0);
+set(handles.radiobutton_none, 'Value', 0);
+set(handles.edit_custom, 'Enable', 'off');
+
+% --- Executes on button press in radiobutton_custom.
+function radiobutton_custom_Callback(hObject, eventdata, handles)
+set(handles.radiobutton_pre, 'Value', 0);
+set(handles.radiobutton_post, 'Value', 0);%radiobutton_whole
+set(handles.radiobutton_whole, 'Value', 0);
+set(handles.radiobutton_custom, 'Value', 1);
+set(handles.radiobutton_none, 'Value', 0);
+set(handles.edit_custom, 'Enable', 'on');
+
+
+% --- Executes on button press in radiobutton_none.
+function radiobutton_none_Callback(hObject, eventdata, handles)
+set(handles.radiobutton_pre, 'Value', 0);
+set(handles.radiobutton_post, 'Value', 0);%radiobutton_whole
+set(handles.radiobutton_whole, 'Value', 0);
+set(handles.radiobutton_custom, 'Value', 0);
+set(handles.radiobutton_none, 'Value', 1);
+set(handles.edit_custom, 'Enable', 'off');
+% Hint: get(hObject,'Value') returns toggle state of radiobutton_none
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_meas_format_path.fig b/studio_functions/GUIs/ERP Tab/f_ERP_meas_format_path.fig
new file mode 100755
index 00000000..ccf145b4
Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_ERP_meas_format_path.fig differ
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_meas_format_path.m b/studio_functions/GUIs/ERP Tab/f_ERP_meas_format_path.m
new file mode 100755
index 00000000..fc043572
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_meas_format_path.m
@@ -0,0 +1,275 @@
+function varargout = f_ERP_meas_format_path(varargin)
+% F_ERP_MEAS_FORMAT_PATH MATLAB code for f_ERP_meas_format_path.fig
+% F_ERP_MEAS_FORMAT_PATH, by itself, creates a new F_ERP_MEAS_FORMAT_PATH or raises the existing
+% singleton*.
+%
+% H = F_ERP_MEAS_FORMAT_PATH returns the handle to a new F_ERP_MEAS_FORMAT_PATH or the handle to
+% the existing singleton*.
+%
+% F_ERP_MEAS_FORMAT_PATH('CALLBACK',hObject,eventData,handles,...) calls the local
+% function named CALLBACK in F_ERP_MEAS_FORMAT_PATH.M with the given input arguments.
+%
+% F_ERP_MEAS_FORMAT_PATH('Property','Value',...) creates a new F_ERP_MEAS_FORMAT_PATH or raises the
+% existing singleton*. Starting from the left, property value pairs are
+% applied to the GUI before f_ERP_meas_format_path_OpeningFcn gets called. An
+% unrecognized property name or invalid value makes property application
+% stop. All inputs are passed to f_ERP_meas_format_path_OpeningFcn via varargin.
+%
+% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
+% instance to run (singleton)".
+%
+% See also: GUIDE, GUIDATA, GUIHANDLES
+
+% Edit the above text to modify the response to help f_ERP_meas_format_path
+
+% Last Modified by GUIDE v2.5 07-Aug-2022 18:19:42
+
+% Begin initialization code - DO NOT EDIT
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @f_ERP_meas_format_path_OpeningFcn, ...
+ 'gui_OutputFcn', @f_ERP_meas_format_path_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+% End initialization code - DO NOT EDIT
+
+
+% --- Executes just before f_ERP_meas_format_path is made visible.
+function f_ERP_meas_format_path_OpeningFcn(hObject, eventdata, handles, varargin)
+% Choose default command line output for f_ERP_meas_format_path
+
+try
+ foutputstr = varargin{1}; %% 1. long; 0 wide
+ pathName= varargin{2};
+
+catch
+ foutputstr = 1; %% 1. long; 0 wide
+ pathName= cd;
+end
+
+handles.output = [];
+erpmenu = findobj('tag', 'erpsets');
+handles.pathName = pathName;
+if ~isempty(erpmenu)
+ handles.menuerp = get(erpmenu);
+ set(handles.menuerp.Children, 'Enable','off');
+end
+
+erplab_studio_default_values;
+version = erplabstudiover;
+set(handles.gui_chassis,'Name', ['EStudio ' version ' - ERP Measurement Tool'])
+
+
+set(handles.current_erp_label,'String', ['ERP Measurement Tool: File format and path'],...
+ 'FontWeight','Bold', 'FontSize', 16);
+if foutputstr
+ set(handles.radiobutton_wide, 'Value', 1);
+ set(handles.radiobutton5_long, 'Value', 0);
+else
+ set(handles.radiobutton_wide, 'Value', 0);
+ set(handles.radiobutton5_long, 'Value', 1);
+end
+set(handles.edit_filename, 'String', pathName);
+%
+% % Color GUI
+% %
+handles = painterplabstudio(handles);
+%
+% %
+% % Set font size
+% %
+handles = setfonterplabestudio(handles);
+
+% Update handles structure
+guidata(hObject, handles);
+
+
+% UIWAIT makes savemyerpGUI wait for user response (see UIRESUME)
+uiwait(handles.gui_chassis);
+
+
+
+
+% --- Outputs from this function are returned to the command line.
+function varargout = f_ERP_meas_format_path_OutputFcn(hObject, eventdata, handles)
+
+% Get default command line output from handles structure
+% try
+% set(handles.menuerp.Children, 'Enable','on');
+% catch
+% disp('ERPset menu was not found...')
+% end
+varargout{1} = handles.output;
+delete(handles.gui_chassis);
+pause(0.1)
+
+
+
+
+% % --- Executes on button press in radio_erpname.
+% function radio_erpname_Callback(hObject, eventdata, handles)
+% % hObject handle to radio_erpname (see GCBO)
+% % eventdata reserved - to be defined in a future version of MATLAB
+% % handles structure with handles and user data (see GUIDATA)
+%
+% % Hint: get(hObject,'Value') returns toggle state of radio_erpname
+% Value_radio_erpname = get(hObject,'Value');
+% set(handles.radio_erpname, 'Value', 1);
+
+
+
+% % --- Executes on button press in radiobutton_saveas.
+% function radiobutton_saveas_Callback(hObject, eventdata, handles)
+%
+% if get(hObject, 'Value')
+% set(handles.edit_filename, 'Enable', 'on');
+% set(handles.filename_erpname, 'Enable', 'on');
+% set(handles.pushbutton_browse, 'Enable', 'on');
+% set(handles.erpname_filename, 'Enable', 'on');
+% else
+% set(handles.edit_filename, 'Enable', 'off');
+% set(handles.filename_erpname, 'Enable', 'off');
+% set(handles.pushbutton_browse, 'Enable', 'off');
+% set(handles.erpname_filename, 'Enable', 'off');
+% set(handles.edit_filename, 'String', '');
+% end
+
+
+function edit_filename_Callback(hObject, eventdata, handles)
+% hObject handle to edit_filename (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Hints: get(hObject,'String') returns contents of edit_filename as text
+% str2double(get(hObject,'String')) returns contents of edit_filename as a double
+
+
+% --- Executes during object creation, after setting all properties.
+function edit_filename_CreateFcn(hObject, eventdata, handles)
+% hObject handle to edit_filename (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+% Hint: edit controls usually have a white background on Windows.
+% See ISPC and COMPUTER.
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+% --- Executes on button press in radiobutton_wide.
+function radiobutton_wide_Callback(hObject, eventdata, handles)
+% hObject handle to radiobutton_wide (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Hint: get(hObject,'Value') returns toggle state of radiobutton_wide
+set(handles.radiobutton_wide, 'Value', 1);
+set(handles.radiobutton5_long, 'Value', 0);
+
+% --- Executes on button press in radiobutton5_long.
+function radiobutton5_long_Callback(hObject, eventdata, handles)
+set(handles.radiobutton_wide, 'Value', 0);
+set(handles.radiobutton5_long, 'Value', 1);
+
+
+
+
+
+
+% --- Executes on button press in pushbutton_browse.
+function pushbutton_browse_Callback(hObject, eventdata, handles)
+
+pathName = handles.pathName;
+
+title = 'Save output file as';
+
+[filename, filepath,filterindex] = uiputfile({'*.txt'; '*.dat'}, ...
+ title,pathName);
+
+if isequal(filterindex,0)
+ disp('User selected Cancel');
+ return;
+else
+ [px, fname, ext] = fileparts(filename);
+ if strcmp(ext,'')
+ if filterindex==1 || filterindex==3
+ ext = '.txt';
+ else
+ ext = '.dat';
+ end
+ end
+ Filename = [fname ext];
+ set(handles.edit_filename,'String',fullfile(filepath,Filename));
+end
+
+
+
+
+
+% --- Executes on button press in pushbutton_Cancel.
+function pushbutton_Cancel_Callback(hObject, eventdata, handles)
+handles.output = [];
+beep;
+disp('User selected Cancel')
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+
+% --- Executes on button press in pushbutton4_okay.
+function pushbutton4_okay_Callback(hObject, eventdata, handles)
+Filename = strtrim(get(handles.edit_filename, 'String'));
+
+[px, fname, ext] = fileparts(Filename);
+if isempty(fname)
+ msgboxText = 'You must enter a name for the saved file at least!';
+ title = 'EStudio: f_ERP_save_single_file empty filename';
+ errorfound(msgboxText, title);
+ return
+end
+
+
+Wide_fromat = (get(handles.radiobutton_wide, 'Value'));
+
+Long_fromat = (get(handles.radiobutton5_long, 'Value'));
+
+
+if Wide_fromat
+ FileFormat = 1;
+elseif Long_fromat
+ FileFormat = 0;
+end
+
+handles.output = {FileFormat, Filename};
+% Update handles structure
+guidata(hObject, handles);
+
+uiresume(handles.gui_chassis);
+
+
+
+
+% -----------------------------------------------------------------------
+function gui_chassis_CloseRequestFcn(hObject, eventdata, handles)
+
+if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting')
+ %The GUI is still in UIWAIT, us UIRESUME
+ handles.output = '';
+ %Update handles structure
+ guidata(hObject, handles);
+ uiresume(handles.gui_chassis);
+else
+ % The GUI is no longer waiting, just close it
+ delete(handles.gui_chassis);
+end
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_measurement_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_measurement_GUI.m
new file mode 100755
index 00000000..b1da2e07
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_measurement_GUI.m
@@ -0,0 +1,1579 @@
+%%% ERPLAB Studio: ERO meansurement panel
+
+
+%Author: Guanghui ZHANG
+%Center for Mind and Brain
+% University of California, Davis
+%Davis, CA
+% 2022
+
+
+function varargout = f_ERP_measurement_GUI(varargin)
+
+global observe_ERPDAT;
+% addlistener(observe_ERPDAT,'ALLERP_change',@erpschange);
+% addlistener(observe_ERPDAT,'ERP_change',@drawui_CB);
+% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange);
+addlistener(observe_ERPDAT,'ERP_chan_change',@ERP_chan_changed);
+addlistener(observe_ERPDAT,'ERP_bin_change',@ERP_bin_changed);
+addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERP_change);
+
+%%Get the parameters for pop_geterpvalues used in the last time.
+def_erpvalue = erpworkingmemory('pop_geterpvalues');
+
+try
+ ALLERP = evalin('base','ALLERP');
+ CurrentERPSet = evalin('base','CURRENTERP');
+catch
+ return;
+end
+
+if isstruct(ALLERP)
+ if ~iserpstruct(ALLERP(1))
+ ALLERP = [];
+ nbinx = 1;
+ nchanx = 1;
+ else
+ nbinx = ALLERP(1).nbin;
+ nchanx = ALLERP(1).nchan;
+ end
+else
+ ALLERP = [];
+ nbinx = 1;
+ nchanx = 1;
+end
+
+
+
+if isempty(def_erpvalue)
+ if isempty(ALLERP)
+ inp1 = 1; %from hard drive
+ CurrentERPSet = [];
+ else
+ inp1 = 0; %from erpset menu
+ CurrentERPSet = 1:length(ALLERP);
+ end
+
+ def_erpvalue = {inp1,CurrentERPSet,'',0,1:nbinx,1:nchanx,'meanbl',...
+ 1,3,'pre',1,1,5,0,0.5,0,0,0,'',0,1,1};
+
+else
+ if ~isempty(ALLERP)
+ if isnumeric(def_erpvalue{2}) % JavierLC 11-17-11
+ [uu, mm] = unique_bc2(def_erpvalue{2}, 'first');
+ erpset_list_sorted = [def_erpvalue{2}(sort(mm))];
+ %def_erpvalue{2} = def_erpvalue{2}(def_erpvalue{2}<=length(ALLERP));
+ % non-empty check, axs jul17
+ erpset_list = erpset_list_sorted(erpset_list_sorted<=length(ALLERP));
+ if isempty(erpset_list)
+ % if nothing in list, just go with current
+ def_erpvalue{2} = CurrentERPSet;
+ else
+ def_erpvalue{2} = erpset_list;
+ end
+
+ end
+ end
+end
+
+
+if def_erpvalue{11} == 0
+ def_erpvalue{11} = 'off';
+else
+ def_erpvalue{11} = 'on';
+end
+
+if def_erpvalue{12} == 0
+ def_erpvalue{12} = 'negative';
+else
+ def_erpvalue{12} = 'positive';
+end
+
+if def_erpvalue{14}==0
+ def_erpvalue{14} = 'NaN';
+else
+ def_erpvalue{14} = 'absolute';
+end
+
+if def_erpvalue{16}==0 % Fractional area latency replacement
+ def_erpvalue{16} = 'NaN';
+else
+ if ismember_bc2({def_erpvalue{7}}, {'fareatlat', 'fninteglat','fareaplat','fareanlat'})
+ def_erpvalue{16} = 'errormsg';
+ else
+ def_erpvalue{16} = 'absolute';
+ end
+end
+
+if def_erpvalue{17} == 0
+ def_erpvalue{17} = 'off';
+else
+ def_erpvalue{17} = 'on';
+end
+
+if def_erpvalue{18} == 0
+ def_erpvalue{18} = 'wide';
+else
+ def_erpvalue{18} = 'long';
+end
+
+
+if def_erpvalue{20} == 0
+ def_erpvalue{20} = 'no';
+else
+ def_erpvalue{20} = 'yes';
+end
+
+%
+S_IN = estudioworkingmemory('geterpvalues');
+if isempty(S_IN)
+ erpvalues_variables = {'geterpvalues','latency',def_erpvalue{4},...
+ 'binArray',def_erpvalue{5},...
+ 'chanArray', def_erpvalue{6},...
+ 'Erpsets', def_erpvalue{2},...
+ 'Measure',def_erpvalue{7},...
+ 'Component',def_erpvalue{8},...
+ 'Resolution', def_erpvalue{9},...
+ 'Baseline', def_erpvalue{10},...
+ 'Binlabel', def_erpvalue{11},...
+ 'Peakpolarity',def_erpvalue{12},...
+ 'Neighborhood', def_erpvalue{13},...
+ 'Peakreplace', def_erpvalue{14},...
+ 'Filename', def_erpvalue{3},...
+ 'Warning','on',...
+ 'SendtoWorkspace', def_erpvalue{17},...
+ 'Append', '',...
+ 'FileFormat', def_erpvalue{18},...
+ 'Afraction',def_erpvalue{15},...
+ 'Mlabel', def_erpvalue{19},...
+ 'Fracreplace', def_erpvalue{16},...
+ 'IncludeLat', def_erpvalue{20},...
+ 'InterpFactor', def_erpvalue{21},...
+ 'Viewer', 'off',...
+ 'PeakOnset',def_erpvalue{22},...
+ 'History', 'gui'};
+ S_OUT = createrplabstudioparameters(S_IN,erpvalues_variables);
+ estudioworkingmemory('geterpvalues',S_OUT.geterpvalues);
+ S_IN = S_OUT.geterpvalues;
+end
+% end
+
+
+EStudio_erp_m_t_p = S_IN;
+
+
+%%---------------------------gui-------------------------------------------
+try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+catch
+ ColorB_def = [0.95 0.95 0.95];
+end
+if nargin == 0
+ fig = figure(); % Parent figure
+ erp_measurement_box = uiextras.BoxPanel('Parent', fig, 'Title', 'ERP Measurement Tool', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel
+elseif nargin == 1
+ erp_measurement_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERP Measurement Tool', 'Padding', 5,'BackgroundColor',ColorB_def);
+else
+ erp_measurement_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERP Measurement Tool', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def);
+end
+
+ERPMTops = struct();
+
+try
+ FonsizeDefault = varargin{2};
+catch
+ FonsizeDefault = [];
+end
+if isempty(FonsizeDefault)
+ FonsizeDefault = f_get_default_fontsize();
+end
+erp_m_t_gui(FonsizeDefault);
+
+
+
+varargout{1} = erp_measurement_box;
+%%********************Draw the GUI for ERP measurement tool*****************
+ function erp_m_t_gui(FonsizeDefault)
+ try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+ catch
+ ColorB_def = [0.95 0.95 0.95];
+ end
+ ERPMTops.mt = uiextras.VBox('Parent',erp_measurement_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ try
+ SelectedIndex = EStudio_erp_m_t_p.Erpsets;
+ catch
+ SelectedIndex = observe_ERPDAT.CURRENTERP;
+ end
+ if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded')
+ checked_curr_index = 1;
+ else
+ checked_curr_index = 0;
+ end
+ checked_ERPset_Index = f_checkerpsets(observe_ERPDAT.ALLERP,SelectedIndex);
+ if checked_curr_index || any(checked_ERPset_Index)
+ Enable_label = 'off';
+ else
+ Enable_label = 'on';
+ end
+
+ %%-----------------------Measurement type setting-------------------
+ ERPMTops.measurement_type = uiextras.Grid('Parent',ERPMTops.mt,'Spacing',1,'BackgroundColor',ColorB_def);
+
+ %%1A
+ ERPMTops.measurement_type_title = uicontrol('Style','text','Parent', ERPMTops.measurement_type,'String','Type:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ set(ERPMTops.measurement_type_title,'HorizontalAlignment','left');
+ %%1B
+ ERPMTops.erpset_select_title = uicontrol('Style','text','Parent', ERPMTops.measurement_type,'String','ERPset:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ set(ERPMTops.erpset_select_title,'HorizontalAlignment','left');
+ %%1C
+ ERPMTops.bin_select_title = uicontrol('Style','text','Parent', ERPMTops.measurement_type,'String','Bin:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ set(ERPMTops.bin_select_title,'HorizontalAlignment','left');
+ %%1D
+ ERPMTops.channel_select_title = uicontrol('Style','text','Parent', ERPMTops.measurement_type,'String','Channel:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ set(ERPMTops.channel_select_title,'HorizontalAlignment','left');
+ %%1E
+ ERPMTops.tw_set_title = uicontrol('Style','text','Parent', ERPMTops.measurement_type,'String','Window:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ set(ERPMTops.tw_set_title,'HorizontalAlignment','left');
+ %%1F
+ ERPMTops.out_file_title = uicontrol('Style','text','Parent', ERPMTops.measurement_type,'String','File&Path:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ set(ERPMTops.out_file_title,'HorizontalAlignment','left');
+
+
+ %%-----------------------------Setting for second column---------------
+ %%2A
+ mesurement_type = {'Mean amplitude between two fixed latencies','Local peak amplitude (Negative)','Local peak amplitude (Positive)','Local peak latency (Negative)',...
+ 'Local peak latency (Positive)','Fractional peak latency (Negative)','Fractional peak latency (Positive)','Fractional area latency: Rectified area (negative values become positive)',...
+ 'Fractional area latency: Numrical integration (area for negatives substracted from area for positives)',...
+ 'Fractional area latency: Area for negative waveforms (positive values will be zeroed)','Fractional area latency: Area for positive waveforms (negative values will be zeroed)',...
+ 'Numerical integration/Area between two fixed latencies: Rectified area (Negative values become positive)',...
+ 'Numerical integration/Area between two fixed latencies: Numerical intergration (area for negative substracted from area for positive)',...
+ 'Numerical integration/Area between two fixed latencies: Area for negative waveforms (positive values will be zeroed)',...
+ 'Numerical integration/Area between two fixed latencies: Area for positive waveforms (negative values will be zeroed)',...
+ 'Numerical integration/Area between two (automatically detected)zero-crossing latencies: Rectified area (Negative values become positive)',...
+ 'Numerical integration/Area between two (automatically detected)zero-crossing latencies: Numerical intergration (area for negative substracted from area for positive)',...
+ 'Numerical integration/Area between two (automatically detected)zero-crossing latencies: Area for negative waveforms (positive values will be zeroed)',...
+ 'Numerical integration/Area between two (automatically detected)zero-crossing latencies: Area for positive waveforms (negative values will be zeroed)',...
+ 'Instantaneous amplitude'};
+ ERPMTops.m_t_type = uicontrol('Style', 'popup','Parent',ERPMTops.measurement_type,'String',mesurement_type,'callback',@Mesurement_type,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ if isempty(EStudio_erp_m_t_p.Measure) || ~ischar(EStudio_erp_m_t_p.Measure)
+ EStudio_erp_m_t_p.Measure = 'meanbl';
+ end
+ switch EStudio_erp_m_t_p.Measure%Find the label of the selected item, the defualt one is 1 (Mean amplitude between two fixed latencies)
+ case 'meanbl'% Mean amplitude
+ set(ERPMTops.m_t_type,'Value',1);
+ case 'peakampbl'% Local peak amplitude (P vs. N)
+ if strcmp(EStudio_erp_m_t_p.Peakpolarity,'positive')
+ set(ERPMTops.m_t_type,'Value',3);
+ else
+ set(ERPMTops.m_t_type,'Value',2);
+ end
+ case 'peaklatbl'%Peak latency (P vs. N)
+ if strcmp(EStudio_erp_m_t_p.Peakpolarity,'positive')
+ set(ERPMTops.m_t_type,'Value',5);
+ elseif strcmp(EStudio_erp_m_t_p.Peakpolarity,'negative')
+ set(ERPMTops.m_t_type,'Value',4);
+ end
+ case 'fpeaklat'%Fractional Peak latency (P vs. N)
+ if strcmp(EStudio_erp_m_t_p.Peakpolarity,'positive')
+ set(ERPMTops.m_t_type,'Value',7);
+ elseif strcmp(EStudio_erp_m_t_p.Peakpolarity,'negative')
+ set(ERPMTops.m_t_type,'Value',6);
+ end
+
+ otherwise%if the measurement type comes from Advanced option
+ MeasureName_other = {'fareatlat','fninteglat','fareaplat','fareanlat',...
+ 'areat','ninteg','areap','arean',...
+ 'areazt','nintegz','areazp','areazn',...
+ 'instabl'};
+ [C,IA] = ismember_bc2({EStudio_erp_m_t_p.Measure}, MeasureName_other);
+ if any(IA) || isempty(IA)
+ set(ERPMTops.m_t_type,'Value',1);
+ else
+ set(ERPMTops.m_t_type,'Value',IA+7);
+ end
+ end
+
+ %%2B ERPset custom
+ SelectedERP_Index = estudioworkingmemory('selectederpstudio');
+ if isempty(SelectedERP_Index) || max(SelectedERP_Index)> length(observe_ERPDAT.ALLERP)
+ ERPMTops.m_t_erpset = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String', '','callback',@erpset_custom,'Enable',Enable_label,'FontSize',FonsizeDefault); %
+ else
+ ERPMTops.m_t_erpset = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String', num2str(vect2colon(SelectedERP_Index,'Sort','on')),'callback',@erpset_custom,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ end
+
+ %%2C
+ if isempty(EStudio_erp_m_t_p.binArray)
+ ERP_CURRENT = evalin('base','ERP');
+ if isempty(ERP_CURRENT.nbin) || any(ERP_CURRENT.nbin)
+ ERPMTops.m_t_bin = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String', [],'callback',@binSelect_custom,'Enable',Enable_label,'FontSize',FonsizeDefault); %
+ else
+ ERPMTops.m_t_bin = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String', num2str(vect2colon(1:ERP_CURRENT.nbin,'Sort','on')),'callback',@binSelect_custom,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ end
+ else
+ ERPMTops.m_t_bin = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String',num2str(vect2colon(EStudio_erp_m_t_p.binArray,'Sort','on')),'callback',@binSelect_custom,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ end
+ %%2D
+ if isempty(EStudio_erp_m_t_p.chanArray) || ~any(EStudio_erp_m_t_p.chanArray)
+ try
+ ERP_CURRENT = evalin('base','ERP');
+ if isempty(ERP_CURRENT.chanArray) || any(ERP_CURRENT.chanArray)
+ ERPMTops.m_t_chan = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String',[],'callback',@chanSelect_custom,'Enable',Enable_label,'FontSize',FonsizeDefault);%vect2colon(observe_ERPDAT.ERP_chan,'Sort', 'on')
+ else
+ ERPMTops.m_t_chan = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String',num2str(vect2colon(1:ERP_CURRENT.nchan,'Sort','on')),'callback',@chanSelect_custom,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ end
+ catch
+ ERPMTops.m_t_chan = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String',[],'callback',@chanSelect_custom,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ end
+ else
+ ERPMTops.m_t_chan = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String',num2str(vect2colon(EStudio_erp_m_t_p.chanArray,'Sort','on')),'callback',@chanSelect_custom,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ end
+ %%2E
+ if isempty(EStudio_erp_m_t_p.latency)
+ ERPMTops.m_t_TW = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String','0.000','callback',@t_w_set,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ else
+ ERPMTops.m_t_TW = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String',num2str(EStudio_erp_m_t_p.latency),'callback',@t_w_set,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ end
+ %%2F
+ if isempty(EStudio_erp_m_t_p.Filename)
+ ERPMTops.m_t_file = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String','','callback',@file_name_set,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ else
+ ERPMTops.m_t_file = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String',EStudio_erp_m_t_p.Filename,'callback',@file_name_set,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ end
+
+
+ %%-----------Setting for third column--------------------------------
+ %%3A
+ ERPMTops.m_t_type_ops = uicontrol('Style', 'pushbutton','Parent',ERPMTops.measurement_type,'String','Option','callback',@Mesurement_type_option,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ %%3B
+ ERPMTops.m_t_erpset_ops = uicontrol('Style','pushbutton','Parent', ERPMTops.measurement_type,'String','Option','callback',@erpsetop,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ %%3C
+ ERPMTops.m_t_bin_ops = uicontrol('Style','pushbutton','Parent', ERPMTops.measurement_type,'String','Option','callback',@binSelect_label,'Enable',Enable_label,'FontSize',FonsizeDefault);
+
+ %%3D
+ ERPMTops.m_t_chan_ops = uicontrol('Style','pushbutton','Parent', ERPMTops.measurement_type,'String','Option','callback',@chanSelect_label,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ %%3E
+ ERPMTops.m_t_TW_ops = uicontrol('Style', 'pushbutton','Parent',ERPMTops.measurement_type,'String','Option','callback',@baseline_set,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ %%3F
+ ERPMTops.m_t_file_ops = uicontrol('Style', 'pushbutton','Parent',ERPMTops.measurement_type,'String','Option','callback',@out_file_option,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ set(ERPMTops.measurement_type, 'ColumnSizes',[65 135 65],'RowSizes',[25 25 25 25 25 25]);
+
+
+ %%-------------------------Setting for Viewer----------------------
+ ERPMTops.mt_viewer = uiextras.HBox('Parent',ERPMTops.mt,'Spacing',1,'BackgroundColor',ColorB_def);
+ ERPMTops.m_t_viewer_title = uicontrol('Style', 'text','Parent', ERPMTops.mt_viewer,'String','Viewer:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ set(ERPMTops.m_t_viewer_title,'HorizontalAlignment','left');
+ ERPMTops.m_t_viewer_on = uicontrol('Style', 'radiobutton','Parent', ERPMTops.mt_viewer,'String','On',...
+ 'callback',@m_t_viewer_on,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ ERPMTops.m_t_viewer_off = uicontrol('Style', 'radiobutton','Parent', ERPMTops.mt_viewer,'String','Off',...
+ 'callback',@m_t_viewer_off,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ if strcmp(EStudio_erp_m_t_p.Viewer,'on')
+ ERPMTops.m_t_viewer_on.Value = 1;
+ ERPMTops.m_t_viewer_off.Value =0;
+ elseif strcmp(EStudio_erp_m_t_p.Viewer,'off')
+ ERPMTops.m_t_viewer_on.Value = 0;
+ ERPMTops.m_t_viewer_off.Value =1;
+
+ end
+ uiextras.Empty('Parent', ERPMTops.mt_viewer,'BackgroundColor',ColorB_def); % 1A
+ set(ERPMTops.mt_viewer,'Sizes',[70 60 60 70]);
+
+ %%---------------------------Select ERPsets and Run options-----------
+ ERPMTops.out_file_run = uiextras.HBox('Parent',ERPMTops.mt,'Spacing',1,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', ERPMTops.out_file_run);
+ uicontrol('Style', 'pushbutton','Parent',ERPMTops.out_file_run,'String','?','callback',@ERPmeasr_help,'Enable','on','FontSize',16);
+ uiextras.Empty('Parent', ERPMTops.out_file_run);
+ ERPMTops.m_t_value = uicontrol('Style', 'pushbutton','Parent',ERPMTops.out_file_run,'String','Save values','callback',@apply_erp_m_t,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ uiextras.Empty('Parent', ERPMTops.out_file_run);
+ set(ERPMTops.out_file_run, 'Sizes',[15 105 20 105 15]);
+
+ %%ERPMTops end
+ set(ERPMTops.mt,'Sizes',[150 25 30]);
+ end
+
+%%****************************************************************************************************************************************
+%%******************* Subfunctions ***************************************************************************************************
+%%****************************************************************************************************************************************
+
+%%-----------------Help------------------------------
+ function ERPmeasr_help(~,~)
+ web('https://github.com/lucklab/erplab/wiki/ERP-Measurement-Tool','-browser');
+ end
+
+%%---------------------------Setting for the Measurement type-----------------------------%%
+ function Mesurement_type(source_measure_type,~)
+ Select_label = source_measure_type.Value;
+ if isempty(Select_label)
+ EStudio_erp_m_t_p.Measure = 'meanbl';
+ elseif Select_label==1 % Mean amplitude
+ EStudio_erp_m_t_p.Measure = 'meanbl';
+ elseif Select_label==2 %Peak amplitude
+ EStudio_erp_m_t_p.Measure ='peakampbl';
+ EStudio_erp_m_t_p.Peakpolarity = 'negative';
+ elseif Select_label==3 % Peak amplitude
+ EStudio_erp_m_t_p.Measure ='peakampbl';
+ EStudio_erp_m_t_p.Peakpolarity = 'positive';
+ elseif Select_label==4 % Peak latency
+ EStudio_erp_m_t_p.Measure = 'peaklatbl';
+ EStudio_erp_m_t_p.Peakpolarity = 'negative';
+ elseif Select_label==5 %Peak latency
+ EStudio_erp_m_t_p.Measure = 'peaklatbl';
+ EStudio_erp_m_t_p.Peakpolarity = 'positive';
+
+ elseif Select_label==6 %Fractional Peak latency
+ EStudio_erp_m_t_p.Measure ='fpeaklat';
+ EStudio_erp_m_t_p.Peakpolarity = 'negative';
+ elseif Select_label==7 %Fractional Peak latency
+ EStudio_erp_m_t_p.Measure ='fpeaklat';
+ EStudio_erp_m_t_p.Peakpolarity = 'positive';
+ else
+ if Select_label > 7
+ MeasureName_other = {'fareatlat','fninteglat','fareanlat','fareaplat',...
+ 'areat','ninteg','arean','areap',...
+ 'areazt','nintegz','areazn','areazp',...
+ 'instabl'};
+ EStudio_erp_m_t_p.Measure = MeasureName_other{Select_label-7};
+ if 15 < Select_label && Select_label<20
+ mnamex = 'Numerical integration/Area between two (automatically detected) zero-crossing latencies';
+ question = [ '%s\n\nThis tool is still in alpha phase.\n'...
+ 'Use it under your responsibility.'];
+ title = 'ERPLAB Studio: Overwriting Confirmation';
+ button = questdlg(sprintf(question, mnamex), title,'OK','OK');
+ end
+ else
+ EStudio_erp_m_t_p.Measure = 'meanbl';
+ end
+ end
+
+ S_ws = estudioworkingmemory('geterpvalues');
+ S_ws.Measure = EStudio_erp_m_t_p.Measure;
+ S_ws.Peakpolarity = EStudio_erp_m_t_p.Peakpolarity;
+ estudioworkingmemory('geterpvalues',S_ws);
+
+ if strcmp(EStudio_erp_m_t_p.Viewer,'on')
+
+ moption = EStudio_erp_m_t_p.Measure;
+ latency = EStudio_erp_m_t_p.latency;
+ if isempty(moption)
+ beep;
+ msgboxText = ['ERP Measurement Tool - User must specify a type of measurement'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if ismember_bc2({moption}, {'instabl', 'areazt','areazp','areazn', 'nintegz'})
+ if length(latency)~=1
+ beep;
+ msgboxText = ['ERP Measurement Tool - ',32,moption ' only needs 1 latency value.'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+
+ end
+ else
+ if length(latency)~=2
+ beep;
+ msgboxText = ['ERP Measurement Tool - ',32,moption ' only needs 2 latency values'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ else
+ if latency(1)>=latency(2)
+ beep;
+ msgboxText = ['ERP Measurement Tool - For latency range, lower time limit must be on the left.\n'...
+ 'Additionally, lower time limit must be at least 1/samplerate seconds lesser than the higher one'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+ end
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ end
+ end
+
+
+%%------------Options for the measurement type-----------------------------
+ function Mesurement_type_option(~,~)
+ try
+ S_ws = estudioworkingmemory('geterpvalues');
+ EStudio_erp_m_t_p.Measure = S_ws.Measure;
+ catch
+ beep;
+ msgboxText = ['ERP Measurement Tool - None of measure types was selected'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ try
+ op = S_ws.Measure;
+ catch
+ op= 'meanbl';
+ end% option: type of measurement ---> instabl, meanbl, peakampbl, peaklatbl, area, areaz, or errorbl.
+ try
+ dig = S_ws.Resolution;
+ catch
+ dig =3;
+ end%Resolution
+ try
+ Binlabel = S_ws.Binlabel;
+ catch
+ Binlabel = 'off';
+ end
+ if strcmpi(Binlabel,'off')
+ binlabop = 0; % 0: bin# as bin label for table, 1 bin label
+ else
+ binlabop = 1;
+ end
+ try
+ Peakpolarity = S_ws.Peakpolarity;
+ catch
+ Peakpolarity = 'negative';
+ end
+ if strcmpi(Peakpolarity,'negative')
+ polpeak = 0;
+ else
+ polpeak = 1; % local peak positive polarity
+ end
+ try
+ sampeak = S_ws.Neighborhood; % number of samples (one-side) for local peak detection criteria
+ catch
+ sampeak = 3;
+ end
+ try
+ Peakreplace = S_ws.Peakreplace;
+ catch
+ Peakreplace = 'absolute';
+ end
+ if strcmpi(Peakreplace,'absolute')
+ locpeakrep = 1;
+ else
+ locpeakrep = 0; % 1 abs peak , 0 Nan
+ end
+ try
+ frac = S_ws.Afraction;
+ catch
+ frac = 0.5;
+ end
+ try
+ Fracreplace = S_ws.Fracreplace;
+ catch
+ Fracreplace = 'NaN';
+ end
+
+ if strcmpi(Fracreplace,'NaN')
+ fracmearep = 0; % def{19}; NaN
+ else
+ fracmearep = 1; % def{19}; NaN
+ end
+ try
+ SendtoWorkspace = S_ws.SendtoWorkspace;
+ catch
+ SendtoWorkspace = 'off';
+ end
+ if strcmpi(SendtoWorkspace,'off')
+ send2ws = 0; % 1 send to ws, 0 dont do
+ else
+ send2ws = 1;
+ end
+ try
+ IncludeLat = S_ws.IncludeLat ;
+ catch
+ IncludeLat = 'off';
+ end
+ if strcmpi(IncludeLat,'on')
+
+ inclate = 1;
+ else
+ inclate = 0;
+ end
+ try
+ intfactor = S_ws.InterpFactor;
+ catch
+ intfactor = 10;
+ end
+ try
+ peakonset =S_ws.PeakOnset;
+ catch
+ peakonset = 1;
+ end
+
+ %%Change the modified parameters after the subfucntion was called
+ def = { op ,dig,binlabop,polpeak,sampeak,locpeakrep,frac,fracmearep,send2ws,inclate,intfactor,peakonset};
+ ERP= observe_ERPDAT.ERP;
+ Answer = geterpvaluesparasGUI2(def,ERP);
+
+ if isempty(Answer)
+ beep;
+ disp('User selected cancel');
+ return;
+ end
+ S_ws.Measure = Answer{1};
+ S_ws.Resolution=Answer{2};
+ binlabop = Answer{3};
+ if binlabop
+ S_ws.Binlabel = 'on';
+ else
+ S_ws.Binlabel = 'off';
+ end
+
+ polpeak= Answer{4};
+ if polpeak==0
+ S_ws.Peakpolarity = 'negative';
+ else
+ S_ws.Peakpolarity = 'positive';
+ end
+
+ S_ws.Neighborhood = Answer{5};
+
+ locpeakrep = Answer{6};
+ if locpeakrep==0
+ S_ws.Peakreplace = 'NaN';
+ else
+ S_ws.Peakreplace = 'absolute';
+ end
+
+ S_ws.Afraction = Answer{7};
+
+ fracmearep= Answer{8};
+ if fracmearep==0 % Fractional area latency replacement
+ S_ws.Fracreplace = 'NaN';
+ else
+ if ismember_bc2({S_ws.Measure}, {'fareatlat', 'fninteglat','fareaplat','fareanlat'})
+ S_ws.Fracreplace = 'errormsg';
+ else
+ S_ws.Fracreplace = 'absolute';
+ end
+ end
+ send2ws = Answer{9};
+ if send2ws
+ S_ws.SendtoWorkspace = 'on';
+ else
+ S_ws.SendtoWorkspace = 'off';
+ end
+ inclate = Answer{10};
+ if inclate
+ S_ws.IncludeLat = 'on' ;
+ else
+ S_ws.IncludeLat = 'off' ;
+ end
+ S_ws.InterpFactor=Answer{11};
+ S_ws.PeakOnset = Answer{12};
+ estudioworkingmemory('geterpvalues',S_ws);
+ if strcmp(EStudio_erp_m_t_p.Viewer,'on')
+
+ moption = EStudio_erp_m_t_p.Measure;
+ latency = EStudio_erp_m_t_p.latency;
+ if isempty(moption)
+ beep;
+ msgboxText = ['ERP Measurement Tool - User must specify a type of measurement'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if ismember_bc2({moption}, {'instabl', 'areazt','areazp','areazn', 'nintegz'})
+ if length(latency)~=1
+ beep;
+ msgboxText = ['ERP Measurement Tool - ',32,moption ' only needs 1 latency value'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ else
+ if length(latency)~=2
+ beep;
+ msgboxText = ['ERP Measurement Tool - ',32,moption ' needs 2 latency values'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ else
+ if latency(1)>=latency(2)
+ beep;
+ msgboxText = ['ERP Measurement Tool - For latency range, lower time limit must be on the left.\n'...
+ 'Additionally, lower time limit must be at least 1/samplerate seconds lesser than the higher one'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+ end
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ end
+
+ end
+
+%%----------------------------ERPset custom--------------------------------
+ function erpset_custom(Source,~)
+ ERPsetArray = str2num(Source.String);
+ ERPsetArraydef = estudioworkingmemory('selectederpstudio');
+ if isempty(ERPsetArray) || max(ERPsetArray)> length(observe_ERPDAT.ALLERP)
+ if isempty(ERPsetArraydef) || max(ERPsetArraydef)> length(observe_ERPDAT.ALLERP)
+ Source.String = '';
+ else
+ Source.String = num2str(vect2colon(ERPsetArraydef,'Sort','on'));
+ end
+ return;
+ else
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,ERPsetArray);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ Current_ERP_selected=ERPsetArray(1);
+ observe_ERPDAT.CURRENTERP = Current_ERP_selected;
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_ERP_selected);
+
+ estudioworkingmemory('selectederpstudio',ERPsetArray);
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ end
+
+ end
+
+%%-------------Select bins by user custom----------------------------------
+ function binSelect_custom(source,~)
+ binNums = str2num(source.String);
+ [chk, msgboxText] = f_ERP_chckbinandchan(observe_ERPDAT.ERP, binNums, [],1);
+
+ if chk(1)
+ binArray= observe_ERPDAT.ERP_bin;
+ source.String = num2str(binArray);
+
+ beep;
+ msgboxText = ['ERP Measurement Tool -',32,msgboxText];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if ~isempty(binNums)
+ binNums = unique_bc2(binNums);
+ binList = 1:observe_ERPDAT.ERP.nbin;
+ indxlistb = binNums;
+ [~,y_check_bin] =find(indxlistb>observe_ERPDAT.ERP.nbin);
+ if any(y_check_bin)
+ mnamex = ['Label of one of the imported bins was higher than the number of bins (',num2str(observe_ERPDAT.ERP.nbin),').'];
+ question = [ '%s\n\n Please input or select bins of interst from "Bin:" on the "ERP Measurement Tool" panel again.\n'];
+ title = 'EStudio: ERP Measurement Tool';
+ button = questdlg(sprintf(question, mnamex), title,'OK','OK');
+ return;
+ end
+
+ indxlistb = indxlistb(indxlistb<=length(binList));
+ EStudio_erp_m_t_p.binArray = indxlistb;
+ S_ws= estudioworkingmemory('geterpvalues');
+ if isempty(S_ws)
+ return;
+ end
+ S_ws.binArray = EStudio_erp_m_t_p.binArray;
+ estudioworkingmemory('geterpvalues',S_ws);clear S_ws;
+ %Remark the selected bin in bin and Channel selection
+ if strcmp(EStudio_erp_m_t_p.Viewer,'on')
+ SelectedERP_Index = estudioworkingmemory('selectederpstudio');
+ if isempty(SelectedERP_Index)
+ SelectedERP_Index = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP_Index);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ estudioworkingmemory('selectederpstudio',SelectedERP_Index);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ Select_index = S_binchan.Select_index;
+
+ Bin_label_select = indxlistb;
+ if isempty(Bin_label_select)
+ beep;
+ disp(['No bin was selected']);
+ return;
+ end
+ if S_binchan.checked_ERPset_Index(1) ==1% The number of bins varied across the selected erpsets
+ S_binchan.bins{Select_index} = Bin_label_select;
+ S_binchan.bin_n(Select_index) = numel(Bin_label_select);
+ else
+
+ for Numofselecterp = 1:numel(SelectedERP_Index)
+ S_binchan.bins{Numofselecterp} = Bin_label_select;
+ S_binchan.bin_n(Numofselecterp) = numel(Bin_label_select);
+ end
+
+ end
+ estudioworkingmemory('geterpbinchan',S_binchan);
+ end
+ observe_ERPDAT.ERP_bin = indxlistb;
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ end
+ end
+
+
+%%----------------Option for erpset----------------------------------------
+ function erpsetop(~,~)
+ ERPsetArraydef = estudioworkingmemory('selectederpstudio');
+ if isempty(ERPsetArraydef) || max(ERPsetArraydef)> length(observe_ERPDAT.ALLERP)
+ ERPsetArraydef = observe_ERPDAT.CURRENTERP;
+ end
+ for Numoferpset = 1:length(observe_ERPDAT.ALLERP)
+ listname{Numoferpset} = char(strcat(num2str(Numoferpset),'.',observe_ERPDAT.ALLERP(Numoferpset).erpname));
+ end
+ indxlistb =ERPsetArraydef;
+
+ titlename = 'Select ERPset(s):';
+ ERPset_select = browsechanbinGUI(listname, indxlistb, titlename);
+
+ if ~isempty(ERPset_select)
+ ERPMTops.m_t_erpset.String = num2str(vect2colon(ERPset_select,'Sort','on'));
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,ERPset_select);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ Current_ERP_selected=ERPset_select(1);
+ observe_ERPDAT.CURRENTERP = Current_ERP_selected;
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_ERP_selected);
+ estudioworkingmemory('selectederpstudio',ERPset_select);
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ else
+ return;
+ end
+
+ end
+
+
+
+%%---------------Bins selection from "Option"------------------------------
+ function binSelect_label(Source,~)
+ ERP_CURRENT = evalin('base','ERP');
+ for Numofbin = 1:length(ERP_CURRENT.bindescr)
+ listb{Numofbin} = char(strcat(num2str(Numofbin),'.',ERP_CURRENT.bindescr{Numofbin}));
+ end
+ try
+ indxlistb =EStudio_erp_m_t_p.binArray;
+ catch
+ indxlistb = 1:ERP_CURRENT.nbin;
+ end
+ titlename = 'Select Bin(s):';
+ %----------------judge the number of latency/latencies--------
+ if ~isempty(listb)
+ bin_label_select = browsechanbinGUI(listb, indxlistb, titlename);
+ if ~isempty(bin_label_select)
+ EStudio_erp_m_t_p.binArray = bin_label_select;
+ ERPMTops.m_t_bin.String=num2str(vect2colon(EStudio_erp_m_t_p.binArray,'Sort', 'on'));
+ else
+ disp('User selected Cancel');
+ return
+ end
+ else
+ beep;
+ msgboxText = ['ERP Measurement Tool - No bin information was found'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end%Program end: Judge the number of latency/latencies
+ S_ws= estudioworkingmemory('geterpvalues');
+ if isempty(S_ws)
+ return;
+ end
+
+ S_ws.binArray = EStudio_erp_m_t_p.binArray;
+ estudioworkingmemory('geterpvalues',S_ws);clear S_ws;
+ %Remark the selected bin in bin and Channel selection
+ if strcmp(EStudio_erp_m_t_p.Viewer,'on')
+ SelectedERP_Index = estudioworkingmemory('selectederpstudio');
+ if isempty(SelectedERP_Index)
+ SelectedERP_Index = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP_Index);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ estudioworkingmemory('selectederpstudio',SelectedERP_Index);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ Select_index = S_binchan.Select_index;
+
+ Bin_label_select = bin_label_select;
+ if isempty(Bin_label_select)
+ beep;
+ disp(['No bin was selected']);
+ return;
+ end
+ EStudio_erp_m_t_p.binArray = bin_label_select;
+ if S_binchan.checked_ERPset_Index(1) ==1% The number of bins varied across the selected erpsets
+ S_binchan.bins{Select_index} = Bin_label_select;
+ S_binchan.bin_n(Select_index) = numel(Bin_label_select);
+ else
+ for Numofselecterp = 1:numel(SelectedERP_Index)
+ S_binchan.bins{Numofselecterp} = Bin_label_select;
+ S_binchan.bin_n(Numofselecterp) = numel(Bin_label_select);
+ end
+ end
+ estudioworkingmemory('geterpbinchan',S_binchan);
+ end
+ observe_ERPDAT.ERP_bin = bin_label_select;
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ end
+
+
+%%----------------Define the channels of interest----------------------
+ function chanSelect_custom(Source,~)
+ chanNums = str2num(Source.String);
+ [chk, msgboxText] = f_ERP_chckbinandchan(observe_ERPDAT.ERP, [], chanNums,2);
+
+ if chk(2)
+ chanArray= observe_ERPDAT.ERP_chan;
+ Source.String = num2str(chanArray);
+ beep;
+ msgboxText = ['ERP Measurement Tool -',32,msgboxText];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if ~isempty(chanNums)
+ chanNums = unique_bc2(chanNums);
+ chanList = 1:observe_ERPDAT.ERP.nchan;
+ indxlist_chan = chanNums;
+
+ [~,y_check_bin] =find(indxlist_chan>observe_ERPDAT.ERP.nchan);
+ if any(y_check_bin)
+ mnamex = ['Label of one of the imported channels was higher than the number of channels (',num2str(observe_ERPDAT.ERP.nchan),').'];
+ question = [ '%s\n\n Please input or select bins of interst from "Channel:" on the "ERP Measurement Tool" panel again.\n'];
+ title = 'ERPLAB Studio: ERP Measurement Tool';
+ button = questdlg(sprintf(question, mnamex), title,'OK','OK');
+ return;
+ end
+
+ indxlist_chan = indxlist_chan(indxlist_chan<=length(chanList));
+ EStudio_erp_m_t_p.chanArray = indxlist_chan;
+ S_ws= estudioworkingmemory('geterpvalues');
+ if isempty(S_ws)
+ return;
+ end
+ S_ws.chanArray = EStudio_erp_m_t_p.chanArray;
+ estudioworkingmemory('geterpvalues',S_ws);clear S_ws;
+ %When the "Viewer" is active on the measurement Tool panel---------
+ if strcmp(EStudio_erp_m_t_p.Viewer,'on')
+ SelectedERP_Index = estudioworkingmemory('selectederpstudio');
+ if isempty(SelectedERP_Index)
+ SelectedERP_Index = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP_Index);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ estudioworkingmemory('selectederpstudio',SelectedERP_Index);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ Select_index = S_binchan.Select_index;
+ chan_label_select = indxlist_chan;
+
+ if S_binchan.checked_ERPset_Index(2) ==2%% the number of channels varied across ERPsets
+ S_binchan.elecs_shown{S_binchan.Select_index} = chan_label_select;
+ S_binchan.elec_n(Select_index) = numel(chan_label_select);
+ S_binchan.first_elec(Select_index) = chan_label_select(1);
+ else
+
+ for Numofselecterp = 1:numel(SelectedERP_Index)
+ S_binchan.elecs_shown{Numofselecterp} = chan_label_select;
+ S_binchan.elec_n(Numofselecterp) = numel(chan_label_select);
+ S_binchan.first_elec(Numofselecterp) = chan_label_select(1);
+ end
+
+ end
+ estudioworkingmemory('geterpbinchan',S_binchan);
+ end
+ observe_ERPDAT.ERP_chan = indxlist_chan;
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ end
+
+ end
+
+
+%%----------------Channels selection from option--------------------------------------
+ function chanSelect_label(Source,~)
+ ERP_CURRENT = evalin('base','ERP');
+
+ if isempty(ERP_CURRENT.nchan) || ERP_CURRENT.nchan ==0
+ beep;
+ msgboxText = ['ERP Measurement Tool -No channel information was found'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ for Numofchan = 1:ERP_CURRENT.nchan
+ listb{Numofchan}= strcat(num2str(Numofchan),'.',ERP_CURRENT.chanlocs(Numofchan).labels);
+ end
+ try
+ indxlistb= EStudio_erp_m_t_p.chanArray ;
+ catch
+ indxlistb = 1:ERP_CURRENT.nchan;
+ end
+ titlename = 'Select Channel(s):';
+
+ if ~isempty(listb)
+ chan_label_select = browsechanbinGUI(listb, indxlistb, titlename);
+ if ~isempty(chan_label_select)
+ EStudio_erp_m_t_p.chanArray = chan_label_select;
+ %%%Save the changed parameters
+ S_ws= estudioworkingmemory('geterpvalues');
+ if isempty(S_ws)
+ return;
+ end
+
+ S_ws.chanArray = EStudio_erp_m_t_p.chanArray;
+ estudioworkingmemory('geterpvalues',S_ws); clear S_ws;
+ ERPMTops.m_t_chan.String=num2str(vect2colon(EStudio_erp_m_t_p.chanArray,'Sort', 'on'));
+ else
+ beep;
+ disp('User selected Cancel');
+ return
+ end
+ else
+ beep;
+ msgboxText = ['ERP Measurement Tool -No channel information was found'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ %When the "Viewer" is active on the measurement Tool panel---------
+ if strcmp(EStudio_erp_m_t_p.Viewer,'on')
+ SelectedERP_Index = estudioworkingmemory('selectederpstudio');
+ if isempty(SelectedERP_Index)
+ SelectedERP_Index = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP_Index);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ estudioworkingmemory('selectederpstudio',SelectedERP_Index);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ Select_index = S_binchan.Select_index;
+ if isempty(chan_label_select)
+ beep;
+ disp(['No channel was selected']);
+ return;
+ end
+ if S_binchan.checked_ERPset_Index(2) ==2%% the number of channels varied across ERPsets
+ S_binchan.elecs_shown{S_binchan.Select_index} = chan_label_select;
+ S_binchan.elec_n(Select_index) = numel(chan_label_select);
+ S_binchan.first_elec(Select_index) = chan_label_select(1);
+ else
+
+ for Numofselecterp = 1:numel(SelectedERP_Index)
+ S_binchan.elecs_shown{Numofselecterp} = chan_label_select;
+ S_binchan.elec_n(Numofselecterp) = numel(chan_label_select);
+ S_binchan.first_elec(Numofselecterp) = chan_label_select(1);
+ end
+ end
+ estudioworkingmemory('geterpbinchan',S_binchan);
+ end
+ chanArray = str2num(ERPMTops.m_t_chan.String);
+ if ~isempty(chanArray)
+ observe_ERPDAT.ERP_chan = chanArray;
+ end
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ end
+
+%%-----------------Measurement time-window-------------------------------%%
+ function t_w_set(source_tw,~)
+ if isempty(str2num(source_tw.String))
+ beep;
+ msgboxText = ['ERP Measurement Tool -No measurement window was set'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ else
+ lat_erp = unique_bc2(str2num(source_tw.String));
+ EStudio_erp_m_t_p.latency = lat_erp;
+ moption = EStudio_erp_m_t_p.Measure;
+ latency = EStudio_erp_m_t_p.latency;
+ if isempty(moption)
+ beep;
+ msgboxText = ['ERP Measurement Tool - User must specify a type of measurement'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if ismember_bc2({moption}, {'instabl', 'areazt','areazp','areazn', 'nintegz'})
+ if length(latency)~=1
+ beep;
+ msgboxText = ['ERP Measurement Tool -',32,moption ' only needs 1 latency value'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ else
+ if length(latency)~=2
+ beep;
+ msgboxText = ['ERP Measurement Tool -',32,moption ' needs 2 latency values'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ else
+ if latency(1)>=latency(2)
+ beep;
+ msgboxText = ['ERP Measurement Tool -For latency range, lower time limit must be on the left.\n'...
+ 'Additionally, lower time limit must be at least 1/samplerate seconds lesser than the higher one'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+ end
+
+
+ S_ws= estudioworkingmemory('geterpvalues');
+ if isempty(S_ws)
+ return;
+ end
+ S_ws.latency = lat_erp;
+ estudioworkingmemory('geterpvalues',S_ws); clear S_ws;
+
+ end
+ if strcmp(EStudio_erp_m_t_p.Viewer,'on')
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ end
+ end
+
+
+%-------------------------Baseline period---------------------------------
+ function baseline_set(~,~)
+ try
+ S_ws=estudioworkingmemory('geterpvalues');
+ Answer = f_ERP_meas_basecorr(S_ws.Baseline);
+ catch
+ Answer = f_ERP_meas_basecorr('none');
+ end
+
+ if isempty(Answer)
+ beep;
+ disp('User selected cancel');
+ return;
+ end
+ ERP_times = observe_ERPDAT.ERP.times;
+ latency = str2num(Answer);
+ if ~isempty(latency)
+ if latency(1)>=latency(2)
+ beep;
+ msgboxText = ['ERP Measurement Tool - The first latency should be smaller than the second one'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if latency(1)< ERP_times(1)
+ beep;
+ msgboxText = ['ERP Measurement Tool - The defined first latency should be larger than',32, num2str(ERP_times(1)),'ms'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if latency(2)> ERP_times(end)
+ beep;
+ msgboxText = ['ERP Measurement Tool - The defined second latency should be smaller than',32, num2str(ERP_times(end)),'ms'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if latency(1)> ERP_times(end)
+ beep;
+ msgboxText = ['ERP Measurement Tool - The defined first latency should be smaller than',32, num2str(ERP_times(end)),'ms'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+
+ S_ws= estudioworkingmemory('geterpvalues');
+ S_ws.Baseline = Answer;
+ estudioworkingmemory('geterpvalues',S_ws);clear S_ws;
+
+ if strcmp(EStudio_erp_m_t_p.Viewer,'on')
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ end
+ end
+
+%%------------------File name setting for the output file.----------------
+ function file_name_set(source_file_name,~)
+ EStudio_erp_m_t_p.Filename = source_file_name.String;
+ S_ws=estudioworkingmemory('geterpvalues');
+ S_ws.Filename = source_file_name.String;
+ estudioworkingmemory('geterpvalues',S_ws);clear S_ws;
+ end
+
+%%-------------------Path setting to save the measurement results----------
+ function out_file_option(~,~)
+ if strcmp(EStudio_erp_m_t_p.FileFormat,'wide')
+ FileFormat = 0;
+ else
+ FileFormat = 1;
+ end
+ pathName_folder_default = erpworkingmemory('ERP_save_folder');
+ FileName = EStudio_erp_m_t_p.Filename;
+ [pathNamex, fname, ext] = fileparts(FileName);
+ Answer = f_ERP_meas_format_path(FileFormat,fullfile(pathName_folder_default,fname));
+
+ if isempty(Answer)
+ disp('User selected Cancel');
+ return;
+
+ end
+ if Answer{1}==1 % 1 means "long format"; 0 means "wide format"
+ foutputstr = 'long';
+ else
+ foutputstr = 'wide';
+ end
+
+ S_ws=estudioworkingmemory('geterpvalues');
+ S_ws.Filename = Answer{2};
+ S_ws.FileFormat = foutputstr;
+ estudioworkingmemory('geterpvalues',S_ws);clear S_ws;
+
+ EStudio_erp_m_t_p.FileFormat = foutputstr;
+ EStudio_erp_m_t_p.Filename = Answer{2};
+ ERPMTops.m_t_file.String = EStudio_erp_m_t_p.Filename;
+
+ end
+
+
+%%---------------Viewer:ON------------------------------
+ function m_t_viewer_on(~,~)
+ Source_value = 1;
+ set(ERPMTops.m_t_viewer_on,'Value',Source_value);
+ set(ERPMTops.m_t_viewer_off,'Value',~Source_value);
+ EStudio_erp_m_t_p.Viewer = 'on';
+ S_ws= estudioworkingmemory('geterpvalues');
+ S_ws.Viewer = EStudio_erp_m_t_p.Viewer;
+ estudioworkingmemory('geterpvalues',S_ws);clear S_ws;
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ end
+
+%%---------------Viewer:Off------------------------------
+ function m_t_viewer_off(~,~)
+ Source_value = 1;
+ set(ERPMTops.m_t_viewer_off,'Value',Source_value);
+ set(ERPMTops.m_t_viewer_on,'Value',~Source_value);
+ EStudio_erp_m_t_p.Viewer = 'off';
+ S_ws=estudioworkingmemory('geterpvalues');
+ S_ws.Viewer = EStudio_erp_m_t_p.Viewer;
+ estudioworkingmemory('geterpvalues',S_ws);clear S_ws;
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ end
+
+
+%%--------------------Apply the set parameters to selected ERPset----------
+ function apply_erp_m_t(~,~)
+ pathName_folder = erpworkingmemory('ERP_save_folder');
+ if isempty(pathName_folder)
+ pathName_folder = cd;
+ end
+
+ EStudio_erp_m_t_p =estudioworkingmemory('geterpvalues');
+ if isempty(EStudio_erp_m_t_p)
+ EStudio_erp_m_t_p =EStudio_erp_m_t_p;
+ return;
+ end
+
+ SelectedERP_Index = estudioworkingmemory('selectederpstudio');
+ if isempty(SelectedERP_Index)
+ SelectedERP_Index = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP_Index);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ estudioworkingmemory('selectederpstudio',SelectedERP_Index);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+
+ EStudio_erp_m_t_p.Erpsets = SelectedERP_Index;
+
+ MeasureName = {'meanbl','peakampbl', 'peaklatbl','fareatlat','fpeaklat','fninteglat','fareaplat','fareanlat',...
+ 'areat','ninteg','areap','arean','areazt','nintegz','areazp','areazn','instabl'};
+ [C,IA] = ismember_bc2({EStudio_erp_m_t_p.Measure}, MeasureName);
+ if ~any(IA) || isempty(IA)
+ IA =1;
+ end
+ if isempty(EStudio_erp_m_t_p.Filename)
+ beep;
+ msgboxText = ['ERP Measurement Tool - Please set a name for the output file'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if isempty(EStudio_erp_m_t_p.latency)
+ beep;
+ msgboxText = ['ERP Measurement Tool - Please set a Measurement window'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ moption = EStudio_erp_m_t_p.Measure;
+ latency = EStudio_erp_m_t_p.latency;
+ if isempty(moption)
+ beep;
+ msgboxText = ['ERP Measurement Tool - User must specify a type of measurement'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if ismember_bc2({moption}, {'instabl', 'areazt','areazp','areazn', 'nintegz'})
+ if length(latency)~=1
+ beep;
+ msgboxText = ['ERP Measurement Tool - ',32, moption ' only needs 1 latency value'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ else
+ if length(latency)~=2
+ beep;
+ msgboxText = ['ERP Measurement Tool - ',32,moption ' needs 2 latency values.'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ else
+ if latency(1)>=latency(2)
+ beep;
+ msgboxText = ['ERP Measurement Tool - For latency range, lower time limit must be on the left.\n'...
+ 'Additionally, lower time limit must be at least 1/samplerate seconds lesser than the higher one.'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+ end
+ ALLERP = evalin('base','ALLERP');
+
+ [chk, msgboxText] = f_ERP_chckbinandchan(observe_ERPDAT.ERP, EStudio_erp_m_t_p.binArray, [],1);
+
+ if chk(1)
+ beep;
+ msgboxText = ['ERP Measurement Tool - ',32,msgboxText];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ [chk, msgboxText] = f_ERP_chckbinandchan(observe_ERPDAT.ERP, [], EStudio_erp_m_t_p.chanArray,2);
+
+ if chk(2)
+ beep;
+ msgboxText = ['ERP Measurement Tool - ',32,msgboxText];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ FileName = EStudio_erp_m_t_p.Filename;
+ [pathNamex, fname, ext] = fileparts(FileName);
+ if isempty(fname)
+ beep;
+ msgboxText = ['ERP Measurement Tool - Please give a name to the output file'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if isempty(pathNamex)
+ EStudio_erp_m_t_p.Filename = fullfile(pathName_folder,fname);
+ end
+
+
+ erpworkingmemory('f_ERP_proces_messg',' ERP Measurement Tool (Save values)');
+ observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started.
+
+ try
+ if ~isempty(EStudio_erp_m_t_p.latency)
+ %
+ [ALLERP, Amp, Lat, erpcom] = pop_geterpvalues(ALLERP, EStudio_erp_m_t_p.latency, EStudio_erp_m_t_p.binArray, EStudio_erp_m_t_p.chanArray,...
+ 'Erpsets', EStudio_erp_m_t_p.Erpsets, 'Measure',MeasureName{IA}, 'Component', EStudio_erp_m_t_p.Component,...
+ 'Resolution', EStudio_erp_m_t_p.Resolution, 'Baseline', EStudio_erp_m_t_p.Baseline, 'Binlabel', EStudio_erp_m_t_p.Binlabel,...
+ 'Peakpolarity',EStudio_erp_m_t_p.Peakpolarity, 'Neighborhood', EStudio_erp_m_t_p.Neighborhood, 'Peakreplace', EStudio_erp_m_t_p.Peakreplace,...
+ 'Filename', EStudio_erp_m_t_p.Filename, 'Warning',EStudio_erp_m_t_p.Warning,'SendtoWorkspace', EStudio_erp_m_t_p.SendtoWorkspace, 'Append', EStudio_erp_m_t_p.Append,...
+ 'FileFormat', EStudio_erp_m_t_p.FileFormat,'Afraction', EStudio_erp_m_t_p.Afraction, 'Mlabel', EStudio_erp_m_t_p.Mlabel,...
+ 'Fracreplace', EStudio_erp_m_t_p.Fracreplace,'IncludeLat', EStudio_erp_m_t_p.IncludeLat, 'InterpFactor', EStudio_erp_m_t_p.InterpFactor,...
+ 'PeakOnset',EStudio_erp_m_t_p.PeakOnset,'History', 'gui');
+ %%%------------Save history to current session--------------
+ ALLERPCOM = evalin('base','ALLERPCOM');
+ [~, ALLERPCOM] = erphistory(observe_ERPDAT.ERP, ALLERPCOM, erpcom);
+ assignin('base','ALLERPCOM',ALLERPCOM);
+
+ %%---------------save the applied parameters using erpworkingmemory function--------------------
+ EStudio_erp_m_t_p_save = EStudio_erp_m_t_p;
+ if strcmp(EStudio_erp_m_t_p_save.Binlabel,'off')
+ EStudio_erp_m_t_p_save.Binlabel = 0;
+ else
+ EStudio_erp_m_t_p_save.Binlabel = 1;
+ end
+
+ if strcmp(EStudio_erp_m_t_p_save.Peakpolarity,'negative')
+ EStudio_erp_m_t_p_save.Peakpolarity = 0;
+ else
+ EStudio_erp_m_t_p_save.Peakpolarity = 1;
+ end
+
+ if strcmp(EStudio_erp_m_t_p_save.Peakreplace,'NaN')
+ EStudio_erp_m_t_p_save.Peakreplace = 0;
+ else
+ EStudio_erp_m_t_p_save.Peakreplace = 1;
+ end
+
+ if strcmp(EStudio_erp_m_t_p_save.Fracreplace,'NaN') % Fractional area latency replacement
+ EStudio_erp_m_t_p_save.Fracreplace = 0;
+ else
+ EStudio_erp_m_t_p_save.Fracreplace = 1;
+ end
+
+ if strcmp(EStudio_erp_m_t_p_save.SendtoWorkspace,'off')
+ EStudio_erp_m_t_p_save.SendtoWorkspace=0;
+ else
+ EStudio_erp_m_t_p_save.SendtoWorkspace=1;
+ end
+
+ if strcmp(EStudio_erp_m_t_p_save.FileFormat,'wide')
+ EStudio_erp_m_t_p_save.FileFormat = 0;
+ else
+ EStudio_erp_m_t_p_save.FileFormat = 1;
+ end
+
+ if strcmp(EStudio_erp_m_t_p_save.IncludeLat,'no')
+ EStudio_erp_m_t_p_save.IncludeLat = 0;
+ else
+ EStudio_erp_m_t_p_save.IncludeLat = 1;
+ end
+
+ erpworkingmemory('pop_geterpvalues', {CurrentERPSet, EStudio_erp_m_t_p_save.Erpsets, EStudio_erp_m_t_p_save.Filename, EStudio_erp_m_t_p_save.latency,...
+ EStudio_erp_m_t_p_save.binArray, EStudio_erp_m_t_p_save.chanArray, EStudio_erp_m_t_p_save.Measure, EStudio_erp_m_t_p_save.Component, EStudio_erp_m_t_p_save.Resolution, EStudio_erp_m_t_p_save.Baseline,...
+ EStudio_erp_m_t_p_save.Binlabel, EStudio_erp_m_t_p_save.Peakpolarity,EStudio_erp_m_t_p_save.Neighborhood, EStudio_erp_m_t_p_save.Peakreplace,...
+ EStudio_erp_m_t_p_save.Afraction, EStudio_erp_m_t_p_save.Fracreplace,EStudio_erp_m_t_p_save.SendtoWorkspace, EStudio_erp_m_t_p_save.FileFormat, EStudio_erp_m_t_p_save.Mlabel,...
+ EStudio_erp_m_t_p_save.IncludeLat, EStudio_erp_m_t_p_save.InterpFactor, EStudio_erp_m_t_p_save.PeakOnset});
+
+ end
+ observe_ERPDAT.Process_messg =2;
+ catch
+ beep;
+ msgboxText = ['ERP Measurement Tool - Cannot export the values'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ end
+
+
+
+%----------displayed channel label will be midified after vaied channels was selected--------
+ function ERP_chan_changed(~,~)
+ ERPMTops.m_t_chan.String = num2str(vect2colon(observe_ERPDAT.ERP_chan,'Sort', 'on'));
+ S_ws= estudioworkingmemory('geterpvalues');
+ S_ws.chanArray = observe_ERPDAT.ERP_chan;
+ EStudio_erp_m_t_p.chanArray = observe_ERPDAT.ERP_chan;
+ estudioworkingmemory('geterpvalues',S_ws); clear S_ws;
+ end
+
+%----------displayed bin label will be midified after different channels was selected--------
+ function ERP_bin_changed(~,~)
+ ERPMTops.m_t_bin.String = num2str(vect2colon(observe_ERPDAT.ERP_bin,'Sort', 'on'));
+ S_ws= estudioworkingmemory('geterpvalues');
+ S_ws.binArray = observe_ERPDAT.ERP_bin;
+ EStudio_erp_m_t_p.binArray = observe_ERPDAT.ERP_bin;
+ estudioworkingmemory('geterpvalues',S_ws);clear S_ws;
+ end
+
+
+%%--------Settting if the current panel is active or not based on the selected ERPsets------------
+ function Count_currentERP_change(~,~)
+ Selectederp_Index= estudioworkingmemory('selectederpstudio');
+ if isempty(Selectederp_Index)
+ Selectederp_Index = observe_ERPDAT.CURRENTERP;
+ if isempty(Selectederp_Index)
+ beep;
+ msgboxText = ['ERP Measurement Tool - No ERPset was selected'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ ERPMTops.m_t_erpset.String= num2str(vect2colon(Selectederp_Index,'Sort','on'));%%Dec 20 2022
+ if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded')
+ checked_curr_index = 1;
+ else
+ checked_curr_index = 0;
+ end
+
+ checked_ERPset_Index = S_binchan.checked_ERPset_Index;
+ if checked_curr_index || any(checked_ERPset_Index(:))
+ ERPMTops.m_t_value.Enable = 'off';
+ else
+ ERPMTops.m_t_value.Enable = 'on';
+ end
+ Enable_label = 'on';
+ ERPMTops.m_t_type.Enable = Enable_label;
+ ERPMTops.m_t_type_ops.Enable = Enable_label;
+ ERPMTops.m_t_bin.Enable = Enable_label;
+ ERPMTops.m_t_bin_ops.Enable = Enable_label;
+ ERPMTops.m_t_chan.Enable = Enable_label;
+ ERPMTops.m_t_chan_ops.Enable = Enable_label;
+ ERPMTops.m_t_TW.Enable = Enable_label;
+ ERPMTops.m_t_TW_ops.Enable = Enable_label;
+ ERPMTops.m_t_file.Enable = Enable_label;
+ ERPMTops.m_t_file_ops.Enable = Enable_label;
+ ERPMTops.m_t_viewer.Enable = Enable_label;
+ ERPMTops.m_t_advanced.Enable = Enable_label;
+ ERPMTops.m_t_viewer_on.Enable = Enable_label;
+ ERPMTops.m_t_viewer_off.Enable = Enable_label;
+ ERPMTops.m_t_erpset.Enable = Enable_label;
+ ERPMTops.m_t_erpset_ops.Enable = Enable_label;
+ if checked_ERPset_Index(1)==1
+ ERPMTops.m_t_bin.Enable = 'off';
+ ERPMTops.m_t_bin_ops.Enable = 'off';
+ else
+ ERPMTops.m_t_bin.Enable = 'on';
+ ERPMTops.m_t_bin_ops.Enable = 'on';
+ end
+ if checked_ERPset_Index(2)==2
+ ERPMTops.m_t_chan.Enable = 'off';
+ ERPMTops.m_t_chan_ops.Enable = 'off';
+ else
+ ERPMTops.m_t_chan.Enable = 'on';
+ ERPMTops.m_t_chan_ops.Enable = 'on';
+ end
+ end
+
+end%Progem end: ERP Measurement tool
\ No newline at end of file
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_plot_scalp_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_plot_scalp_GUI.m
new file mode 100755
index 00000000..964fb78f
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_plot_scalp_GUI.m
@@ -0,0 +1,1468 @@
+%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com
+%Center for Mind and Brain
+%University of California, Davis
+%Davis, CA, USA
+%Feb. 2022
+
+% ERPLAB Studio
+
+function varargout = f_ERP_plot_scalp_GUI(varargin)
+global observe_ERPDAT;
+gui_erp_scalp_map = struct();
+% addlistener(observe_ERPDAT,'ALLERP_change',@allErpChanged);
+% addlistener(observe_ERPDAT,'ERP_change',@onErpChanged);
+% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange);
+addlistener(observe_ERPDAT,'ERP_bin_change',@ERP_bin_changed);
+addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged);
+
+
+
+%-----------------------------Name the title----------------------------------------------
+% global ERP_plot_scalp_gui;
+[version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+if nargin == 0
+ fig = figure(); % Parent figure
+ ERP_plot_scalp_gui = uiextras.BoxPanel('Parent', fig, 'Title', 'Plot Scalp Maps', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel
+elseif nargin == 1
+ ERP_plot_scalp_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Plot Scalp Maps', 'Padding', 5,'BackgroundColor',ColorB_def);
+else
+ ERP_plot_scalp_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Plot Scalp Maps', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def);
+end
+
+%-----------------------------Draw the panel-------------------------------------
+try
+ FonsizeDefault = varargin{2};
+catch
+ FonsizeDefault = [];
+end
+if isempty(FonsizeDefault)
+ FonsizeDefault = f_get_default_fontsize();
+end
+drawui_erp_scalp_operation(FonsizeDefault);
+
+varargout{1} = ERP_plot_scalp_gui;
+
+ function drawui_erp_scalp_operation(FonsizeDefault)
+ % FontSize_defualt = erpworkingmemory('fontsizeGUI');
+ % if isempty(FontSize_defualt)
+ FontSize_defualt = 12;
+ % end
+ if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded')
+ Enable_label = 'off';
+ else
+ Enable_label = 'on';
+ end
+
+ plegend.binnum = 1;
+ plegend.bindesc = 1;
+ plegend.type = 1;
+ plegend.latency = 1;
+ plegend.electrodes = 0;
+ plegend.elestyle = 'on';
+ plegend.elec3D = 'off';
+ plegend.colorbar = 1;
+ plegend.colormap = 0;
+ plegend.maximize = 0;
+ estudioworkingmemory('pscalp_plegend',plegend);
+ agif.value =0;
+ agif.fps =[];
+ agif.fname ='';
+ estudioworkingmemory('pscalp_agif',agif);
+
+
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+ %%--------------------bin and latency setting----------------------
+ gui_erp_scalp_map.ERPscalpops = uiextras.VBox('Parent', ERP_plot_scalp_gui,'BackgroundColor',ColorB_def);
+
+ %%%------------BIN TO PLOT---------------------
+ gui_erp_scalp_map.bin_latency_title = uiextras.HBox('Parent', gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def);
+ uicontrol('Style', 'text','Parent', gui_erp_scalp_map.bin_latency_title,...
+ 'String','Bin & Latency:','FontWeight','bold','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ gui_erp_scalp_map.bin_plot_title = uiextras.HBox('Parent', gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def);
+ gui_erp_scalp_map.bin_plot = uicontrol('Style','text','Parent',gui_erp_scalp_map.bin_plot_title,...
+ 'String','Bin(s)','FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F
+ set(gui_erp_scalp_map.bin_plot,'HorizontalAlignment','left');
+ gui_erp_scalp_map.bin_plot_edit = uicontrol('Style','edit','Parent',gui_erp_scalp_map.bin_plot_title,...
+ 'String','','callback',@scalp_bin_edit,'FontSize',FontSize_defualt,'Enable',Enable_label,'BackgroundColor',[1 1 1]); % 2F
+ gui_erp_scalp_map.bin_plot_opt = uicontrol('Style','pushbutton','Parent',gui_erp_scalp_map.bin_plot_title,...
+ 'String','Browse','callback',@scalp_bin_op,'FontSize',FontSize_defualt,'Enable',Enable_label,'BackgroundColor',[1 1 1]); % 2F
+ set(gui_erp_scalp_map.bin_plot_title ,'Sizes',[60 150 60]);
+
+ %%%------------Latency TO PLOT---------------------
+ gui_erp_scalp_map.latency_plot_title = uiextras.HBox('Parent', gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def);
+ gui_erp_scalp_map.latency_plot = uicontrol('Style','text','Parent',gui_erp_scalp_map.latency_plot_title,...
+ 'String','Latency (ms) [min max]','FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F
+ set(gui_erp_scalp_map.latency_plot,'HorizontalAlignment','left');
+ gui_erp_scalp_map.latency_plot_edit = uicontrol('Style','edit','Parent',gui_erp_scalp_map.latency_plot_title,...
+ 'String','','callback',@scalp_latency_plot,'FontSize',FontSize_defualt,'Enable',Enable_label,'BackgroundColor',[1 1 1]); % 2F
+
+ %%----------------------------------Map Type------------------------------
+ gui_erp_scalp_map.map_type_title = uiextras.HBox('Parent', gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def);
+ uicontrol('Style', 'text','Parent', gui_erp_scalp_map.map_type_title,...
+ 'String','Map Type:','FontWeight','bold','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ %%2d
+ gui_erp_scalp_map.map_type = uiextras.Grid('Parent',gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def);
+ %
+ gui_erp_scalp_map.map_type_2d = uicontrol('Style', 'radiobutton','Parent', gui_erp_scalp_map.map_type,...
+ 'String','2D','callback',@map_type_2d,'Value',1,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ gui_erp_scalp_map.map_type_3d = uicontrol('Style', 'radiobutton','Parent', gui_erp_scalp_map.map_type,...
+ 'String','3D','callback',@map_type_3d,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ gui_erp_scalp_map.map_type_2d_type = uicontrol('Style', 'popupmenu','Parent',gui_erp_scalp_map.map_type,...
+ 'String',{'map','contour','both','fill','blank'},'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]);
+ gui_erp_scalp_map.map_type_3d_spl = uicontrol('Style', 'pushbutton','Parent',gui_erp_scalp_map.map_type,...
+ 'String','Spline','callback',@map_type_3d_spl,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]);
+
+ gui_erp_scalp_map.map_type_2d_type_outside = uicontrol('Style', 'checkbox','Parent',gui_erp_scalp_map.map_type,...
+ 'String','Outside','Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_scalp_map.map_type);
+
+ set(gui_erp_scalp_map.map_type, 'ColumnSizes',[50 130 90],'RowSizes',[25 30]);
+
+ %%----------------------------------Bar scale------------------------------
+ gui_erp_scalp_map.bar_scale_title = uiextras.HBox('Parent', gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def);
+ uicontrol('Style', 'text','Parent', gui_erp_scalp_map.bar_scale_title,...
+ 'String','Color Bar Scale:','FontWeight','bold','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ gui_erp_scalp_map.bar_scale = uiextras.HBox('Parent',gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def);
+
+ gui_erp_scalp_map.max_min = uicontrol('Style', 'radiobutton','Parent', gui_erp_scalp_map.bar_scale,...
+ 'String','Max-Min','callback',@bar_scale_max_min,'Value',1,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ gui_erp_scalp_map.custom_option = uicontrol('Style', 'radiobutton','Parent',gui_erp_scalp_map.bar_scale,...
+ 'String','Custom (min max:e.g.uv)','callback',@bar_scale_custom_opt,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ set(gui_erp_scalp_map.bar_scale ,'Sizes',[100 170]);
+
+
+ gui_erp_scalp_map.bar_scale_2 = uiextras.HBox('Parent',gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def);
+ gui_erp_scalp_map.abs_max = uicontrol('Style', 'radiobutton','Parent', gui_erp_scalp_map.bar_scale_2,...
+ 'String','Abs Max','callback',@bar_scale_abs_max,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ gui_erp_scalp_map.bar_scale_custom_option_edit = uicontrol('Style', 'edit','Parent',gui_erp_scalp_map.bar_scale_2,...
+ 'String',' ','callback',@bar_scale_custom_edit,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]);
+ set(gui_erp_scalp_map.bar_scale_2 ,'Sizes',[100 170]);
+
+ %%----------------------------------Map Extras------------------------------
+ gui_erp_scalp_map.map_extras_title = uiextras.HBox('Parent', gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def);
+ uicontrol('Style', 'text','Parent', gui_erp_scalp_map.map_extras_title,...
+ 'String','Map Extras:','FontWeight','bold','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ %%view
+ gui_erp_scalp_map.map_extras_view = uiextras.HBox('Parent',gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def);
+
+ uicontrol('Style', 'text','Parent', gui_erp_scalp_map.map_extras_view,...
+ 'String','View','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def,'HorizontalAlignment','left');
+
+ morimenu = {'front', 'back', 'right', 'left', 'top',...
+ 'frontleft', 'frontright', 'backleft', 'backright',...
+ 'custom'};
+ gui_erp_scalp_map.map_extras_view_ops = uicontrol('Style', 'popupmenu','Parent',gui_erp_scalp_map.map_extras_view,...
+ 'String',morimenu,'callback',@map_extras_view_ops,'Enable','off','FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]);
+
+ gui_erp_scalp_map.map_extras_view_location = uicontrol('Style', 'edit','Parent',gui_erp_scalp_map.map_extras_view,...
+ 'String','','callback',@map_extras_view_location,'Enable','off','FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]);
+
+ set(gui_erp_scalp_map.map_extras_view,'Sizes',[70 100 100]);
+
+
+ %%Extras
+ gui_erp_scalp_map.map_extras_cmap_display= uiextras.HBox('Parent',gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def);
+
+ gui_erp_scalp_map.map_extras_cmap = uicontrol('Style', 'text','Parent', gui_erp_scalp_map.map_extras_cmap_display,...
+ 'String','Colormap','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ set(gui_erp_scalp_map.map_extras_cmap,'HorizontalAlignment','left');
+ cMap_par={'jet','hsv','hot','cool','gray','viridis'};
+ gui_erp_scalp_map.map_extras_cmap_ops = uicontrol('Style', 'popupmenu','Parent', gui_erp_scalp_map.map_extras_cmap_display,...
+ 'String',cMap_par,'Value',1,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',[1,1,1]);
+
+ gui_erp_scalp_map.map_extras_cmapb_disp = uicontrol('Style', 'checkbox','Parent', gui_erp_scalp_map.map_extras_cmap_display,...
+ 'String','Display color scale bar','Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ gui_erp_scalp_map.map_extras_cmapb_disp.String = 'Display Color Scale Bar';
+ set(gui_erp_scalp_map.map_extras_cmap_display ,'Sizes',[70 90 110]);
+
+
+ %%-----------------Run---------------------------------------------
+ gui_erp_scalp_map.run_title = uiextras.HBox('Parent', gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def);
+
+ uicontrol('Style','pushbutton','Parent',gui_erp_scalp_map.run_title,...
+ 'String','?','callback',@scap_help,'FontSize',16,'Enable','on'); % 2F
+
+ gui_erp_scalp_map.advanced = uicontrol('Style','pushbutton','Parent',gui_erp_scalp_map.run_title,...
+ 'String','Advanced','callback',@apply_advanced,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F
+
+ gui_erp_scalp_map.run = uicontrol('Style','pushbutton','Parent',gui_erp_scalp_map.run_title,...
+ 'String','Apply','callback',@apply_run,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F
+ set(gui_erp_scalp_map.ERPscalpops,'Sizes',[20,25,25,25 55 20 30 25 20 25 30 30]);
+ end
+
+
+
+%%**************************************************************************%%
+%%--------------------------Sub function------------------------------------%%
+%%**************************************************************************%%
+
+% %%------------------help---------------------------------------------
+ function scap_help(~,~)%% It seems that it can be ignored
+ web('https://github.com/lucklab/erplab/wiki/Topographic-Mapping','-browser');
+ end
+
+
+%%-------------------Input bin number---------------------------------------
+ function scalp_bin_edit(Source,~)
+ binNums = str2num(Source.String);
+ [chk, msgboxText] = f_ERP_chckbinandchan(observe_ERPDAT.ERP, binNums, [],1);
+
+ if chk(1)
+ beep;
+ msgboxText = ['Plot Scalp Maps>Bins-',msgboxText];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+
+ gui_erp_scalp_map.bin_plot_edit.String = '';
+ return;
+ end
+ end
+
+%%---------------------bin options---------------------------------
+ function scalp_bin_op(~,~)
+
+ ERP_CURRENT = evalin('base','ERP');
+ for Numofbin = 1:length(ERP_CURRENT.bindescr)
+ listb{Numofbin} = char(strcat(num2str(Numofbin),'.',ERP_CURRENT.bindescr{Numofbin}));
+ end
+ try
+ indxlistb = 1:ERP_CURRENT.nbin;
+ catch
+ return;
+ end
+
+ titlename = 'Select Bin(s):';
+ %----------------judge the number of latency/latencies--------
+ if ~isempty(listb)
+ bin_label_select = browsechanbinGUI(listb, indxlistb, titlename);
+ if ~isempty(bin_label_select)
+ gui_erp_scalp_map.bin_plot_edit.String=num2str(vect2colon(bin_label_select,'Sort', 'on'));
+ else
+ disp('User selected Cancel');
+ return
+ end
+ else
+ msgboxText = ['Plot Scalp Maps>Bins>Browse-No bin information was found',];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end%Program end: Judge the number of latency/latencies
+ S_ws= estudioworkingmemory('geterpvalues');
+ if isempty(S_ws)
+ return;
+ end
+
+ S_ws.binArray = bin_label_select;
+ estudioworkingmemory('geterpvalues',S_ws);clear S_ws;
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ end
+
+
+%%----------------------Define time window (two latencies)-----------------
+ function scalp_latency_plot(Source,~)
+ Latecny_scale = str2num(Source.String);
+ ERP_times = observe_ERPDAT.ERP.times;
+ if isempty(Latecny_scale)
+ beep;
+ msgboxText = ['Plot Scalp Maps>latency-No latency was defined',];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+
+ latency = Latecny_scale;
+ if length(latency)~=2
+ beep;
+ msgboxText = ['Plot Scalp Maps>Latency-Latency needs two values',];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ elseif length(latency)==2
+ if latency(1)>=latency(2)
+ beep;
+ msgboxText = ['Plot Scalp Maps>Latency-The left edge should be smaller than the seocnd one'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if latency(1)< ERP_times(1)
+ beep;
+ msgboxText = ['Plot Scalp Maps>Latency-The left edge should be larger than the seocnd one',32, num2str(ERP_times(1)),'ms'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if latency(2)> ERP_times(end)
+ beep;
+ msgboxText = ['Plot Scalp Maps>Latency-The right edge should be smaller than the seocnd one',32, num2str(ERP_times(end)),'ms'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if latency(1)> ERP_times(end)
+ beep;
+ msgboxText = ['Plot Scalp Maps>Latency-The left edge should be smaller than the seocnd one',32, num2str(ERP_times(end)),'ms'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ end
+ end
+
+
+
+
+%%-----------------Dispaly topography with 2D------------------------------
+ function map_type_2d(~,~)
+ gui_erp_scalp_map.map_type_2d.Value=1;
+ gui_erp_scalp_map.map_type_3d.Value=0;
+ set(gui_erp_scalp_map.map_type_2d_type,'Enable','on','Value',1);
+ gui_erp_scalp_map.map_type_3d_spl.Enable = 'off';
+ gui_erp_scalp_map.map_extras_view_ops.Enable = 'off';
+ gui_erp_scalp_map.map_extras_view_ops.String = '+X';
+ gui_erp_scalp_map.map_extras_view_ops.Value =1;
+ gui_erp_scalp_map.map_extras_view_location.String = num2str([-180 30]);
+ gui_erp_scalp_map.map_extras_view_location.Enable = 'off';
+ gui_erp_scalp_map.map_type_2d_type_outside.Enable = 'on';
+ end
+
+
+
+%%-----------------Dispaly topography with 3D------------------------------
+ function map_type_3d(~,~)
+ gui_erp_scalp_map.map_type_2d.Value=0;
+ gui_erp_scalp_map.map_type_3d.Value=1;
+ gui_erp_scalp_map.map_type_3d_spl.Enable = 'on';
+ morimenu = {'front', 'back', 'right', 'left', 'top',...
+ 'frontleft', 'frontright', 'backleft', 'backright',...
+ 'custom'};
+ %%for 2D
+ set(gui_erp_scalp_map.map_type_2d_type,'Enable','off');
+ set(gui_erp_scalp_map.map_type_2d_type_outside,'Enable','off','Value',0);
+ %%for 3D
+ set(gui_erp_scalp_map.map_extras_view_ops,'String', morimenu,'Enable','on','Value',1);
+ gui_erp_scalp_map.map_extras_view_location.String = num2str([-180 30]);
+ gui_erp_scalp_map.map_extras_view_location.Enable = 'off';
+ end
+
+
+%%---------------------Spline setting for 3D-------------------------------
+ function map_type_3d_spl(~,~)
+ pathName_def = erpworkingmemory('ERP_save_folder');
+ if isempty(pathName_def)
+ pathName_def =cd;
+ end
+ Selectederp_Index= estudioworkingmemory('selectederpstudio');
+ if isempty(Selectederp_Index)%%Check indexs of the selected ERPsets
+ Selectederp_Index = observe_ERPDAT.CURRENTERP;
+ if isempty(Selectederp_Index)
+ msgboxText = 'No ERPset was imported!!!';
+ title = 'EStudio: f_ERP_binoperation_GUI error.';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ else
+ [chk, msgboxText] = f_ERP_chckerpindex(observe_ERPDAT.ALLERP, Selectederp_Index);
+ if chk==1
+ Selectederp_Index = observe_ERPDAT.CURRENTERP;
+ if isempty(Selectederp_Index)
+ msgboxText = 'No ERPset was imported!!!';
+ title = 'EStudio: f_ERP_binoperation_GUI error.';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+ end
+
+ %%Send message to Message panel
+ erpworkingmemory('f_ERP_proces_messg','Plot Scalp Maps');
+ observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started.
+
+
+ Selectederp_Index_save = [];
+ count_scalp = 0;
+ try
+ erpworkingmemory('f_ERP_proces_messg','Plot Scalp Maps > 3D > Spline');
+ observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started.
+ ALLERPCOM = evalin('base','ALLERPCOM');
+ for Numofselectederp = 1:length(Selectederp_Index)
+ ERP = observe_ERPDAT.ALLERP(Selectederp_Index(Numofselectederp));
+ ERP.filepath = pathName_def;
+
+ try
+ splnfile = ERP.splinefile;
+ catch
+ splnfile = '';
+ end
+ if ~isempty(splnfile)
+ [pathstr, file_name, ext] = fileparts(splnfile);
+ splnfile = fullfile(pathName_def,[file_name,ext]);
+ end
+
+ %% open splinefilegui
+ splineinfo = splinefileGUI({splnfile},ERP);
+ if isempty(splineinfo)
+ disp('User selected Cancel');
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Process_messg =3;%%
+ return
+ end
+
+ splinefile = splineinfo.path;
+
+ if isempty(splinefile)
+ msgboxText = 'You must specify a name for the spline file.';
+ title = 'EStudio: Plot Scalp Maps inputs';
+ errorfound(msgboxText, title);
+ return
+ end
+ Save_file_label =0;
+ if splineinfo.save
+ if isempty(ERP.splinefile)
+ ERP.splinefile = splinefile;
+ % ERP = pop_savemyerp(ERP, 'gui', 'erplab', 'History', 'off');
+ else
+ question = ['This ERPset already has spline file info.\n'...
+ 'Would you like to replace it?'];
+ title_msg = 'EStudio: spline file';
+ button = askquest(sprintf(question), title_msg);
+
+ if ~strcmpi(button,'yes')
+ disp('User selected Cancel')
+ return
+ else
+ ERP.splinefile = splinefile;
+ end
+ end
+
+ Answer = f_ERP_save_single_file(strcat(ERP.erpname,'_scalspline'),ERP.filename,Selectederp_Index(Numofselectederp));
+ if isempty(Answer)
+ beep;
+ disp('User selectd cancal');
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Process_messg =3;%%
+ return;
+ end
+
+ if ~isempty(Answer)
+ ERPName = Answer{1};
+ if ~isempty(ERPName)
+ ERP.erpname = ERPName;
+ end
+ fileName_full = Answer{2};
+ if isempty(fileName_full)
+ ERP.filename = ERP.erpname;
+ Save_file_label =0;
+ elseif ~isempty(fileName_full)
+ [pathstr, file_name, ext] = fileparts(fileName_full);
+ ext = '.erp';
+ if strcmp(pathstr,'')
+ pathstr = cd;
+ end
+ ERP.filename = [file_name,ext];
+ ERP.filepath = pathstr;
+ Save_file_label =1;
+ end
+
+ end
+ observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP;
+ count_scalp = count_scalp+1;%%Record the new data;
+ Selectederp_Index_save(count_scalp) = length(observe_ERPDAT.ALLERP);
+ splineinfo.save = 0;
+ observe_ERPDAT.ERP = ERP;
+ else
+ ERP.splinefile = splinefile;
+ observe_ERPDAT.ALLERP(Selectederp_Index(Numofselectederp)) = ERP;
+ observe_ERPDAT.ERP = ERP;
+ end
+
+
+ if Save_file_label==1
+ [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath);
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ assignin('base','ERPCOM',ERPCOM);
+ end
+ end%%end for ERPset loop
+
+ if ~isempty(Selectederp_Index_save)
+ try
+ Selected_ERP_afd = Selectederp_Index_save;
+ observe_ERPDAT.CURRENTERP = Selectederp_Index_save(1);
+ catch
+ Selected_ERP_afd = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ end
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ estudioworkingmemory('selectederpstudio',Selected_ERP_afd);
+ end
+
+ assignin('base','ALLERPCOM',ALLERPCOM);
+ erpworkingmemory('f_ERP_bin_opt',1);
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Process_messg =2;
+ return;
+ catch
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ Selected_ERP_afd =observe_ERPDAT.CURRENTERP;
+ estudioworkingmemory('selectederpstudio',Selected_ERP_afd);
+ erpworkingmemory('f_ERP_bin_opt',1);
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Process_messg =3;%%
+ return;
+ end%%end for try
+
+
+ end
+
+%%------------------------------Color bar scale: Max-min----------------------------
+ function bar_scale_max_min(~,~)
+ gui_erp_scalp_map.max_min.Value = 1;
+ gui_erp_scalp_map.custom_option.Value = 0;
+ gui_erp_scalp_map.abs_max.Value = 0;
+ gui_erp_scalp_map.bar_scale_custom_option_edit.Enable = 'off';
+ end
+
+
+%%------------------------------Color bar scale: abs max----------------------------
+ function bar_scale_abs_max(~,~)
+ gui_erp_scalp_map.max_min.Value = 0;
+ gui_erp_scalp_map.custom_option.Value = 0;
+ gui_erp_scalp_map.abs_max.Value = 1;
+ gui_erp_scalp_map.bar_scale_custom_option_edit.Enable = 'off';
+ end
+
+
+%%------------------------------Color bar scale: custom----------------------------
+ function bar_scale_custom_opt(~,~)
+ gui_erp_scalp_map.max_min.Value = 0;
+ gui_erp_scalp_map.custom_option.Value = 1;
+ gui_erp_scalp_map.abs_max.Value = 0;
+ gui_erp_scalp_map.bar_scale_custom_option_edit.Enable = 'on';
+ end
+%%-------------------Bar scale custom edit---------------------------------
+ function bar_scale_custom_edit(Source,~)
+
+
+ end
+
+
+
+
+%%---------------location selection----------------------------------------
+ function map_extras_view_ops(Source,~)
+
+ if gui_erp_scalp_map.map_type_3d.Value%%%If 3D
+ pos = Source.Value;
+ lview = Source.String;
+ strv = lview{pos};
+ if strcmpi(strv, 'custom')
+ set(gui_erp_scalp_map.map_extras_view_location, 'Enable', 'on')
+ else
+ switch strv
+ case {'front','f'}
+ mview = [-180,30];
+ case {'back','b'}
+ mview = [0,30];
+ case {'left','l'}
+ mview = [-90,30];
+ case {'right','r'}
+ mview = [90,30];
+ case {'frontright','fr'}
+ mview = [135,30];
+ case {'backright','br'}
+ mview = [45,30];
+ case {'frontleft','fl'}
+ mview = [-135,30];
+ case {'backleft','bl'}
+ mview = [-45,30];
+ case 'top'
+ mview = [0,90];
+ otherwise
+ mview = [];
+ end
+ set(gui_erp_scalp_map.map_extras_view_location, 'String', vect2colon(mview, 'Delimiter', 'off'))
+ set(gui_erp_scalp_map.map_extras_view_location, 'Enable', 'off')
+ end
+
+ end
+ end
+
+%%---------------------Setting for advanced---------------------------------
+ function apply_advanced(~,~)
+
+ is2Dmap = gui_erp_scalp_map.map_type_2d.Value;
+
+ pscale_legend = {1,1,1,1,0,'on','off',0,is2Dmap};
+ Latecny_scale = str2num(gui_erp_scalp_map.latency_plot_edit.String);
+ ERP_times = observe_ERPDAT.ERP.times;
+ if isempty(Latecny_scale)
+ beep;
+ msgboxText = ['Plot Scalp Maps - No latency was defined'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ latency = Latecny_scale;
+ if length(latency)~=2
+ beep;
+ msgboxText = ['Plot Scalp Maps - Latency needs two values'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ elseif length(latency)==2
+ if latency(1)>=latency(2)
+ beep;
+ msgboxText = ['Plot Scalp Maps - Left edge of Latency should be smaller than the seocnd one'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if latency(1)< ERP_times(1)
+ beep;
+ msgboxText = ['Plot Scalp Maps - Left edge of Latency should be larger than',32, num2str(ERP_times(1)),'ms'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if latency(2)> ERP_times(end)
+ beep;
+ msgboxText = ['Plot Scalp Maps - Right edge of Latency should be smaller than',32, num2str(ERP_times(end)),'ms'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if latency(1)> ERP_times(end)
+ beep;
+ msgboxText = ['Plot Scalp Maps - Left edge of Latency should be smaller than',32, num2str(ERP_times(end)),'ms'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+
+ pagif_legend = {0,[],'',latency};
+ Answer = f_scalplotadvanceGUI(pscale_legend,pagif_legend);
+ if isempty(Answer)
+ beep;
+ disp('User selected cancel.');
+ return;
+ end
+ %%{binnum, bindesc, type, latency, electrodes, elestyle, elec3D, ismaxim, 2Dvalue}
+ %%parameters for agif
+ pscale_legend = Answer{1};
+ pscalp_plegend.binnum = pscale_legend{1};
+ pscalp_plegend.bindesc = pscale_legend{2};
+ pscalp_plegend.type = pscale_legend{3};
+ pscalp_plegend.latency = pscale_legend{4};
+ pscalp_plegend.electrodes = pscale_legend{5};
+ pscalp_plegend.elestyle = pscale_legend{6};
+ pscalp_plegend.elec3D = pscale_legend{7};
+ pscalp_plegend.colorbar = gui_erp_scalp_map.map_extras_cmapb_disp.Value;
+ pscalp_plegend.colormap = gui_erp_scalp_map.map_extras_cmap_ops.Value;
+ pscalp_plegend.maximize = pscale_legend{8};
+ %%parameters for agif
+ pagif = Answer{2};
+ pscalp_agif.value = pagif{1};
+ pscalp_agif.fps = pagif{2};
+ pscalp_agif.fname = pagif{4};
+ %%Save parameters
+ estudioworkingmemory('pscalp_plegend', pscalp_plegend);
+ estudioworkingmemory('pscalp_agif', pscalp_agif);
+ %%-------------------Plotting scalp mapping-----------------------
+ %%Send message to Message panel
+ erpworkingmemory('f_ERP_proces_messg','Plot Scalp Maps');
+ observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started.
+
+
+ pathName_def = erpworkingmemory('ERP_save_folder');
+ if isempty(pathName_def)
+ pathName_def =cd;
+ end
+
+ Selectederp_Index= estudioworkingmemory('selectederpstudio');
+ if isempty(Selectederp_Index)
+ Selectederp_Index = observe_ERPDAT.CURRENTERP;
+
+ if isempty(Selectederp_Index)
+ beep;
+ msgboxText = ['Plot Scalp Maps - No ERPset was selected'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+
+
+ plegend = estudioworkingmemory('pscalp_plegend');
+ if isempty(plegend)
+ plegend.binnum = 1;
+ plegend.bindesc = 1;
+ plegend.type = 1;
+ plegend.latency = 1;
+ plegend.electrodes = 0;
+ plegend.elestyle = 'on';
+ plegend.elec3D = 'off';
+ plegend.colorbar = gui_erp_scalp_map.map_extras_cmapb_disp.Value;
+ plegend.colormap = gui_erp_scalp_map.map_extras_cmap_ops.Value;
+ plegend.maximize = 0;
+ estudioworkingmemory('pscalp_plegend',plegend);
+ end
+
+ agif = estudioworkingmemory('pscalp_agif');
+
+ if isempty(agif)
+ agif.value =0;
+ agif.fps =[];
+ agif.fname ='';
+ estudioworkingmemory('pscalp_agif',agif);
+ end
+
+ binArray = str2num(gui_erp_scalp_map.bin_plot_edit.String);
+ [chk, msgboxText] = f_ERP_chckbinandchan(observe_ERPDAT.ERP, binArray, [],1);
+ if chk(1)
+ beep;
+ msgboxText = ['Plot Scalp Maps -',msgboxText];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ latencyArray = str2num(gui_erp_scalp_map.latency_plot_edit.String);
+ ERP_times = observe_ERPDAT.ERP.times;
+ if isempty(latencyArray)
+ beep;
+ msgboxText = ['Plot Scalp Maps - No latency was defined'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if length(latencyArray)~=2
+ beep;
+ msgboxText = ['Plot Scalp Maps - Latency needs two values'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ elseif length(latencyArray)==2
+ if latencyArray(1)>=latencyArray(2)
+ beep;
+ msgboxText = ['Plot Scalp Maps - The left edge of latency should be smaller than the seocnd one'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+
+ end
+
+ if latencyArray(1)< ERP_times(1)
+ beep;
+ msgboxText = ['Plot Scalp Maps - The left edge of latency should be larger than',32, num2str(ERP_times(1)),'ms'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if latencyArray(2)> ERP_times(end)
+ beep;
+ msgboxText = ['Plot Scalp Maps - The right edge of latency should be smaller than',32, num2str(ERP_times(end)),'ms'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if latencyArray(1)> ERP_times(end)
+ beep;
+ msgboxText = ['Plot Scalp Maps - The left edge of latency should be smaller than',32, num2str(ERP_times(end)),'ms'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+ measurestr = 'mean';
+ baseline = 'none';
+ if gui_erp_scalp_map.max_min.Value
+ maplimit = 'maxmin';
+ elseif gui_erp_scalp_map.abs_max.Value
+ maplimit = 'absmax';
+ elseif gui_erp_scalp_map.custom_option.Value
+ cusca = str2num(gui_erp_scalp_map.bar_scale_custom_option_edit.String);
+ if isempty(cusca)
+ beep;
+ msgboxText = ['Plot Scalp Maps - No value was defined for "Color Bar Scale"'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ else
+ ncusca = length(cusca);
+ if ncusca == 2
+ if cusca(1)=latencyArray(2)
+ beep;
+ msgboxText = ['Plot Scalp Maps - The left edge of latency should be smaller than the right one'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if latencyArray(1)< ERP_times(1)
+ beep;
+ msgboxText = ['Plot Scalp Maps - The left edge of latency should be larger than',32, num2str(ERP_times(1)),'ms'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if latencyArray(2)> ERP_times(end)
+ beep;
+ msgboxText = ['Plot Scalp Maps - The left edge of latency should be smaller than',32, num2str(ERP_times(end)),'ms'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+
+ if latencyArray(1)> ERP_times(end)
+ beep;
+ msgboxText = ['Plot Scalp Maps - The left edge of latency should be smaller than',32, num2str(ERP_times(end)),'ms'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+
+
+
+ measurestr = 'mean';
+ baseline = 'none';
+ if gui_erp_scalp_map.max_min.Value
+ maplimit = 'maxmin';
+ elseif gui_erp_scalp_map.abs_max.Value
+ maplimit = 'absmax';
+ elseif gui_erp_scalp_map.custom_option.Value
+ cusca = str2num(gui_erp_scalp_map.bar_scale_custom_option_edit.String);
+ if isempty(cusca)
+ beep;
+ msgboxText = ['Plot Scalp Maps - No value was defined for "Color Bar Scale"'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ else
+ ncusca = length(cusca);
+ if ncusca == 2
+ if cusca(1)length(observe_ERPDAT.ALLERP)
+ SelectedIndex =1;
+ end
+
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedIndex);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ S_IN = S_erpbinchan.geterpplot;
+
+
+end
+
+S_erpplot = S_IN;
+
+plotops_erp = struct();
+gui_erp_plot = struct;
+
+%-----------------------------Name the title----------------------------------------------
+% global ERP_plotset_box;
+[version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+
+if nargin == 0
+ fig = figure(); % Parent figure
+ ERP_plotset_box = uiextras.BoxPanel('Parent', fig, 'Title', 'Plot Setting', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel
+elseif nargin == 1
+ ERP_plotset_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Plot Setting', 'Padding', 5,'BackgroundColor',ColorB_def);
+else
+ ERP_plotset_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Plot Setting', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def);
+end
+
+%-----------------------------Draw the panel-------------------------------------
+try
+ FonsizeDefault = varargin{2};
+catch
+ FonsizeDefault = [];
+end
+if isempty(FonsizeDefault)
+ FonsizeDefault = f_get_default_fontsize();
+end
+drawui_erpplot(FonsizeDefault);
+varargout{1} = ERP_plotset_box;
+
+ function drawui_erpplot(FonsizeDefault)
+
+ estudioworkingmemory('erp_plot_set',0);
+ estudioworkingmemory('erp_xtickstep',0);
+ %%--------------------x and y axes setting-------------------------
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ Select_index = S_binchan.Select_index;
+ gui_erp_plot.plotop = uiextras.VBox('Parent',ERP_plotset_box, 'Spacing',1,'BackgroundColor',ColorB_def);
+
+ % set(gui_erp_plot.time_sel, 'Sizes', [-1 -1 -1 -1 -1]);
+ uicontrol('Style','text','Parent', gui_erp_plot.plotop,'String','Time Range:','FontWeight','bold','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def,'BackgroundColor',ColorB_def); % 1B
+
+ gui_erp_plot.ticks = uiextras.HBox('Parent',gui_erp_plot.plotop,'Spacing',1,'BackgroundColor',ColorB_def);
+ plotops_erp.timet_auto = uicontrol('Style','checkbox','Parent', gui_erp_plot.ticks,'String','Auto','callback',@timet_auto,'Value',1,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 2B
+ uicontrol('Style','text','Parent', gui_erp_plot.ticks,'String','Low','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ plotops_erp.timet_low = uicontrol('Style', 'edit','Parent',gui_erp_plot.ticks,...
+ 'String',num2str(S_erpplot.timet_low(Select_index)),'callback',@low_ticks_change,'Enable','off','FontSize',FonsizeDefault);
+ uicontrol('Style','text','Parent', gui_erp_plot.ticks,'String','High','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ plotops_erp.timet_high = uicontrol('Style', 'edit','Parent',gui_erp_plot.ticks,'String',num2str(S_erpplot.timet_high(Select_index)),...
+ 'callback',@high_ticks_change,'Enable','off','FontSize',FonsizeDefault);
+ uicontrol('Style','text','Parent', gui_erp_plot.ticks,'String','Step','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ plotops_erp.timet_step = uicontrol('Style', 'edit','Parent',gui_erp_plot.ticks,'String',num2str(S_erpplot.timet_step(Select_index)),...
+ 'callback',@ticks_step_change,'Enable','off','FontSize',FonsizeDefault);
+
+ set(gui_erp_plot.ticks, 'Sizes', [60 -1 -1 -1 -1 -1 -1]);
+
+ uicontrol('Style','text','Parent', gui_erp_plot.plotop,'String','Y Scale:','FontWeight','bold','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ gui_erp_plot.yscale = uiextras.HBox('Parent',gui_erp_plot.plotop,'Spacing',1,'BackgroundColor',ColorB_def);
+ plotops_erp.yscale_auto = uicontrol('Style','checkbox','Parent',gui_erp_plot.yscale,'String','Auto',...
+ 'callback',@yscale_auto,'Value',1,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ tooltiptext = sprintf('Tick Length:\nSize of Y Ticks');
+ uicontrol('Style','text','Parent',gui_erp_plot.yscale,'String','Ticks','TooltipString',tooltiptext,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ plotops_erp.yscale_change = uicontrol('Style','edit','Parent',gui_erp_plot.yscale,...
+ 'String',S_erpplot.yscale(Select_index),'callback',@yscale_change,'Enable','off','FontSize',FonsizeDefault);
+ tooltiptext = sprintf('Minimum Vertical Spacing:\nSmallest possible distance in inches between zero lines before plots go off the page.');
+ uicontrol('Style','text','Parent',gui_erp_plot.yscale,'String','Spacing','TooltipString',tooltiptext,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ plotops_erp.min_vspacing = uicontrol('Style','edit','Parent',gui_erp_plot.yscale,'String',S_erpplot.min_vspacing(Select_index),'callback',@min_vspacing,'Enable','off','FontSize',FonsizeDefault);
+ tooltiptext = sprintf('Fill Screen:\nDynamically expand plots to fill screen.');
+ plotops_erp.fill_screen = uicontrol('Style','checkbox','Parent',gui_erp_plot.yscale,'String','Fill','callback',@fill_screen,...
+ 'TooltipString',tooltiptext,'Value',S_erpplot.fill(Select_index),'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ set(gui_erp_plot.yscale, 'Sizes', [50 45 35 50 35 60]);
+
+
+ gui_erp_plot.plot_column = uiextras.HBox('Parent',gui_erp_plot.plotop,'Spacing',1,'BackgroundColor',ColorB_def,'BackgroundColor',ColorB_def);
+
+ uicontrol('Style','text','Parent', gui_erp_plot.plot_column,'String','Number of columns:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 1E
+
+ ColumnNum = estudioworkingmemory('EStudioColumnNum');
+ if isempty(ColumnNum) || numel(ColumnNum)~=1
+ ColumnNum =1;
+ end
+ plotops_erp.columns = uicontrol('Style','edit','Parent', gui_erp_plot.plot_column,...
+ 'String',num2str(ColumnNum),'callback',@onElecNbox,'FontSize',FonsizeDefault); % 2E Plot_column
+ set(gui_erp_plot.plot_column, 'Sizes', [150 -1]);
+
+
+ gui_erp_plot.polarity_waveform = uiextras.HBox('Parent',gui_erp_plot.plotop,'Spacing',1,'BackgroundColor',ColorB_def);
+
+ uicontrol('Style','text','Parent', gui_erp_plot.polarity_waveform,'String','Polarity:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 1F
+
+ %% second column:
+ plotops_erp.positive_up = uicontrol('Style','radiobutton','Parent',gui_erp_plot.polarity_waveform,'String','Positive Up','callback',@polarity_up,'Value',1,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 2F
+ plotops_erp.negative_up = uicontrol('Style','radiobutton','Parent', gui_erp_plot.polarity_waveform,'String','Negative Up','callback',@polarity_down,'Value',0,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 2F
+
+ set(gui_erp_plot.polarity_waveform, 'Sizes',[60 -1 -1]);
+
+ gui_erp_plot.bin_chan = uiextras.HBox('Parent',gui_erp_plot.plotop,'Spacing',1,'BackgroundColor',ColorB_def);
+
+ gui_erp_plot.pagesel = uicontrol('Parent', gui_erp_plot.bin_chan, 'Style', 'popupmenu','String',...
+ {'CHANNELS with BINS overlay','BINS with CHANNELS overlay'},'callback',@pageviewchanged,'FontSize',FonsizeDefault);
+
+
+ gui_erp_plot.reset_apply = uiextras.HBox('Parent',gui_erp_plot.plotop,'Spacing',1,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_plot.reset_apply); % 1A
+ plotops_erp.plot_reset = uicontrol('Style', 'pushbutton','Parent',gui_erp_plot.reset_apply,...
+ 'String','Reset','callback',@plot_erp_reset,'FontSize',FonsizeDefault);
+ uiextras.Empty('Parent', gui_erp_plot.reset_apply); % 1A
+ plotops_erp.plot_apply = uicontrol('Style', 'pushbutton','Parent',gui_erp_plot.reset_apply,...
+ 'String','Apply','callback',@plot_erp_apply,'FontSize',FonsizeDefault);
+ uiextras.Empty('Parent', gui_erp_plot.reset_apply); % 1A
+ set(gui_erp_plot.reset_apply, 'Sizes',[10 -1 30 -1 10]);
+
+ set(gui_erp_plot.plotop, 'Sizes', [20 25 20 25 25 25 20 30]);
+
+ end
+
+
+
+%%**************************************************************************%%
+%%--------------------------Sub function------------------------------------%%
+%%**************************************************************************%%
+
+%---------------------------------Auto time ticks-------------------------------*
+ function timet_auto( src, ~ )
+ estudioworkingmemory('erp_xtickstep',0);
+ S_selectedERP = estudioworkingmemory('selectederpstudio');
+ if isempty(S_selectedERP)
+ S_selectedERP = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ Select_index = S_binchan.Select_index;
+
+ if src.Value == 1
+ plotops_erp.timet_low.Enable = 'off';
+ plotops_erp.timet_high.Enable = 'off';
+ plotops_erp.timet_step.Enable = 'off';
+ else
+ plotops_erp.timet_low.Enable = 'on';
+ plotops_erp.timet_high.Enable = 'on';
+ plotops_erp.timet_step.Enable = 'on';
+ end
+ plotops_erp.timet_low.String = num2str(floor(observe_ERPDAT.ALLERP(S_selectedERP(Select_index)).times(1)/5)*5);
+ plotops_erp.timet_high.String = num2str(ceil(observe_ERPDAT.ALLERP(S_selectedERP(Select_index)).times(end)/5)*5);
+
+
+ Min_time=floor(observe_ERPDAT.ALLERP(S_selectedERP(Select_index)).times(1)/5)*5;
+ Max_time = ceil(observe_ERPDAT.ALLERP(S_selectedERP(Select_index)).times(end)/5)*5;
+
+ [def xstep]= default_time_ticks_studio(observe_ERPDAT.ERP, [Min_time,Max_time]);
+ plotops_erp.timet_step.String = num2str(xstep);
+
+ checked_ERPset_Index = S_binchan.checked_ERPset_Index;
+
+
+ if any(checked_ERPset_Index(5))
+ S_erpplot.timet_low(Select_index) = floor(observe_ERPDAT.ALLERP(S_selectedERP(Select_index)).times(1)/5)*5;
+ else
+ S_erpplot.timet_low(1:end) = floor(observe_ERPDAT.ALLERP(S_selectedERP(Select_index)).times(1)/5)*5;
+ end
+
+ if any(checked_ERPset_Index(6))
+ S_erpplot.timet_high(Select_index) = ceil(observe_ERPDAT.ALLERP(S_selectedERP(Select_index)).times(end)/5)*5;
+ else
+ S_erpplot.timet_high(1:end) = ceil(observe_ERPDAT.ALLERP(S_selectedERP(Select_index)).times(end)/5)*5;
+ end
+
+ if any(checked_ERPset_Index(6)) || any(checked_ERPset_Index(5))
+ S_erpplot.timet_step(Select_index) = xstep;
+ else
+ S_erpplot.timet_step(1:end) = xstep;
+ end
+ end
+
+
+%%--------------------------Min. interval of time ticks---------------------
+ function low_ticks_change( src, ~ )
+
+ S_selectedERP = estudioworkingmemory('selectederpstudio');
+ if isempty(S_selectedERP)
+ S_selectedERP = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ Select_index = S_binchan.Select_index;
+
+ xtixlk_min = str2num(src.String);
+ xtixlk_max = str2num(plotops_erp.timet_high.String);
+ if isempty(xtixlk_min)
+ src.String = num2str(S_erpplot.timet_low(Select_index));
+ beep;
+ msgboxText = ['Plot Setting> Time range- Input of left edge must be a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+
+ if numel(xtixlk_min)>1
+ src.String = num2str(S_erpplot.timet_low(Select_index));
+ msgboxText = ['Plot Setting> Time range- nput of left edge must be a single numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+
+ return;
+ end
+
+
+ checked_ERPset_Index = S_binchan.checked_ERPset_Index;
+
+ if xtixlk_min < S_erpplot.timet_high(Select_index)
+ S_erpplot.timet_low(Select_index)=xtixlk_min;
+ if any(checked_ERPset_Index(5))
+ S_erpplot.timet_low(Select_index)=xtixlk_min;
+ else
+ S_erpplot.timet_low(1:end)=xtixlk_min;
+ end
+
+ [def xstep]= default_time_ticks_studio(observe_ERPDAT.ERP, [xtixlk_min,xtixlk_max]);
+ plotops_erp.timet_step.String = num2str(xstep);
+ S_erpplot.timet_step(1:end) = xstep;
+ else
+ src.String = S_erpplot.min(Select_index);
+
+ msgboxText = ['Plot Setting> Time range- left range must be lower than high tick'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if S_erpplot.timet_step(Select_index) > S_erpplot.timet_high(Select_index)- S_erpplot.timet_low(Select_index)
+ plotops_erp.timet_step.String = num2str(S_erpplot.timet_step(Select_index));
+
+ msgboxText = ['Plot Setting> Time range- Step must be within the time range'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ end
+
+
+
+%%----------------------high interval of time ticks--------------------------------*
+ function high_ticks_change( src, ~ )
+ S_selectedERP = estudioworkingmemory('selectederpstudio');
+ if isempty(S_selectedERP)
+ S_selectedERP = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ Select_index = S_binchan.Select_index;
+ xtixlk_min = str2num(plotops_erp.timet_low.String);
+ xtixlk_max = str2num(src.String);
+
+ if isempty(xtixlk_max)
+ src.String = num2str(S_erpplot.timet_high(Select_index));
+ beep;
+ msgboxText = ['Plot Setting> Y Scale- Input of ticks edge must be a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+
+ return;
+ end
+
+ if numel(xtixlk_max)>1
+ src.String = num2str(S_erpplot.timet_high(Select_index));
+ beep;
+ msgboxText = ['Plot Setting> Y Scale- Input of ticks edge must be a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+
+ return;
+ end
+
+
+ checked_ERPset_Index = S_binchan.checked_ERPset_Index;
+
+ if xtixlk_max > xtixlk_min
+
+ if any(checked_ERPset_Index(6))
+ S_erpplot.timet_high(Select_index) = xtixlk_max;
+ else
+ S_erpplot.timet_high(1:end) = xtixlk_max;
+ end
+ [def xstep]= default_time_ticks_studio(observe_ERPDAT.ERP, [xtixlk_min,xtixlk_max]);
+ plotops_erp.timet_step.String = num2str(xstep);
+ S_erpplot.timet_step(1:end) = xstep;
+
+ else
+ src.String = num2str(S_erpplot.timet_high(Select_index));
+ beep;
+ msgboxText = ['Plot Setting> Time range- right edge must be higher than',32,num2str(xtixlk_min),'ms'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if S_erpplot.timet_step(Select_index) > S_erpplot.timet_high(Select_index) -S_erpplot.timet_low(Select_index)
+ beep;
+ plotops_erp.timet_step.String = num2str(S_erpplot.timet_step(Select_index));
+ msgboxText = ['Plot Setting> Time range- Step must be within the time range'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+
+
+%%----------------------Step of time ticks--------------------------------*
+ function ticks_step_change( src, ~ )
+
+ tick_step = str2num(src.String);
+ S_selectedERP = estudioworkingmemory('selectederpstudio');
+ if isempty(S_selectedERP)
+ S_selectedERP = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ Select_index = S_binchan.Select_index;
+
+ if isempty(tick_step)
+ src.String = num2str(S_erpplot.timet_step(Select_index));
+ beep;
+ msgboxText = ['Plot Setting> Time range- The input of Step must be a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if numel(tick_step)>1
+ src.String = num2str(S_erpplot.timet_step(Select_index));
+ beep;
+ msgboxText = ['Plot Setting> Time range- The input of Step must be one numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if tick_step<=0 %% otherwise, a bug will be displayed
+ src.String = num2str(S_erpplot.timet_step(Select_index));
+ beep;
+ msgboxText = ['Plot Setting> Time range- Step must be a positive value'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ checked_ERPset_Index = S_binchan.checked_ERPset_Index;
+
+ if tick_step < S_erpplot.timet_high(Select_index) -S_erpplot.timet_low(Select_index)
+
+ if any(checked_ERPset_Index(5)) && any(checked_ERPset_Index(6))
+ S_erpplot.timet_step(Select_index) = tick_step;
+ else
+ S_erpplot.timet_step(1:end) = tick_step;
+ end
+ estudioworkingmemory('erp_xtickstep',1);
+
+
+ else
+ src.String = num2str(S_erpplot.timet_step(Select_index));
+ beep;
+ msgboxText = ['Plot Setting> Time range- Step must be within the time range'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ end
+
+%%---------------------------------Auto y scale---------------------------------*
+ function yscale_auto( src, ~ )
+ S_selectedERP = estudioworkingmemory('selectederpstudio');
+ if isempty(S_selectedERP)
+ S_selectedERP = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ end
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ Select_index = S_binchan.Select_index;
+
+ if src.Value == 1
+ plotops_erp.yscale_change.Enable = 'off';
+ YScale =prctile((observe_ERPDAT.ALLERP(S_selectedERP(Select_index)).bindata(:)*S_erpplot.Positive_up(Select_index)),95)*2/3;
+ if YScale>= 0&&YScale <=0.1
+ YScale = 0.1;
+ elseif YScale< 0&& YScale > -0.1
+ YScale = -0.1;
+ else
+ YScale = round(YScale);
+ end
+ plotops_erp.yscale_change.String = YScale;
+ S_erpplot.yscale(1:end) = YScale;
+
+ plotops_erp.min_vspacing.Enable = 'off';
+ plotops_erp.min_vspacing.String = 1.5;
+ S_erpplot.min_vspacing(1:end) =1.5;
+ else
+ plotops_erp.yscale_change.Enable = 'on';
+ plotops_erp.min_vspacing.Enable = 'on';
+ end
+
+ end
+
+
+%%---------------------------------y scale change---------------------------------*
+ function yscale_change(src, ~ )
+
+ clear i
+ val = 1i;
+ try
+ val = str2double(src.String);
+ catch
+ beep;
+ msgboxText = ['Plot Setting> y scale - Input of y scale must be a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if val ~= 1i
+ if val <= 0
+ beep;
+ msgboxText = ['Plot Setting> y scale - Input must be greater than zero'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ else
+ S_erpplot.yscale(1:end) = val;
+ end
+ end
+
+ end
+
+
+%%-------------------------- Y scale spacing-------------------------------
+ function min_vspacing( src, ~ )
+ clear i
+ val = 1i;
+ try
+ val = str2double(src.String);
+ catch
+ beep;
+ msgboxText = ['Plot Setting> y scale > spacing - Input of spacing must be a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ src.String = 1.5;
+ end
+ if val ~= 1i
+ if val <= 0
+ beep;
+ msgboxText = ['Plot Setting> y scale > spacing - Input of spacing must be greater than zero'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ src.String = 1.5;
+ else
+ S_erpplot.min_vspacing(1:end) = val;
+ end
+ end
+ end
+
+%%-----------------fill screen---------------------------------------------*
+ function fill_screen( src, ~ )
+ S_erpplot.fill(1:end)= src.Value;
+ end
+
+%%-----------Determing the numbrt of columns------------------------------
+ function onElecNbox(source,~)
+ Values = str2num(source.String);
+ if isempty(Values) || Values <=0
+ source.String = num2str( S_erpplot.Plot_column(1));
+ msgboxText = ['Plot Setting> Number of columns - Input for the number of columns must be greater than zero'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ S_erpplot.Plot_column(1:end) = Values;
+ end
+
+%------------------Set the polarity of waveform is up or not-------------------
+ function polarity_up(~,~)
+ source_value_up = 1;
+ plotops_erp.positive_up.Value =source_value_up;
+ plotops_erp.negative_up.Value = 0;
+ S_erpplot.Positive_up(1:end) = source_value_up;
+ end
+
+
+%------------------Set the polarity of waveform is up or not-------------------
+ function polarity_down( source, ~)
+ source_value_down = 1;
+ plotops_erp.positive_up.Value =0;
+ plotops_erp.negative_up.Value = source_value_down;
+ S_erpplot.Positive_up(1:end) = -source_value_down;
+ end
+
+%%-------------------------------------------------------------------------
+ function Count_currentERPChanged(~,~)
+ erp_plot_set_label = estudioworkingmemory('erp_plot_set');
+ if isempty(erp_plot_set_label)
+ erp_plot_set_label =1;
+ end
+ if ~erp_plot_set_label
+ S_selectedERP = estudioworkingmemory('selectederpstudio');
+ if isempty(S_selectedERP)
+ S_selectedERP = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ Select_index = S_binchan.Select_index;
+ S_erpplot = estudioworkingmemory('geterpplot');
+ plotops_erp.timet_auto.Value = 1; % 2B
+ plotops_erp.timet_low.String = num2str(S_erpplot.timet_low(Select_index));
+ plotops_erp.timet_low.Enable = 'off';
+ plotops_erp.timet_high.String = num2str(S_erpplot.timet_high(Select_index));
+ plotops_erp.timet_high.Enable = 'off';
+ try
+ plotops_erp.timet_step.String = num2str(S_erpplot.timet_step(Select_index));
+ catch
+ plotops_erp.timet_step.String = num2str(floor((S_erpplot.max(Select_index)-S_erpplot.min(Select_index))/5));
+ end
+ plotops_erp.timet_step.Enable = 'off';
+
+
+ plotops_erp.yscale_auto.Value = 1;
+
+ plotops_erp.yscale_change.String = num2str(S_erpplot.yscale(Select_index));
+ plotops_erp.yscale_change.Enable = 'off';
+ plotops_erp.min_vspacing.String = num2str(S_erpplot.min_vspacing(Select_index));
+ plotops_erp.min_vspacing.Enable = 'off';
+ plotops_erp.fill_screen.Value = S_erpplot.fill(Select_index);
+ ColumnNum = estudioworkingmemory('EStudioColumnNum');
+ if isempty(ColumnNum) || numel(ColumnNum)~=1
+ ColumnNum =1;
+ end
+
+ plotops_erp.columns.String = num2str(ColumnNum); % 2E Plot_column
+ plotops_erp.columns.Enable = 'on';
+
+ if S_erpplot.Positive_up(Select_index) == -1
+ plotops_erp.positive_up.Value =0;
+ plotops_erp.negative_up.Value = 1;
+ else
+ plotops_erp.positive_up.Value = 1;
+ plotops_erp.negative_up.Value = 0;
+ end
+
+ try
+ Bin_chan_overlay = S_binchan.bins_chans(1);
+ catch
+ Bin_chan_overlay = 0;
+ end
+
+ set(gui_erp_plot.pagesel,'Value',Bin_chan_overlay+1);
+ end
+ estudioworkingmemory('erp_plot_set',0);
+
+ %%---------------Deative the setting for the number of columns when activing ERP viewer
+ try
+ S_ws_geterpvalues = estudioworkingmemory('geterpvalues');
+ S_ws_viewer = S_ws_geterpvalues.Viewer;
+ catch
+ S_ws_viewer = 'off';
+ end
+ if strcmp(S_ws_viewer,'on')
+ plotops_erp.columns.Enable = 'off';
+ end
+
+ end
+
+
+%%----------------------Setting for bin overlay chan---------------------
+ function pageviewchanged(src,~)
+ S_selectedERP = estudioworkingmemory('selectederpstudio');
+ if isempty(S_selectedERP)
+ S_selectedERP = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ estudioworkingmemory('selectederpstudio',S_selectedERP);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ Select_index = S_binchan.Select_index;
+
+ if src.Value == 1
+ if S_binchan.checked_ERPset_Index(1) ==1 || S_binchan.checked_ERPset_Index(2) ==2
+ S_binchan.bins_chans(Select_index) = 0;
+ else
+ S_binchan.bins_chans(1:end) = 0;
+ end
+ else
+ if S_binchan.checked_ERPset_Index(1) ==1 || S_binchan.checked_ERPset_Index(2) ==2
+ S_binchan.bins_chans(Select_index) = 1;
+ else
+ S_binchan.bins_chans(1:end) = 1;
+ end
+ end
+
+ estudioworkingmemory('geterpbinchan',S_binchan);
+ end
+
+
+
+
+%%--------------Reset the parameters for plotting panel--------------------
+ function plot_erp_reset(~,~)
+ erpworkingmemory('f_ERP_proces_messg','Plot Setting>Reset');
+ observe_ERPDAT.Process_messg =1;
+
+ S_selectedERP = estudioworkingmemory('selectederpstudio');
+ if isempty(S_selectedERP)
+ try
+ S_selectedERP = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP);
+ estudioworkingmemory('selectederpstudio',S_selectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ catch
+ return;
+ end
+ else
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ end
+ gui_erp_plot.pagesel.Value = 1;
+
+
+ erp_plot_set_label = estudioworkingmemory('erp_plot_set');
+ if isempty(erp_plot_set_label)
+ erp_plot_set_label =1;
+ end
+ if ~erp_plot_set_label
+ S_selectedERP = estudioworkingmemory('selectederpstudio');
+ if isempty(S_selectedERP)
+ S_selectedERP = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ Select_index = S_binchan.Select_index;
+ S_erpplot = estudioworkingmemory('geterpplot');
+ plotops_erp.timet_auto.Value = 1; % 2B
+ plotops_erp.timet_low.String = num2str(S_erpplot.timet_low(Select_index));
+ plotops_erp.timet_low.Enable = 'off';
+ plotops_erp.timet_high.String = num2str(S_erpplot.timet_high(Select_index));
+ plotops_erp.timet_high.Enable = 'off';
+ try
+ plotops_erp.timet_step.String = num2str(S_erpplot.timet_step(Select_index));
+ catch
+ plotops_erp.timet_step.String = num2str(floor((S_erpplot.max(Select_index)-S_erpplot.min(Select_index))/5));
+ end
+ plotops_erp.timet_step.Enable = 'off';
+ plotops_erp.yscale_auto.Value = 1;
+ plotops_erp.yscale_change.String = num2str(S_erpplot.yscale(Select_index));
+ plotops_erp.yscale_change.Enable = 'off';
+ plotops_erp.min_vspacing.String = num2str(S_erpplot.min_vspacing(Select_index));
+ plotops_erp.min_vspacing.Enable = 'off';
+ plotops_erp.fill_screen.Value = S_erpplot.fill(Select_index);
+ ColumnNum = estudioworkingmemory('EStudioColumnNum');
+ if isempty(ColumnNum) || numel(ColumnNum)~=1
+ ColumnNum =1;
+ end
+
+ plotops_erp.columns.String = num2str(ColumnNum); % 2E Plot_column
+ plotops_erp.columns.Enable = 'on';
+
+ if S_erpplot.Positive_up(Select_index) == -1
+ plotops_erp.positive_up.Value =0;
+ plotops_erp.negative_up.Value = 1;
+ else
+ plotops_erp.positive_up.Value = 1;
+ plotops_erp.negative_up.Value = 0;
+ end
+
+ try
+ Bin_chan_overlay = S_binchan.bins_chans(1);
+ catch
+ Bin_chan_overlay = 0;
+ end
+
+ set(gui_erp_plot.pagesel,'Value',Bin_chan_overlay+1);
+ end
+ estudioworkingmemory('erp_plot_set',0);
+
+ %%---------------Deative the setting for the number of columns when activing ERP viewer
+ try
+ S_ws_geterpvalues = estudioworkingmemory('geterpvalues');
+ S_ws_viewer = S_ws_geterpvalues.Viewer;
+ catch
+ S_ws_viewer = 'off';
+ end
+ if strcmp(S_ws_viewer,'on')
+ plotops_erp.columns.Enable = 'off';
+ end
+
+ observe_ERPDAT.Process_messg =2;
+
+ %%plot the waveforms
+ try
+ S_ws_geterpvalues = estudioworkingmemory('geterpvalues');
+ S_ws_viewer = S_ws_geterpvalues.Viewer;
+
+ moption = S_ws_geterpvalues.Measure;
+ latency = S_ws_geterpvalues.latency;
+ if strcmp(S_ws_viewer,'on')
+ if isempty(moption)
+ msgboxText = ['EStudio says: User must specify a type of measurement.'];
+ title = 'EStudio: ERP measurement tool- "Measurement type".';
+ errorfound(msgboxText, title);
+ return;
+ end
+ if ismember_bc2({moption}, {'instabl', 'areazt','areazp','areazn', 'nintegz'})
+ if length(latency)~=1
+ msgboxText = ['ERPLAB says: ' moption ' only needs 1 latency value.'];
+ title = 'EStudio: ERP measurement tool- "Measurement type".';
+ errorfound(msgboxText, title);
+ return;
+ end
+ else
+ if length(latency)~=2
+ msgboxText = ['EStudio says: ' moption ' needs 2 latency values.'];
+ title = 'EStudio: ERP measurement tool- "Measurement type".';
+ errorfound(msgboxText, title);
+ return;
+ else
+ if latency(1)>=latency(2)
+ msgboxText = ['For latency range, lower time limit must be on the left.\n'...
+ 'Additionally, lower time limit must be at least 1/samplerate seconds lesser than the higher one.'];
+ title = 'EStudio: ERP measurement tool-Measurement window';
+ errorfound(sprintf(msgboxText), title);
+ return
+ end
+ end
+ end
+ f_redrawERP_mt_viewer();
+ else
+ f_redrawERP();
+ end
+ catch
+ f_redrawERP();
+ end
+
+ end
+
+
+%------------Apply current parameters in plotting panel to the selected ERPset---------
+ function plot_erp_apply(~,~)
+ erpworkingmemory('f_ERP_proces_messg','Plot Setting>Apply');
+ observe_ERPDAT.Process_messg =1;
+
+ estudioworkingmemory('geterpplot',S_erpplot);
+ estudioworkingmemory('erp_plot_set',1);
+ ColumnNum = str2num(plotops_erp.columns.String);
+ if isempty(ColumnNum) && numel(ColumnNum)~=1
+ ColumnNum = 1;
+ end
+ estudioworkingmemory('EStudioColumnNum',ColumnNum);
+ % observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Process_messg =2;
+
+ %%plot the waveforms
+ try
+ S_ws_geterpvalues = estudioworkingmemory('geterpvalues');
+ S_ws_viewer = S_ws_geterpvalues.Viewer;
+
+ moption = S_ws_geterpvalues.Measure;
+ latency = S_ws_geterpvalues.latency;
+ if strcmp(S_ws_viewer,'on')
+ if isempty(moption)
+ msgboxText = ['EStudio says: User must specify a type of measurement.'];
+ title = 'EStudio: ERP measurement tool- "Measurement type".';
+ errorfound(msgboxText, title);
+ return;
+ end
+ if ismember_bc2({moption}, {'instabl', 'areazt','areazp','areazn', 'nintegz'})
+ if length(latency)~=1
+ msgboxText = ['ERPLAB says: ' moption ' only needs 1 latency value.'];
+ title = 'EStudio: ERP measurement tool- "Measurement type".';
+ errorfound(msgboxText, title);
+ return;
+ end
+ else
+ if length(latency)~=2
+ msgboxText = ['EStudio says: ' moption ' needs 2 latency values.'];
+ title = 'EStudio: ERP measurement tool- "Measurement type".';
+ errorfound(msgboxText, title);
+ return;
+ else
+ if latency(1)>=latency(2)
+ msgboxText = ['For latency range, lower time limit must be on the left.\n'...
+ 'Additionally, lower time limit must be at least 1/samplerate seconds lesser than the higher one.'];
+ title = 'EStudio: ERP measurement tool-Measurement window';
+ errorfound(sprintf(msgboxText), title);
+ return
+ end
+ end
+ end
+ f_redrawERP_mt_viewer();
+ else
+ f_redrawERP();
+ end
+ catch
+ f_redrawERP();
+ end
+ end
+
+end
\ No newline at end of file
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_rename_gui.fig b/studio_functions/GUIs/ERP Tab/f_ERP_rename_gui.fig
new file mode 100755
index 00000000..5dc9e8af
Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_ERP_rename_gui.fig differ
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_rename_gui.m b/studio_functions/GUIs/ERP Tab/f_ERP_rename_gui.m
new file mode 100755
index 00000000..ae76509a
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_rename_gui.m
@@ -0,0 +1,181 @@
+function varargout = f_ERP_rename_gui(varargin)
+% F_ERP_RENAME_GUI MATLAB code for f_ERP_rename_gui.fig
+% F_ERP_RENAME_GUI, by itself, creates a new F_ERP_RENAME_GUI or raises the existing
+% singleton*.
+%
+% H = F_ERP_RENAME_GUI returns the handle to a new F_ERP_RENAME_GUI or the handle to
+% the existing singleton*.
+%
+% F_ERP_RENAME_GUI('CALLBACK',hObject,eventData,handles,...) calls the local
+% function named CALLBACK in F_ERP_RENAME_GUI.M with the given input arguments.
+%
+% F_ERP_RENAME_GUI('Property','Value',...) creates a new F_ERP_RENAME_GUI or raises the
+% existing singleton*. Starting from the left, property value pairs are
+% applied to the GUI before f_ERP_rename_gui_OpeningFcn gets called. An
+% unrecognized property name or invalid value makes property application
+% stop. All inputs are passed to f_ERP_rename_gui_OpeningFcn via varargin.
+%
+% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
+% instance to run (singleton)".
+%
+% See also: GUIDE, GUIDATA, GUIHANDLES
+
+% Edit the above text to modify the response to help f_ERP_rename_gui
+
+% Last Modified by GUIDE v2.5 02-Aug-2022 16:46:06
+
+% Begin initialization code - DO NOT EDIT
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @f_ERP_rename_gui_OpeningFcn, ...
+ 'gui_OutputFcn', @f_ERP_rename_gui_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+% End initialization code - DO NOT EDIT
+
+
+% --- Executes just before f_ERP_rename_gui is made visible.
+function f_ERP_rename_gui_OpeningFcn(hObject, eventdata, handles, varargin)
+% Choose default command line output for f_ERP_rename_gui
+
+try
+ erpname = varargin{1};
+ currenterp = varargin{2};
+catch
+ erpname = '';
+ currenterp = '';
+end
+
+handles.erpnameor = erpname;
+handles.output = [];
+erpmenu = findobj('tag', 'erpsets');
+
+if ~isempty(erpmenu)
+ handles.menuerp = get(erpmenu);
+ set(handles.menuerp.Children, 'Enable','off');
+end
+
+erplab_studio_default_values;
+version = erplabstudiover;
+
+set(handles.gui_chassis,'Name', ['EStudio ' version ' - Rename current ERPset GUI'])
+set(handles.edit_erpname, 'String', erpname);
+
+if isempty(currenterp)
+ set(handles.current_erp_label,'String', ['No active erpset was found'],...
+ 'FontWeight','Bold', 'FontSize', 16);
+else
+ ERPNAME = char(strcat('ERPset # ', num2str(currenterp),': (',erpname,')'));
+ set(handles.current_erp_label,'String',ERPNAME ,...
+ 'FontWeight','Bold', 'FontSize', 16)
+end
+%
+% % Color GUI
+% %
+handles = painterplabstudio(handles);
+%
+% %
+% % Set font size
+% %
+handles = setfonterplabestudio(handles);
+
+% Update handles structure
+guidata(hObject, handles);
+
+
+% UIWAIT makes savemyerpGUI wait for user response (see UIRESUME)
+uiwait(handles.gui_chassis);
+
+
+
+
+% --- Outputs from this function are returned to the command line.
+function varargout = f_ERP_rename_gui_OutputFcn(hObject, eventdata, handles)
+
+% Get default command line output from handles structure
+% try
+% set(handles.menuerp.Children, 'Enable','on');
+% catch
+% disp('ERPset menu was not found...')
+% end
+varargout{1} = handles.output;
+delete(handles.gui_chassis);
+pause(0.1)
+
+
+
+
+% --- Executes on button press in radio_erpname.
+function radio_erpname_Callback(hObject, eventdata, handles)
+% hObject handle to radio_erpname (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Hint: get(hObject,'Value') returns toggle state of radio_erpname
+
+
+function edit_erpname_Callback(hObject, eventdata, handles)
+
+
+% --- Executes during object creation, after setting all properties.
+function edit_erpname_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+% --- Executes on button press in pushbutton_Cancel.
+function pushbutton_Cancel_Callback(hObject, eventdata, handles)
+handles.output = [];
+beep;
+disp('User selected Cancel')
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+
+% --- Executes on button press in pushbutton4_okay.
+function pushbutton4_okay_Callback(hObject, eventdata, handles)
+erpname = strtrim(get(handles.edit_erpname, 'String'));
+
+if isempty(erpname)
+ msgboxText = 'You must enter an erpname at least!';
+ title = 'EStudio: f_ERP_save_single_file empty erpname';
+ errorfound(msgboxText, title);
+ return
+end
+
+
+handles.output = {erpname};
+% Update handles structure
+guidata(hObject, handles);
+
+uiresume(handles.gui_chassis);
+
+
+
+
+% -----------------------------------------------------------------------
+function gui_chassis_CloseRequestFcn(hObject, eventdata, handles)
+
+if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting')
+ %The GUI is still in UIWAIT, us UIRESUME
+ handles.output = '';
+ %Update handles structure
+ guidata(hObject, handles);
+ uiresume(handles.gui_chassis);
+else
+ % The GUI is no longer waiting, just close it
+ delete(handles.gui_chassis);
+end
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_save_multi_file.fig b/studio_functions/GUIs/ERP Tab/f_ERP_save_multi_file.fig
new file mode 100755
index 00000000..e7351ed6
Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_ERP_save_multi_file.fig differ
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_save_multi_file.m b/studio_functions/GUIs/ERP Tab/f_ERP_save_multi_file.m
new file mode 100755
index 00000000..726cf919
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_save_multi_file.m
@@ -0,0 +1,391 @@
+function varargout = f_ERP_save_multi_file(varargin)
+% F_ERP_SAVE_MULTI_FILE MATLAB code for f_ERP_save_multi_file.fig
+% F_ERP_SAVE_MULTI_FILE, by itself, creates a new F_ERP_SAVE_MULTI_FILE or raises the existing
+% singleton*.
+%
+% H = F_ERP_SAVE_MULTI_FILE returns the handle to a new F_ERP_SAVE_MULTI_FILE or the handle to
+% the existing singleton*.
+%
+% F_ERP_SAVE_MULTI_FILE('CALLBACK',hObject,eventData,handles,...) calls the local
+% function named CALLBACK in F_ERP_SAVE_MULTI_FILE.M with the given input arguments.
+%
+% F_ERP_SAVE_MULTI_FILE('Property','Value',...) creates a new F_ERP_SAVE_MULTI_FILE or raises the
+% existing singleton*. Starting from the left, property value pairs are
+% applied to the GUI before f_ERP_save_multi_file_OpeningFcn gets called. An
+% unrecognized property name or invalid value makes property application
+% stop. All inputs are passed to f_ERP_save_multi_file_OpeningFcn via varargin.
+%
+% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
+% instance to run (singleton)".
+%
+% See also: GUIDE, GUIDATA, GUIHANDLES
+
+% Edit the above text to modify the response to help f_ERP_save_multi_file
+
+% Last Modified by GUIDE v2.5 13-Jun-2022 18:55:22
+
+% Begin initialization code - DO NOT EDIT
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @f_ERP_save_multi_file_OpeningFcn, ...
+ 'gui_OutputFcn', @f_ERP_save_multi_file_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+% End initialization code - DO NOT EDIT
+
+
+% --- Executes just before f_ERP_save_multi_file is made visible.
+function f_ERP_save_multi_file_OpeningFcn(hObject, eventdata, handles, varargin)
+% Choose default command line output for f_ERP_save_multi_file
+
+try
+ ALLERP = varargin{1};
+ Selected_ERP_label = varargin{2};
+ suffix = varargin{3};
+catch
+ suffix = '';
+ ERPLAB = [];
+ ERPLAB.erpname = 'No erpset was selected';
+ ERPLAB.filename ='No erpset was selected';
+ ERPLAB.event = [];
+ ERPLAB.chanlocs = [];
+ ERPLAB.nbchan = 0;
+ ALLERP(1) = ERPLAB;
+ Selected_ERP_label = 1;
+end
+
+% handles.erpnameor = erpname;
+handles.output = [];
+handles.suffix = suffix;
+
+handles.ALLERP = ALLERP;
+handles.Selected_ERP_label =Selected_ERP_label;
+
+erplab_studio_default_values;
+version = erplabstudiover;
+set(handles.gui_chassis,'Name', ['EStudio ' version ' - Save multiple Erpsets GUI'])
+
+
+% set(handles.checkbox1_suffix,'Value',1);
+set(handles.edit_suffix_name,'String',suffix);
+set(handles.checkbox2_save_label,'Value',0);
+
+ColumnName_table = {'ERP name','File name'};
+
+set(handles.uitable1_erpset_table,'ColumnName',cellstr(ColumnName_table));
+set(handles.uitable1_erpset_table,'RowName',cellstr(num2str(Selected_ERP_label')));
+
+
+for Numofselectederp = 1:numel(Selected_ERP_label)
+ DataString{Numofselectederp,1} = strcat(ALLERP(Selected_ERP_label(Numofselectederp)).erpname,suffix);
+ DataString{Numofselectederp,2} = '';
+end
+
+set(handles.uitable1_erpset_table,'Data',cellstr(DataString));
+set(handles.uitable1_erpset_table,'ColumnWidth',{248 248});
+set(handles.uitable1_erpset_table,'Enable','on');
+set(handles.checkbox3_filename_erpname,'Enable','off');
+
+%
+% % Color GUI
+% %
+handles = painterplabstudio(handles);
+%
+% %
+% % Set font size
+% %
+handles = setfonterplabestudio(handles);
+
+% Update handles structure
+guidata(hObject, handles);
+
+
+% UIWAIT makes savemyerpGUI wait for user response (see UIRESUME)
+uiwait(handles.gui_chassis);
+
+
+
+
+% --- Outputs from this function are returned to the command line.
+function varargout = f_ERP_save_multi_file_OutputFcn(hObject, eventdata, handles)
+
+% Get default command line output from handles structure
+try
+ varargout{1} = handles.output;
+catch
+ varargout{1} = [];
+end
+
+delete(handles.gui_chassis);
+pause(0.1)
+
+
+
+% --- Executes on button press in checkbox1_suffix.
+function checkbox1_suffix_Callback(hObject, eventdata, handles)
+ALLERP = handles.ALLERP;
+Selected_ERP_label = handles.Selected_ERP_label;
+suffix_edit = handles.edit_suffix_name.String;
+
+if isempty(suffix_edit)
+ msgboxText = 'You must enter a suffix at least!';
+ title = 'EStudio: f_ERP_save_multi_file() error';
+ errorfound(msgboxText, title);
+ return
+end
+
+
+DataString_before = handles.uitable1_erpset_table.Data;
+for Numofselectederp = 1:numel(Selected_ERP_label)
+ DataString{Numofselectederp,1} = strcat(ALLERP(Selected_ERP_label(Numofselectederp)).erpname,suffix_edit);
+ DataString{Numofselectederp,2} = DataString_before{Numofselectederp,2};
+end
+set(handles.uitable1_erpset_table,'Data',cellstr(DataString));
+set(handles.uitable1_erpset_table,'ColumnWidth',{248 248});
+if handles.checkbox2_save_label.Value
+ set(handles.uitable1_erpset_table,'Enable','off');
+else
+ set(handles.uitable1_erpset_table,'Enable','on');
+end
+
+
+
+
+function edit_suffix_name_Callback(hObject, eventdata, handles)
+
+% Suffix_string = handles.edit_suffix_name.String;
+% if isempty(Suffix_string)
+% msgboxText = 'You must enter a suffix at least!';
+% title = 'EStudio: f_ERP_save_multi_file() error';
+% errorfound(msgboxText, title);
+% return
+% end
+%
+% if handles.checkbox1_suffix.Value
+%
+% DataString_before = handles.uitable1_erpset_table.Data;
+% for Numofselectederp = 1:size(DataString_before,1)
+% DataString{Numofselectederp,1} = char(strcat(DataString_before{Numofselectederp,1},'-',char(Suffix_string)));
+% DataString{Numofselectederp,2} = DataString_before{Numofselectederp,2};
+% end
+%
+% set(handles.uitable1_erpset_table,'Data',cellstr(DataString));
+% set(handles.uitable1_erpset_table,'ColumnWidth',{248 248});
+% set(handles.uitable1_erpset_table,'Enable','off');
+% handles.suffix=Suffix_string;
+% end
+
+% --- Executes during object creation, after setting all properties.
+function edit_suffix_name_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+
+
+
+% --- Executes on button press in checkbox2_save_label.
+function checkbox2_save_label_Callback(hObject, eventdata, handles)
+
+Values = handles.checkbox2_save_label.Value;
+
+if Values
+ set(handles.checkbox3_filename_erpname,'Enable','on');
+ ALLERP = handles.ALLERP;
+ Selected_ERP_label = handles.Selected_ERP_label;
+ DataString_before = handles.uitable1_erpset_table.Data;
+ for Numofselectederp = 1:size(DataString_before,1)
+ DataString{Numofselectederp,1} = DataString_before{Numofselectederp,1};
+ DataString{Numofselectederp,2} = char(ALLERP(Selected_ERP_label(Numofselectederp)).filename);
+ end
+ set(handles.uitable1_erpset_table,'Data',DataString);
+else
+ set(handles.checkbox3_filename_erpname,'Enable','off');
+ DataString_before = handles.uitable1_erpset_table.Data;
+ for Numofselectederp = 1:size(DataString_before,1)
+ DataString_before{Numofselectederp,2} = '';
+ end
+ set(handles.uitable1_erpset_table,'Data',DataString_before);
+ set(handles.uitable1_erpset_table,'Enable','on');
+end
+if handles.checkbox2_save_label.Value
+ set(handles.uitable1_erpset_table,'Enable','off');
+else
+ set(handles.uitable1_erpset_table,'Enable','on');
+end
+
+
+
+% --- Executes on button press in checkbox3_filename_erpname.
+function checkbox3_filename_erpname_Callback(hObject, eventdata, handles)
+Value_filename_erpname = handles.checkbox3_filename_erpname.Value;
+
+set(handles.uitable1_erpset_table,'Enable','off');
+DataString_before = handles.uitable1_erpset_table.Data;
+
+for Numofselectederp = 1:size(DataString_before,1)
+
+ DataString{Numofselectederp,1} = DataString_before{Numofselectederp,1};
+ fileName = char(DataString_before{Numofselectederp,1});
+ if isempty(fileName)
+ fileName = strcat(num2str(Numofselectederp),'erp');
+ end
+ [pathstr, file_name, ext] = fileparts(fileName);
+ if isempty(file_name)
+ file_name = [num2str(Selected_ERP_label(Numofselectederp)),'_ERP.erp'];
+ else
+ file_name = [file_name,'.erp'];
+ end
+ DataString{Numofselectederp,2} = file_name;
+end
+
+set(handles.uitable1_erpset_table,'Data',cellstr(DataString));
+set(handles.uitable1_erpset_table,'ColumnWidth',{248 248});
+
+
+
+
+
+% --- Executes when entered data in editable cell(s) in uitable1_erpset_table.
+function uitable1_erpset_table_CellEditCallback(hObject, eventdata, handles)
+
+DataString = handles.uitable1_erpset_table.Data;
+Selected_ERP_label = handles.Selected_ERP_label;
+if size(DataString,1) < numel(Selected_ERP_label)
+ msgboxText = 'Erpname and filename for one of erpsets are empty at least! Please give name to erpname and filename';
+ title = 'EStudio: f_ERP_save_multi_file empty erpname';
+ errorfound(msgboxText, title);
+ return
+end
+
+for Numofselected = 1:numel(Selected_ERP_label)
+ if isempty(DataString{Numofselected,1})
+ msgboxText = 'Erpname for one of erpsets is empty at least! Please give name to that erpset';
+ title = 'EStudio: f_ERP_save_multi_file empty erpname';
+ errorfound(msgboxText, title);
+ return
+ end
+
+end
+
+
+
+% --- Executes on button press in pushbutton_Cancel.
+function pushbutton_Cancel_Callback(hObject, eventdata, handles)
+handles.output = [];
+% beep;
+disp('User selected Cancel.');
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+
+
+
+% --- Executes on button press in pushbutton4_okay.
+function pushbutton4_okay_Callback(hObject, eventdata, handles)
+% suffix = strtrim(get(handles.edit_suffix_name, 'String'));
+% if handles.checkbox1_suffix.Value
+% if isempty(suffix)
+% msgboxText = 'You must enter suffix at least!';
+% title = 'EStudio: f_ERP_save_multi_file empty erpname';
+% errorfound(msgboxText, title);
+% return
+% end
+% end
+
+Data_String =handles.uitable1_erpset_table.Data;
+ALLERP = handles.ALLERP;
+Selected_ERP_label = handles.Selected_ERP_label;
+
+if size(Data_String,1)< numel(Selected_ERP_label)%
+ msgboxText = 'Erpname for one of erpsets is empty at least! Please give a name';
+ title = 'EStudio: f_ERP_save_multi_file empty erpname';
+ errorfound(msgboxText, title);
+ return
+end
+
+
+if size(Data_String,1)> numel(Selected_ERP_label)%
+ msgboxText = 'More erpname is given. Please delect it!!!';
+ title = 'EStudio: f_ERP_save_multi_file empty erpname';
+ errorfound(msgboxText, title);
+ return
+end
+
+
+
+for Numofselected = 1:numel(Selected_ERP_label)
+ if isempty(Data_String{Numofselected,1})
+ msgboxText = 'Erpname for one of erpsets is empty at least! Please give name to that erpset';
+ title = 'EStudio: f_ERP_save_multi_file empty erpname';
+ errorfound(msgboxText, title);
+ return
+ end
+
+end
+
+
+
+for Numofselectederp = 1:numel(Selected_ERP_label)
+ ALLERP(Selected_ERP_label(Numofselectederp)).erpname = Data_String{Numofselectederp,1};
+ fileName = char(Data_String{Numofselectederp,2});
+ if isempty(fileName)
+ fileName = Data_String{Numofselectederp,1};
+ end
+
+ [pathstr, file_name, ext] = fileparts(fileName);
+ if isempty(file_name)
+ file_name = [num2str(Selected_ERP_label(Numofselectederp)),'_ERP.erp'];
+ else
+ file_name = [file_name,'.erp'];
+ end
+
+ ALLERP(Selected_ERP_label(Numofselectederp)).filename = file_name;
+ if handles.checkbox2_save_label.Value
+ ALLERP(Selected_ERP_label(Numofselectederp)).filepath = cd;
+ end
+
+ if handles.checkbox2_save_label.Value
+ ALLERP(Selected_ERP_label(Numofselectederp)).saved = 'yes';
+ else
+ ALLERP(Selected_ERP_label(Numofselectederp)).saved = 'no';
+ end
+
+end
+
+FilePath = handles.checkbox2_save_label.Value;
+
+handles.output = {ALLERP, FilePath};
+% Update handles structure
+guidata(hObject, handles);
+
+uiresume(handles.gui_chassis);
+
+
+
+% -----------------------------------------------------------------------
+function gui_chassis_CloseRequestFcn(hObject, eventdata, handles)
+
+if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting')
+ %The GUI is still in UIWAIT, us UIRESUME
+ handles.output = '';
+ %Update handles structure
+ guidata(hObject, handles);
+ uiresume(handles.gui_chassis);
+else
+ % The GUI is no longer waiting, just close it
+ delete(handles.gui_chassis);
+end
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_save_single_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_save_single_GUI.m
new file mode 100755
index 00000000..7dfaffce
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_save_single_GUI.m
@@ -0,0 +1,231 @@
+%%This function is GUI that is used to save single ERP
+
+
+
+
+
+
+
+function ERP_OUT = f_ERP_save_single_GUI(ERP_In)
+
+
+global observe_ERPDAT;
+
+try
+ % % ERP_In = evalin('base','ERP');
+ ERP_In = ERP_In;
+ % % Suffix = varargin{2};
+catch
+ ERP_In = evalin('base','ERP');
+end
+
+
+% varargout = {};
+f_ERP_save_single = figure( 'Name', 'Save ERPset GUI for single file', ...
+ 'NumberTitle', 'off', ...
+ 'MenuBar', 'none', ...
+ 'Toolbar', 'none', ...
+ 'HandleVisibility', 'off');
+f_ERP_save_single.Position(3:4) = [600 200];
+
+% global gui_erp_save_single;
+ERP_OUT = [];
+% varargout{1} = f_ERP_save_single;
+
+erp_blc_dt_adv_gui(ERP_In);
+% varargout{1} = ERP_basecorr_detrend_box;
+%%********************Draw the GUI for ERP measurement tool*****************
+ function erp_blc_dt_adv_gui(ERP_In)
+ gui_erp_save_single.erp_file_name = uiextras.VBox('Parent',f_ERP_save_single,'Spacing',1);
+
+ gui_erp_save_single.erpname_title = uiextras.HBox('Parent',gui_erp_save_single.erp_file_name,'Spacing',1);
+ uicontrol('Style', 'text','Parent', gui_erp_save_single.erpname_title,...
+ 'String',['Your active erpset is #', num2str(observe_ERPDAT.CURRENTERP)],'fontsize',16);
+
+
+ gui_erp_save_single.erpname_sec = uiextras.Grid('Parent',gui_erp_save_single.erp_file_name,'Spacing',1);
+ gui_erp_save_single.erpname_save = uicontrol('Style', 'radiobutton','Parent', gui_erp_save_single.erpname_sec,...
+ 'String','ERPname','callback',@erpname_radio,'Value',1);
+ % uiextras.Empty('Parent', gui_erp_save_single.erpname_sec);
+ gui_erp_save_single.erpname_str = uicontrol('Style', 'edit','Parent', gui_erp_save_single.erpname_sec,...
+ 'String',ERP_In.erpname,'callback',@erpname_str);
+
+ gui_erp_save_single.erpname_filename = uicontrol('Style', 'pushbutton','Parent', gui_erp_save_single.erpname_sec,...
+ 'String','save as filename','callback',@erpname_filename,'Enable','off');
+
+ set(gui_erp_save_single.erpname_sec, 'ColumnSizes',[80 400 115],'RowSizes',[40]);
+
+
+
+
+ %%Save as
+ gui_erp_save_single.filename_sec = uiextras.Grid('Parent',gui_erp_save_single.erp_file_name,'Spacing',1);
+ gui_erp_save_single.filename_save = uicontrol('Style', 'radiobutton','Parent', gui_erp_save_single.filename_sec,...
+ 'String','Save ERP as','callback',@filename_radio,'Value',0);
+ gui_erp_save_single.filename_str = uicontrol('Style', 'edit','Parent', gui_erp_save_single.filename_sec,...
+ 'String','','Enable','off');
+
+ gui_erp_save_single.filename_browse = uicontrol('Style', 'pushbutton','Parent', gui_erp_save_single.filename_sec,...
+ 'String','Browse','callback',@filename_browse,'Enable','off');
+
+ set(gui_erp_save_single.filename_sec, 'ColumnSizes',[100 410 85],'RowSizes',[40]);
+
+
+ %%Cancel and Run
+
+ gui_erp_save_single.other_option = uiextras.HBox('Parent',gui_erp_save_single.erp_file_name,'Spacing',1);
+ uiextras.Empty('Parent', gui_erp_save_single.other_option);
+ gui_erp_save_single.cancel = uicontrol('Style','pushbutton','Parent',gui_erp_save_single.other_option,...
+ 'String','Cancel','callback',@cancel_blc_dt);
+ uiextras.Empty('Parent', gui_erp_save_single.other_option);
+ gui_erp_save_single.run = uicontrol('Parent',gui_erp_save_single.other_option,'Style','pushbutton',...
+ 'String','Ok','callback',@run_blc_dt);
+ uiextras.Empty('Parent', gui_erp_save_single.other_option);
+ set(gui_erp_save_single.other_option,'Sizes',[80 170 100 170 80]);
+
+ set(gui_erp_save_single.erp_file_name,'Sizes',[30 60 60 40]);
+ end
+
+%%------------------------------------------------------------------------%%
+%%----------------------------Subfunction---------------------------------%%
+%%------------------------------------------------------------------------%%
+
+%%----------------Setting for 'save ERPname" Radio-----------------------------------------
+ function erpname_radio(~,~)
+ gui_erp_save_single.erpname_save.Value = 1;
+ end
+
+
+%%---------------Setting for filename--------------------------------------
+ function erpname_str(Source,~)
+ if gui_erp_save_single.filename_save.Value ==1
+ gui_erp_save_single.filename_str.String = gui_erp_save_single.erpname_str.String;
+ else
+ gui_erp_save_single.filename_str.String = '';
+ end
+ end
+
+%%--------------Save erpname as filename-----------------------------------
+ function erpname_filename(~,~)
+ fileName = gui_erp_save_single.filename_str.String;
+ [px, fname, ext] = fileparts(fileName);
+ gui_erp_save_single.erpname_str.String = fname;
+ end
+
+
+%%--------------------Select "Save ERP as"-----------------------------------
+ function filename_radio(Source,~)
+ if Source.Value == 0
+ gui_erp_save_single.filename_str.String = '';
+ gui_erp_save_single.filename_str.Enable = 'off';
+ gui_erp_save_single.filename_browse.Enable = 'off';
+ gui_erp_save_single.erpname_filename.Enable = 'off';
+ else
+ gui_erp_save_single.filename_str.String = gui_erp_save_single.erpname_str.String;
+ gui_erp_save_single.filename_str.Enable = 'on';
+ gui_erp_save_single.filename_browse.Enable = 'on';
+ gui_erp_save_single.erpname_filename.Enable = 'on';
+ end
+ end
+
+
+
+%%--------------------------Path-------------------------------------------
+
+ function filename_browse(~,~)
+ fileName = gui_erp_save_single.filename_str.String;
+ if ~isempty(fileName)
+ [px, fname1, ext] = fileparts(fileName);
+
+ [filename, filepath,filterindex] = uiputfile({'*.erp'; '*.mat'}, ...
+ 'Save Output file as',fname1);
+ else
+ [filename, filepath] = uiputfile({'*.erp'; '*.mat'}, ...
+ 'Save Output file as');
+ end
+
+ if isequal(filename,0)
+ disp('User selected Cancel');
+ return
+ else
+ [px, fname, ext] = fileparts(filename);
+ if strcmp(ext,'')
+ if filterindex==1 || filterindex==3
+ ext = '.erp';
+ else
+ ext = '.mat';
+ end
+ end
+ gui_erp_save_single.filename_str.String =[filepath,fname ext];
+ end
+ end
+
+
+
+
+
+
+%%-----------------------Cancel section-----------------------------------
+ function cancel_blc_dt(Source_localp_cancel,~)
+ Values_localp_cancel = Source_localp_cancel.Value;
+ if ~isempty(Values_localp_cancel)
+ beep;
+ disp('User selected Cancel');
+ ERP_OUT = ERP_In;
+ close(f_ERP_save_single);
+
+ ERPName = ERP_In.erpname;
+ px_fn = ERP_In.filepath;
+ fileName_save = ERP_In.filename;
+ erpworkingmemory('f_ERP_save_single_file',{ERPName,fileName_save,px_fn,0});
+ return;
+ end
+ end
+
+%%-----------------------Run selection-------------------------------------
+ function run_blc_dt(Source_localp_run,~)
+ Values_localp_run = Source_localp_run.Value;
+ if ~isempty(Values_localp_run)
+ ERPName = gui_erp_save_single.erpname_str.String;
+
+ if isempty(ERPName)
+ ERP_In.erpname = ERP_In.erpname;
+ ERPName = ERP_In.erpname;
+ else
+ ERP_In.erpname = ERPName;
+ end
+
+ if gui_erp_save_single.filename_save.Value ==1
+ FileName = gui_erp_save_single.filename_str.String;
+ [px_fn, fname_fn, ext_fn] = fileparts(FileName);
+
+ fileName_save = [fname_fn ext_fn];
+
+ if strcmp(ext_fn,'.erp')
+ ERP_In.filename = fileName_save;
+ ERP = ERP_In;
+ [ERP, issave, erpcom] = pop_savemyerp( ERP,'filename', fileName_save, 'filepath', px_fn);
+
+ elseif strcmp(ext_fn,'.mat')
+ ERP = ERP_In;
+ save([px_fn,filesep,fileName_save],'ERP');
+ end
+ fileName_save = [fname_fn '.erp'];
+ else
+ px_fn = ERP_In.filepath;
+ fileName_save = ERP_In.filename;
+ end
+
+
+
+ erpworkingmemory('f_ERP_save_single_file',{ERPName,fileName_save,px_fn,1});
+ ERP_OUT = ERP_In;
+ close(f_ERP_save_single);
+
+ return;
+ end
+ end
+
+
+
+end
\ No newline at end of file
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_save_single_file.fig b/studio_functions/GUIs/ERP Tab/f_ERP_save_single_file.fig
new file mode 100755
index 00000000..24128fe2
Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_ERP_save_single_file.fig differ
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_save_single_file.m b/studio_functions/GUIs/ERP Tab/f_ERP_save_single_file.m
new file mode 100755
index 00000000..1ff500a1
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_save_single_file.m
@@ -0,0 +1,320 @@
+function varargout = f_ERP_save_single_file(varargin)
+% F_ERP_SAVE_SINGLE_FILE MATLAB code for f_ERP_save_single_file.fig
+% F_ERP_SAVE_SINGLE_FILE, by itself, creates a new F_ERP_SAVE_SINGLE_FILE or raises the existing
+% singleton*.
+%
+% H = F_ERP_SAVE_SINGLE_FILE returns the handle to a new F_ERP_SAVE_SINGLE_FILE or the handle to
+% the existing singleton*.
+%
+% F_ERP_SAVE_SINGLE_FILE('CALLBACK',hObject,eventData,handles,...) calls the local
+% function named CALLBACK in F_ERP_SAVE_SINGLE_FILE.M with the given input arguments.
+%
+% F_ERP_SAVE_SINGLE_FILE('Property','Value',...) creates a new F_ERP_SAVE_SINGLE_FILE or raises the
+% existing singleton*. Starting from the left, property value pairs are
+% applied to the GUI before f_ERP_save_single_file_OpeningFcn gets called. An
+% unrecognized property name or invalid value makes property application
+% stop. All inputs are passed to f_ERP_save_single_file_OpeningFcn via varargin.
+%
+% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
+% instance to run (singleton)".
+%
+% See also: GUIDE, GUIDATA, GUIHANDLES
+
+% Edit the above text to modify the response to help f_ERP_save_single_file
+
+% Last Modified by GUIDE v2.5 02-Aug-2022 18:34:55
+
+% Begin initialization code - DO NOT EDIT
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @f_ERP_save_single_file_OpeningFcn, ...
+ 'gui_OutputFcn', @f_ERP_save_single_file_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+% End initialization code - DO NOT EDIT
+
+
+% --- Executes just before f_ERP_save_single_file is made visible.
+function f_ERP_save_single_file_OpeningFcn(hObject, eventdata, handles, varargin)
+% Choose default command line output for f_ERP_save_single_file
+
+try
+ erpname = varargin{1};
+ filename = varargin{2};
+ currenterp = varargin{3};
+ [pathstr, file_name, ext] = fileparts(erpname);
+ erpname =file_name;
+catch
+ erpname = '';
+ filename = '';
+ currenterp = '';
+end
+
+handles.erpnameor = erpname;
+handles.output = [];
+erpmenu = findobj('tag', 'erpsets');
+
+if ~isempty(erpmenu)
+ handles.menuerp = get(erpmenu);
+ set(handles.menuerp.Children, 'Enable','off');
+end
+
+erplab_studio_default_values;
+version = erplabstudiover;
+set(handles.gui_chassis,'Name', ['EStudio ' version ' - Save single Erpset GUI'])
+set(handles.edit_erpname, 'String', erpname);
+set(handles.radio_erpname,'Value',1);
+if isempty(currenterp)
+ set(handles.current_erp_label,'String', ['No active erpset was found'],...
+ 'FontWeight','Bold', 'FontSize', 16);
+else
+
+ set(handles.current_erp_label,'String', ['Your active erpset is # ' num2str(currenterp)],...
+ 'FontWeight','Bold', 'FontSize', 16)
+end
+if ~isempty(filename)
+ set(handles.edit_filename, 'Enable', 'off');
+ set(handles.edit_filename, 'String', '');
+ set(handles.radiobutton_saveas, 'Value', 0);
+ set(handles.filename_erpname, 'Enable', 'off');
+ set(handles.erpname_filename, 'Enable', 'off');
+ set(handles.pushbutton_browse, 'Enable', 'off');
+else
+ set(handles.edit_filename, 'String', '');
+ set(handles.radiobutton_saveas, 'Value', 0);
+ set(handles.edit_filename, 'Enable', 'off');
+ set(handles.filename_erpname, 'Enable', 'off');
+ set(handles.erpname_filename, 'Enable', 'off');
+ set(handles.pushbutton_browse, 'Enable', 'off');
+end
+%
+% % Color GUI
+% %
+handles = painterplabstudio(handles);
+%
+% %
+% % Set font size
+% %
+handles = setfonterplabestudio(handles);
+
+% Update handles structure
+guidata(hObject, handles);
+set(handles.filename_erpname,'BackgroundColor','white')
+
+% UIWAIT makes savemyerpGUI wait for user response (see UIRESUME)
+uiwait(handles.gui_chassis);
+
+
+
+
+% --- Outputs from this function are returned to the command line.
+function varargout = f_ERP_save_single_file_OutputFcn(hObject, eventdata, handles)
+
+% Get default command line output from handles structure
+% try
+% set(handles.menuerp.Children, 'Enable','on');
+% catch
+% disp('ERPset menu was not found...')
+% end
+varargout{1} = handles.output;
+delete(handles.gui_chassis);
+pause(0.1)
+
+
+
+
+% --- Executes on button press in radio_erpname.
+function radio_erpname_Callback(hObject, eventdata, handles)
+% hObject handle to radio_erpname (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Hint: get(hObject,'Value') returns toggle state of radio_erpname
+Value_radio_erpname = get(hObject,'Value');
+set(handles.radio_erpname, 'Value', 1);
+
+
+
+function edit_erpname_Callback(hObject, eventdata, handles)
+
+
+% --- Executes during object creation, after setting all properties.
+function edit_erpname_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+% --- Executes on button press in erpname_filename.
+function erpname_filename_Callback(hObject, eventdata, handles)
+
+fname = get(handles.edit_filename, 'String');
+%
+if strcmp(fname,'')
+ msgboxText = 'You must enter a filename first!';
+ title = 'ERPLAB: f_ERP_save_single GUI empty filename';
+ errorfound(msgboxText, title);
+ return
+end
+[pathstr, fname, ext] = fileparts(fname);
+erpname = fname;
+set(handles.edit_erpname, 'String', erpname);
+
+
+% --- Executes on button press in radiobutton_saveas.
+function radiobutton_saveas_Callback(hObject, eventdata, handles)
+
+if get(hObject, 'Value')
+ set(handles.edit_filename, 'Enable', 'on');
+ set(handles.filename_erpname, 'Enable', 'on');
+ set(handles.pushbutton_browse, 'Enable', 'on');
+ set(handles.erpname_filename, 'Enable', 'on');
+else
+ set(handles.edit_filename, 'Enable', 'off');
+ set(handles.filename_erpname, 'Enable', 'off');
+ set(handles.pushbutton_browse, 'Enable', 'off');
+ set(handles.erpname_filename, 'Enable', 'off');
+ set(handles.edit_filename, 'String', '');
+end
+
+
+function edit_filename_Callback(hObject, eventdata, handles)
+% hObject handle to edit_filename (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Hints: get(hObject,'String') returns contents of edit_filename as text
+% str2double(get(hObject,'String')) returns contents of edit_filename as a double
+
+
+% --- Executes during object creation, after setting all properties.
+function edit_filename_CreateFcn(hObject, eventdata, handles)
+% hObject handle to edit_filename (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+% Hint: edit controls usually have a white background on Windows.
+% See ISPC and COMPUTER.
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+% --- Executes on button press in filename_erpname.
+function filename_erpname_Callback(hObject, eventdata, handles)
+% hObject handle to filename_erpname (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+fname = get(handles.edit_erpname, 'String');
+%
+if strcmp(fname,'') || isempty(fname)
+ msgboxText = 'You must enter a filename first!';
+ title = 'ERPLAB: f_ERP_save_single GUI empty filename';
+ errorfound(msgboxText, title);
+ return
+end
+[pathstr, fname, ext] = fileparts(fname);
+erpname = fname;
+set(handles.edit_filename, 'String', erpname);
+
+
+
+
+% --- Executes on button press in pushbutton_browse.
+function pushbutton_browse_Callback(hObject, eventdata, handles)
+fndefault = get(handles.edit_filename,'String');
+[fname, pathname] = uiputfile({'*.erp', 'ERPset (*.erp)';...
+ '*.mat', 'MAT-files (*.mat)';...
+ '*.*' , 'All Files (*.*)'},'Save Output file as',...
+ fndefault);
+
+if isequal(fname,0)
+ disp('User selected Cancel')
+ guidata(hObject, handles);
+ handles.owfp = 0; % over write file permission
+ guidata(hObject, handles);
+else
+ set(handles.edit_filename,'String', fullfile(pathname, fname));
+ % disp(['To save ERP, user selected ', fullfile(pathname, fname)])
+ handles.owfp = 1; % over write file permission
+ guidata(hObject, handles);
+end
+
+
+
+% --- Executes on button press in pushbutton_Cancel.
+function pushbutton_Cancel_Callback(hObject, eventdata, handles)
+handles.output = [];
+beep;
+disp('User selected Cancel')
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+
+% --- Executes on button press in pushbutton4_okay.
+function pushbutton4_okay_Callback(hObject, eventdata, handles)
+erpname = strtrim(get(handles.edit_erpname, 'String'));
+
+if isempty(erpname)
+ msgboxText = 'You must enter an erpname at least!';
+ title = 'EStudio: f_ERP_save_single_file empty erpname';
+ errorfound(msgboxText, title);
+ return
+end
+
+fname = strtrim(get(handles.edit_filename, 'String'));
+if ~isempty(fname) && get(handles.radiobutton_saveas, 'Value')
+
+ [pathstr, name, ext] = fileparts(fname);
+
+ if ~strcmp(ext,'.erp') && ~strcmp(ext,'.mat')
+ ext = '.erp';
+ end
+ if strcmp(pathstr,'')
+ pathstr = cd;
+ end
+
+ fullname = fullfile(pathstr, [name ext]);
+elseif isempty(fname) && get(handles.radiobutton_saveas, 'Value')
+ msgboxText = 'You must enter a filename!';
+ title = 'EStudio: f_ERP_save_single_file empty filename';
+ errorfound(msgboxText, title);
+ return;
+else
+ fullname = [];
+end
+
+handles.output = {erpname, fullname};
+% Update handles structure
+guidata(hObject, handles);
+
+uiresume(handles.gui_chassis);
+
+
+
+
+% -----------------------------------------------------------------------
+function gui_chassis_CloseRequestFcn(hObject, eventdata, handles)
+
+if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting')
+ %The GUI is still in UIWAIT, us UIRESUME
+ handles.output = '';
+ %Update handles structure
+ guidata(hObject, handles);
+ uiresume(handles.gui_chassis);
+else
+ % The GUI is no longer waiting, just close it
+ delete(handles.gui_chassis);
+end
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_simulation_panel.m b/studio_functions/GUIs/ERP Tab/f_ERP_simulation_panel.m
new file mode 100644
index 00000000..5b18461e
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_simulation_panel.m
@@ -0,0 +1,2161 @@
+%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com
+%Center for Mind and Brain
+%University of California, Davis
+%Davis, CA, USA
+%Mar. 2023
+
+% ERPLAB Studio
+
+function varargout = f_ERP_simulation_panel(varargin)
+
+% global gui_erp_simulation;
+global observe_ERPDAT;
+% addlistener(observe_ERPDAT,'ALLERP_change',@erpschange);
+% addlistener(observe_ERPDAT,'ERP_change',@drawui_CB);
+% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange);
+addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged);
+
+%%---------------------------gui-------------------------------------------
+[version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+if nargin == 0
+ fig = figure(); % Parent figure
+ ERP_simulation_box = uiextras.BoxPanel('Parent', fig, 'Title', 'Create Artificial ERP Waveform', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel
+elseif nargin == 1
+ ERP_simulation_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Create Artificial ERP Waveform', 'Padding', 5,'BackgroundColor',ColorB_def);
+else
+ ERP_simulation_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Create Artificial ERP Waveform', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def);
+end
+
+gui_erp_simulation = struct();
+try
+ FonsizeDefault = varargin{2};
+catch
+ FonsizeDefault = [];
+end
+if isempty(FonsizeDefault)
+ FonsizeDefault = f_get_default_fontsize();
+end
+erp_blc_dt_gui(FonsizeDefault);
+varargout{1} = ERP_simulation_box;
+%%********************Draw the GUI for ERP measurement tool*****************
+ function erp_blc_dt_gui(FonsizeDefault)
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+
+ if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded')
+ Enable_label = 'off';
+ else
+ Enable_label = 'on';
+ end
+
+ def = erpworkingmemory('pop_ERP_simulation');
+ if isempty(def)
+ def = {1,1,100,50,0,-200,799,1,1000,0,1,0,1,0,1,10};
+ end
+
+ try
+ BasFunLabel = def{1};
+ catch
+ BasFunLabel =1;
+ end
+ if isempty(BasFunLabel)|| ~isnumeric(BasFunLabel)
+ BasFunLabel =1;
+ end
+ if numel(BasFunLabel)~=1
+ BasFunLabel=BasFunLabel(1);
+ end
+
+ gui_erp_simulation.bsfun_box = uiextras.VBox('Parent',ERP_simulation_box,'Spacing',1,'BackgroundColor',ColorB_def);
+
+
+ %%-----------------------Plot axis---------------------------------
+ gui_erp_simulation.plotasix_op = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+
+ gui_erp_simulation.plot_erp = axes( 'Parent', gui_erp_simulation.plotasix_op);%, 'ActivePositionProperty', 'Position'
+ %
+
+ %%----------------------information for Real data------------------
+ gui_erp_simulation.realdata_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.realdata_title,...
+ 'String','Basic Information for Real Data','FontWeight','bold','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def);
+
+ gui_erp_simulation.realdatamatch_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ gui_erp_simulation.realerp_check = uicontrol('Style', 'checkbox','Parent', gui_erp_simulation.realdatamatch_title,...
+ 'callback',@erpcheckbox,'String','Compare with Real Data','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def,'Value',0);
+ uiextras.Empty('Parent', gui_erp_simulation.realdatamatch_title);
+ set(gui_erp_simulation.realdatamatch_title, 'Sizes',[200 70]);
+
+ %%ERPset for real data
+ gui_erp_simulation.erpset_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.erpset_title,...
+ 'String','ERPset:','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def);
+ gui_erp_simulation.erpsetedit = uicontrol('Style', 'edit','Parent', gui_erp_simulation.erpset_title,...
+ 'callback',@erpsetedit,'String','','FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1],'Enable','off');
+
+ gui_erp_simulation.erpsetpopup = uicontrol('Style', 'pushbutton','Parent', gui_erp_simulation.erpset_title,...
+ 'callback',@erpsetpopup,'String','Browse','FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1],'Enable','off');
+
+ %%Channel for real data
+ gui_erp_simulation.erpsetchan_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.erpsetchan_title,...
+ 'String','Channel:','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def);
+ gui_erp_simulation.channeledit = uicontrol('Style', 'edit','Parent', gui_erp_simulation.erpsetchan_title,...
+ 'callback',@channeledit,'String','','FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1],'Enable','off');
+
+ gui_erp_simulation.channelpopup = uicontrol('Style', 'pushbutton','Parent', gui_erp_simulation.erpsetchan_title,...
+ 'callback',@channelpopup,'String','Browse','FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1],'Enable','off');
+
+
+ %%bin for real data
+ gui_erp_simulation.erpsetbin_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.erpsetbin_title,...
+ 'String','Bin:','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def);
+ gui_erp_simulation.binedit = uicontrol('Style', 'edit','Parent', gui_erp_simulation.erpsetbin_title,...
+ 'callback',@binedit,'String','','FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1],'Enable','off');
+
+ gui_erp_simulation.binpopup = uicontrol('Style', 'pushbutton','Parent', gui_erp_simulation.erpsetbin_title,...
+ 'callback',@binpopup,'String','Browse','FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1],'Enable','off');
+
+ if length(observe_ERPDAT.ALLERP)==1 && strcmpi(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded')
+ gui_erp_simulation.realerp_check.Value =0;
+ EnableFlag = 'off';
+ gui_erp_simulation.realerp_check.Enable = EnableFlag;
+ end
+ %%--------------------Basic information----------------------------
+ gui_erp_simulation.asif_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.asif_title,...
+ 'String','Basic Information for Simulation','FontWeight','bold','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def);
+
+
+ gui_erp_simulation.epoch_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.epoch_title,...
+ 'String','Epoch: Start','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def);
+ try
+ epochStart = def{6};
+ catch
+ epochStart = -200;
+ end
+ gui_erp_simulation.epoch_start = uicontrol('Style', 'edit','Parent', gui_erp_simulation.epoch_title,...
+ 'callback',@epochstart,'String',num2str(epochStart),'FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1]);
+
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.epoch_title,...
+ 'String','Stop','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def);
+ try
+ epochStop = def{7};
+ catch
+ epochStop = 799;
+ end
+
+ gui_erp_simulation.epoch_stop = uicontrol('Style', 'edit','Parent', gui_erp_simulation.epoch_title,...
+ 'callback',@epocstop,'String',num2str(epochStop),'FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1]);
+
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.epoch_title,...
+ 'String','ms','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def);
+ set(gui_erp_simulation.epoch_title, 'Sizes',[80 60 40 60 25]);
+
+ try
+ srateop = def{8};
+ catch
+ srateop = 1;
+ end
+
+ gui_erp_simulation.srate_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ gui_erp_simulation.srate=uicontrol('Style', 'radiobutton','Parent', gui_erp_simulation.srate_title,...
+ 'callback',@srateop,'String','Sampling rate','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def);
+ try
+ srate = def{9};
+ catch
+ srate = 1000;
+ end
+ gui_erp_simulation.srateedit =uicontrol('Style', 'edit','Parent', gui_erp_simulation.srate_title,...
+ 'callback',@srateedit,'String', '','FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1]);
+ if srateop==1
+ gui_erp_simulation.srate.Value =1;
+ gui_erp_simulation.srateedit.Enable = 'on';
+ gui_erp_simulation.srateedit.String = num2str(srate);
+ else
+ gui_erp_simulation.srate.Value =0;
+ gui_erp_simulation.srateedit.Enable = 'off';
+ gui_erp_simulation.srateedit.String = num2str(1000/srate);
+ end
+
+
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.srate_title,...
+ 'String','Hz','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_simulation.srate_title);
+ set(gui_erp_simulation.srate_title, 'Sizes',[120 80 25 40]);
+
+
+ gui_erp_simulation.speriod_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+
+ gui_erp_simulation.srateperiod=uicontrol('Style', 'radiobutton','Parent', gui_erp_simulation.speriod_title,...
+ 'callback',@srateperiod,'String','Sampling period','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def);
+ gui_erp_simulation.srateperiodedit =uicontrol('Style', 'edit','Parent', gui_erp_simulation.speriod_title,...
+ 'callback',@srateperiodedit,'String', '','FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1]);
+ if srateop==1
+ gui_erp_simulation.srateperiod.Value =0;
+ gui_erp_simulation.srateperiodedit.Enable = 'off';
+ gui_erp_simulation.srateperiodedit.String = num2str(1000/srate);
+ else
+ gui_erp_simulation.srateperiod.Value =1;
+ gui_erp_simulation.srateperiodedit.Enable = 'on';
+ gui_erp_simulation.srateperiodedit.String = num2str(srate);
+ end
+
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.speriod_title,...
+ 'String','ms','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_simulation.speriod_title);
+ set(gui_erp_simulation.speriod_title, 'Sizes',[120 80 25 40]);
+
+
+ %%----------------------Basic Function title type-------------------
+ gui_erp_simulation.bsfun_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.bsfun_title,...
+ 'String','Basic Function for Simulation','FontWeight','bold','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def);
+
+ %%ExGaussian Function
+ gui_erp_simulation.exguafun_option = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ gui_erp_simulation.exgua_op = uicontrol('Style', 'radiobutton','Parent', gui_erp_simulation.exguafun_option,...
+ 'String','ExGaussian','callback',@exguass_op,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ if BasFunLabel==1
+ gui_erp_simulation.exgua_op.Value =1;
+ ExgauEnable = 'on';
+ else
+ gui_erp_simulation.exgua_op.Value =0;
+ ExgauEnable = 'off';
+ end
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.exguafun_option,...
+ 'String','Peak amplitude','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ try
+ Exgau_amp = def{2};
+ catch
+ Exgau_amp =0;
+ end
+ if isempty(Exgau_amp)|| ~isnumeric(Exgau_amp)
+ Exgau_amp =0;
+ end
+ if numel(Exgau_amp)~=1
+ Exgau_amp = Exgau_amp(1);
+ end
+ gui_erp_simulation.exgua_peakamp = uicontrol('Style', 'edit','Parent', gui_erp_simulation.exguafun_option,...
+ 'String',num2str(Exgau_amp),'callback',@exgau_peakamp,'Enable',ExgauEnable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]);
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.exguafun_option,...
+ 'String','μV','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ uiextras.Empty('Parent', gui_erp_simulation.exguafun_option);
+ set(gui_erp_simulation.exguafun_option, 'Sizes',[90 90 60 30 15]);
+
+ gui_erp_simulation.exguafun_setting = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_simulation.exguafun_setting);
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.exguafun_setting,...
+ 'String','Gaussian mean','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ try
+ Exgau_mean = def{3};
+ catch
+ Exgau_mean =100;
+ end
+ if isempty(Exgau_mean) || ~isnumeric(Exgau_mean)
+ Exgau_mean =100;
+ end
+ gui_erp_simulation.exgua_mean = uicontrol('Style', 'edit','Parent', gui_erp_simulation.exguafun_setting,...
+ 'String',num2str(Exgau_mean),'callback',@exgau_mean,'Enable',ExgauEnable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]);
+
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.exguafun_setting,...
+ 'String','SD','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ try
+ ExGauSD = def{4};
+ catch
+ ExGauSD =50;
+ end
+ if isempty(ExGauSD) || ~isnumeric(ExGauSD)
+ ExGauSD =50;
+ end
+ gui_erp_simulation.exgua_sd = uicontrol('Style', 'edit','Parent', gui_erp_simulation.exguafun_setting,...
+ 'String',num2str(ExGauSD),'callback',@exgau_sd,'Enable',ExgauEnable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]);
+ set(gui_erp_simulation.exguafun_setting, 'Sizes',[15 90 50 40 50]);
+
+
+ gui_erp_simulation.exguafun_setting1 = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_simulation.exguafun_setting1);
+
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.exguafun_setting1,...
+ 'String','Exponential tau','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ try
+ ExGauTau = def{5};
+ catch
+ ExGauTau =0;
+ end
+ if isempty(ExGauTau) || ~isnumeric(ExGauTau)
+ ExGauTau =0;
+ end
+ gui_erp_simulation.exgua_tau = uicontrol('Style', 'edit','Parent', gui_erp_simulation.exguafun_setting1,...
+ 'String',num2str(ExGauTau),'callback',@exgau_tau,'Enable',ExgauEnable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]);
+ uiextras.Empty('Parent', gui_erp_simulation.exguafun_setting1);
+ uiextras.Empty('Parent', gui_erp_simulation.exguafun_setting1);
+ set(gui_erp_simulation.exguafun_setting1, 'Sizes',[15 90 50 40 50]);
+
+ %%Impulse function
+ gui_erp_simulation.impulse_option = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ gui_erp_simulation.impulse_op = uicontrol('Style', 'radiobutton','Parent', gui_erp_simulation.impulse_option,...
+ 'String','Impulse','callback',@impulse_op,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ if BasFunLabel==2
+ ImpulseEnable ='on';
+ gui_erp_simulation.impulse_op.Value =1;
+
+ else
+ ImpulseEnable = 'off';
+ gui_erp_simulation.impulse_op.Value =0;
+ end
+
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.impulse_option,...
+ 'String','Peak amplitude','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ gui_erp_simulation.impulse_peakamp = uicontrol('Style', 'edit','Parent', gui_erp_simulation.impulse_option,...
+ 'String','','callback',@impulse_peakamp,'Enable',ImpulseEnable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]);
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.impulse_option,...
+ 'String','μV','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ if BasFunLabel==2
+ try
+ impulsePeakamp = def{2};
+ catch
+ impulsePeakamp = 1;
+ end
+ if isempty(impulsePeakamp) || ~isnumeric(impulsePeakamp)
+ impulsePeakamp =1;
+ end
+ gui_erp_simulation.impulse_peakamp.String = num2str(impulsePeakamp);
+ end
+ uiextras.Empty('Parent', gui_erp_simulation.impulse_option);
+ set( gui_erp_simulation.impulse_option, 'Sizes',[80 100 60 30 15]);
+
+ gui_erp_simulation.impulse_setting = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_simulation.impulse_setting);
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.impulse_setting,...
+ 'String','Latency','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ gui_erp_simulation.impulse_latency = uicontrol('Style', 'edit','Parent', gui_erp_simulation.impulse_setting,...
+ 'String','','callback',@impulse_latency,'Enable',ImpulseEnable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]);
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.impulse_setting,...
+ 'String','ms','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ if BasFunLabel==2
+ try
+ impulselat = def{3};
+ catch
+ impulselat = 100;
+ end
+ if isempty(impulselat) || ~isnumeric(impulselat)
+ impulselat = 100;
+ end
+ gui_erp_simulation.impulse_latency.String = num2str(impulselat);
+ end
+
+ uiextras.Empty('Parent', gui_erp_simulation.impulse_setting);
+ set(gui_erp_simulation.impulse_setting, 'Sizes',[80 100 60 30 15]);
+
+ %%Boxcar function
+ gui_erp_simulation.square_option = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ gui_erp_simulation.square_op = uicontrol('Style', 'radiobutton','Parent', gui_erp_simulation.square_option,...
+ 'String','Boxcar','callback',@square_op,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.square_option,...
+ 'String','Peak amplitude','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ if BasFunLabel==3
+ squareEnable = 'on';
+ else
+ squareEnable = 'off';
+ end
+ gui_erp_simulation.square_peakamp = uicontrol('Style', 'edit','Parent', gui_erp_simulation.square_option,...
+ 'String','','callback',@square_peakamp,'Enable',squareEnable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]);
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.square_option,...
+ 'String','μV','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_simulation.square_option);
+ if BasFunLabel==3
+ try
+ sqaurePeakamp = def{2};
+ catch
+ sqaurePeakamp = 1;
+ end
+ if isempty(sqaurePeakamp) || ~isnumeric(sqaurePeakamp)
+ sqaurePeakamp =1;
+ end
+ gui_erp_simulation.square_peakamp.String = num2str(sqaurePeakamp);
+ gui_erp_simulation.square_op.Value =1;
+ else
+ gui_erp_simulation.square_op.Value =0;
+ end
+ set( gui_erp_simulation.square_option, 'Sizes',[80 100 60 30 15]);
+
+ gui_erp_simulation.square_setting = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_simulation.square_setting);
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.square_setting,...
+ 'String','Onset','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ gui_erp_simulation.square_onset = uicontrol('Style', 'edit','Parent', gui_erp_simulation.square_setting,...
+ 'String','','callback',@square_onset,'Enable',squareEnable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]);
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.square_setting,...
+ 'String','ms','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ if BasFunLabel==3
+ try
+ Onsetlat = def{3};
+ catch
+ Onsetlat = 100;
+ end
+ if isempty(Onsetlat) || ~isnumeric(Onsetlat)
+ Onsetlat =100;
+ end
+ gui_erp_simulation.square_onset.String = num2str(Onsetlat);
+ end
+
+
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.square_setting,...
+ 'String','Offset','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ gui_erp_simulation.square_offset = uicontrol('Style', 'edit','Parent', gui_erp_simulation.square_setting,...
+ 'String','','callback',@square_offset,'Enable',squareEnable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]);
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.square_setting,...
+ 'String','ms','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ if BasFunLabel==3
+ try
+ Offsetlat = def{4};
+ catch
+ Offsetlat = 50;
+ end
+ if isempty(Offsetlat) || ~isnumeric(Offsetlat)
+ Offsetlat =50;
+ end
+ gui_erp_simulation.square_offset.String = num2str(Offsetlat);
+ end
+ set( gui_erp_simulation.square_setting, 'Sizes',[15 40 60 25 40 60 25]);
+
+
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ %%-----------------------noise ------------------------------------
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ gui_erp_simulation.noisefun_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.noisefun_title,...
+ 'String','Noise Function for Simulation','FontWeight','bold','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def);
+
+
+ %%sin noise
+ gui_erp_simulation.sin_option = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ gui_erp_simulation.sin_op = uicontrol('Style', 'checkbox','Parent', gui_erp_simulation.sin_option ,...
+ 'String','Sinusoidal','callback',@sinoise_op,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ try
+ sinop = def{14};
+ catch
+ sinop =0;
+ end
+ if isempty(sinop)
+ sinop =0;
+ end
+ if sinop==1
+ gui_erp_simulation.sin_op.Value=1;
+ sinEnable = 'on';
+ else
+ gui_erp_simulation.sin_op.Value=0;
+ sinEnable = 'off';
+ end
+
+ gui_erp_simulation.sin_amp = uicontrol('Style', 'edit','Parent', gui_erp_simulation.sin_option ,...
+ 'String',' ','callback',@sin_amp,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',sinEnable);
+ try
+ sinamp = def{15};
+ catch
+ sinamp =0;
+ end
+ if isempty(sinamp) ||~isnumeric(sinamp)
+ sinamp =0;
+ end
+ gui_erp_simulation.sin_amp.String = num2str(sinamp);
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.sin_option,...
+ 'String','μV','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ gui_erp_simulation.sin_fre = uicontrol('Style', 'edit','Parent', gui_erp_simulation.sin_option ,...
+ 'String',' ','callback',@sinoise_fre,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',sinEnable);
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.sin_option,...
+ 'String','Hz','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+
+ try
+ sinfre = def{16};
+ catch
+ sinfre =10;
+ end
+ if isempty(sinfre) ||~isnumeric(sinfre) || sinfre<=0
+ sinfre =10;
+ end
+ gui_erp_simulation.sin_fre.String = num2str(sinfre);
+ set(gui_erp_simulation.sin_option, 'Sizes',[90 60 30 60 30]);
+
+ %%white noise
+ gui_erp_simulation.white_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ gui_erp_simulation.white_op = uicontrol('Style', 'checkbox','Parent', gui_erp_simulation.white_title ,...
+ 'String','White','callback',@whitenoise_op,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ try
+ whiteop =def{10};
+ catch
+ whiteop=0;
+ end
+ if isempty(whiteop) || ~isnumeric(whiteop)
+ whiteop=0;
+ end
+ if whiteop==1
+ gui_erp_simulation.white_op.Value =1;
+ whitEnable = 'on';
+ else
+ gui_erp_simulation.white_op.Value =0;
+ whitEnable = 'off';
+ end
+
+ gui_erp_simulation.white_amp = uicontrol('Style', 'edit','Parent', gui_erp_simulation.white_title ,...
+ 'String',' ','callback',@white_amp,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',whitEnable);
+
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.white_title,...
+ 'String','μV','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_simulation.white_title);
+ uiextras.Empty('Parent', gui_erp_simulation.white_title);
+ try
+ whiteamp =def{11};
+ catch
+ whiteamp=0;
+ end
+ if isempty(whiteamp)
+ whiteamp=0;
+ end
+ gui_erp_simulation.white_amp.String = num2str(whiteamp);
+ set(gui_erp_simulation.white_title, 'Sizes',[90 60 30 60 30]);
+
+ %%pink noise
+ gui_erp_simulation.pink_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ gui_erp_simulation.pink_op = uicontrol('Style', 'checkbox','Parent', gui_erp_simulation.pink_title ,...
+ 'String','Pink','callback',@pinknoise_op,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ try
+ pinkeop =def{12};
+ catch
+ pinkeop=0;
+ end
+ if isempty(pinkeop) || ~isnumeric(pinkeop)
+ pinkeop=0;
+ end
+ if pinkeop==1
+ gui_erp_simulation.pink_op.Value =1;
+ pinkEnable = 'on';
+ else
+ gui_erp_simulation.pink_op.Value =0;
+ pinkEnable = 'off';
+ end
+
+ gui_erp_simulation.pink_amp = uicontrol('Style', 'edit','Parent', gui_erp_simulation.pink_title ,...
+ 'String',' ','callback',@pink_amp,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',pinkEnable);
+ try
+ pinkAmp = def{13};
+ catch
+ pinkAmp=0;
+ end
+ gui_erp_simulation.pink_amp.String = num2str(pinkAmp);
+ uicontrol('Style', 'text','Parent', gui_erp_simulation.pink_title,...
+ 'String','μV','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_simulation.pink_title);
+ uiextras.Empty('Parent', gui_erp_simulation.pink_title);
+ set(gui_erp_simulation.pink_title, 'Sizes',[90 60 30 60 30]);
+
+ %%update noise if needed New Noise
+ %%seeds for white and pink noise
+ gui_erp_simulation.SimulationSeed = erpworkingmemory('SimulationSeed');
+ rng(1,'twister');
+ SimulationSeed = rng;
+ erpworkingmemory('SimulationSeed',SimulationSeed);
+ %phase for sin noise
+ gui_erp_simulation.SimulationPhase = erpworkingmemory('SimulationPhase');
+ SimulationPhase = 0;
+ erpworkingmemory('SimulationPhase',SimulationPhase);
+
+ gui_erp_simulation.newnoise_option = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_simulation.newnoise_option);
+ gui_erp_simulation.newnoise_op = uicontrol('Style', 'pushbutton','Parent', gui_erp_simulation.newnoise_option ,...
+ 'String','Re-randomize noise','callback',@newnoise_op,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Value',0);
+ % uiextras.Empty('Parent', gui_erp_simulation.newnoise_option);
+ % uiextras.Empty('Parent', gui_erp_simulation.newnoise_option);
+ uiextras.Empty('Parent', gui_erp_simulation.newnoise_option);
+ set(gui_erp_simulation.newnoise_option, 'Sizes',[70 130 70]);
+
+
+ %%Cancel and advanced
+ gui_erp_simulation.other_option = uiextras.HBox('Parent',gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_simulation.other_option,'BackgroundColor',ColorB_def);
+ gui_erp_simulation.simulation_help = uicontrol('Parent',gui_erp_simulation.other_option,'Style','pushbutton',...
+ 'String','?','FontWeight','bold','callback',@simulation_help,'FontSize',14,'BackgroundColor',[1 1 1]);
+ uiextras.Empty('Parent', gui_erp_simulation.other_option);
+ gui_erp_simulation.apply = uicontrol('Style','pushbutton','Parent',gui_erp_simulation.other_option,...
+ 'String','Apply','callback',@simulation_apply,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]);
+ uiextras.Empty('Parent', gui_erp_simulation.other_option);
+ set(gui_erp_simulation.other_option, 'Sizes',[15 105 30 105 15]);
+ set(gui_erp_simulation.bsfun_box, 'Sizes',[200 20 25 25 25 25 20 25 25 25 20 25 25 25 25 25 25 25 20 25 25 25 25 25]);
+ plot_erp_simulation();
+ end
+
+
+
+%%****************************************************************************************************************************************
+%%******************* Subfunctions ***************************************************************************************************
+%%****************************************************************************************************************************************
+
+
+%%---------------------Match with real ERP?--------------------------------
+ function erpcheckbox(Str,~)
+ Value = Str.Value;
+ if Value ==1
+ EnableFlag = 'on';
+ else
+ EnableFlag = 'off';
+ end
+ if length(observe_ERPDAT.ALLERP)==1 && strcmpi(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded')
+ Str.Enable = 'off';
+ EnableFlag = 'off';
+
+ gui_erp_simulation.erpsetedit.Enable = EnableFlag;
+ gui_erp_simulation.erpsetpopup.Enable = EnableFlag;
+ gui_erp_simulation.channeledit.Enable = EnableFlag;
+ gui_erp_simulation.channelpopup.Enable = EnableFlag;
+ gui_erp_simulation.binedit.Enable = EnableFlag;
+ gui_erp_simulation.binpopup.Enable = EnableFlag;
+ return;
+ end
+ gui_erp_simulation.erpsetedit.Enable = EnableFlag;
+ gui_erp_simulation.erpsetpopup.Enable = EnableFlag;
+ gui_erp_simulation.channeledit.Enable = EnableFlag;
+ gui_erp_simulation.channelpopup.Enable = EnableFlag;
+ gui_erp_simulation.binedit.Enable = EnableFlag;
+ gui_erp_simulation.binpopup.Enable = EnableFlag;
+ if Value ==1
+ EnableFlagn = 'off';
+ else
+ EnableFlagn = 'on';
+ end
+
+ gui_erp_simulation.epoch_start.Enable = EnableFlagn;
+ gui_erp_simulation.epoch_stop.Enable = EnableFlagn;
+ gui_erp_simulation.srate.Enable = EnableFlagn;
+ gui_erp_simulation.srateedit.Enable = EnableFlagn;
+ gui_erp_simulation.srateperiod.Enable = EnableFlagn;
+ gui_erp_simulation.srateperiodedit.Enable = EnableFlagn;
+ if Value ==0
+ if gui_erp_simulation.srate.Value ==1
+ gui_erp_simulation.srate.Value = 1;
+ gui_erp_simulation.srateedit.Enable = 'on';
+ gui_erp_simulation.srateperiod.Value = 0;
+ gui_erp_simulation.srateperiodedit.Enable = 'off';
+ else
+ gui_erp_simulation.srate.Value = 0;
+ gui_erp_simulation.srateedit.Enable = 'off';
+ gui_erp_simulation.srateperiod.Value = 1;
+ gui_erp_simulation.srateperiodedit.Enable = 'on';
+ end
+ end
+ plot_erp_simulation();
+ end
+
+%%------------------------ERPset edit--------------------------------------
+ function erpsetedit(Str,~)
+ ERPArray = str2num(Str.String);
+ if ~isempty(observe_ERPDAT.ALLERP)
+ if ~isempty(ERPArray) && min(ERPArray)>0
+ if numel(ERPArray) ~=1
+ ERPArray = ERPArray(1);
+ end
+ if ERPArray> length(observe_ERPDAT.ALLERP)
+ msgboxText = 'Create Artificial ERP Waveform -Real ERP: Input should be smaller than the length of ALLERP';
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '';
+ return;
+ end
+ gui_erp_simulation.erpsetedit.String = num2str(ERPArray);
+ ERP =observe_ERPDAT.ALLERP(ERPsetArray);
+ if ~strcmpi(ERP.erpname,'No ERPset loaded')
+ EpochStart =[];
+ EpochStop = [];
+ srate =[];
+ try
+ EpochStart = ERP.times(1);
+ EpochStop = ERP.times(end);
+ srate = ERP.srate;
+ catch
+ end
+ if ~isempty(EpochStart) && ~isempty(EpochStop) && ~isempty(srate)
+ gui_erp_simulation.epoch_start.String = num2str(EpochStart);
+ gui_erp_simulation.epoch_stop.String = num2str(EpochStop);
+ if srate~=0
+ gui_erp_simulation.srateedit.String = num2str(srate);
+ gui_erp_simulation.srateperiodedit.String = num2str(1000/srate);
+ end
+ end
+ end
+ else
+ msgboxText = 'Create Artificial ERP Waveform -Real ERP: Index of ERPset should be a positive numeric';
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '';
+ return;
+ end
+ else
+ gui_erp_simulation.realerp_check.Value =0;
+ EnableFlag = 'off';
+ gui_erp_simulation.realerp_check.Enable = EnableFlag;
+ gui_erp_simulation.erpsetedit.Enable = EnableFlag;
+ gui_erp_simulation.erpsetpopup.Enable = EnableFlag;
+ gui_erp_simulation.channeledit.Enable = EnableFlag;
+ gui_erp_simulation.channelpopup.Enable = EnableFlag;
+ gui_erp_simulation.binedit.Enable = EnableFlag;
+ gui_erp_simulation.binpopup.Enable = EnableFlag;
+ msgboxText = 'Create Artificial ERP Waveform -Real ERP: ALLERPset is empty and cannot match simulation with it';
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+
+%%-----------------------ERPset popup--------------------------------------
+ function erpsetpopup(~,~)
+ ERPArray = str2num(gui_erp_simulation.erpsetedit.String);
+ if ~isempty(ERPArray)
+ if numel(ERPArray)~=1
+ ERPArray = ERPArray(1);
+ end
+ if ERPArray< 0 || ERPArray> length(observe_ERPDAT.ALLERP)
+ ERPArray = length(observe_ERPDAT.ALLERP);
+ end
+ gui_erp_simulation.erpsetedit.String = num2str(ERPArray);
+ if ~isempty(observe_ERPDAT.ALLERP)
+ for Numoferpset = 1:length(observe_ERPDAT.ALLERP)
+ listname{Numoferpset} = char(strcat(num2str(Numoferpset),'.',observe_ERPDAT.ALLERP(Numoferpset).erpname));
+ end
+ indxlistb =ERPArray;
+
+ titlename = 'Select one ERPset:';
+ ERPsetArray = browsechanbinGUI(listname, indxlistb, titlename);
+ if ~isempty(ERPsetArray)
+ if numel(ERPsetArray)~=1
+ ERPsetArray =ERPsetArray(1);
+ end
+ CURRENTERP = ERPsetArray;
+ ALLERP = observe_ERPDAT.ALLERP;
+ handles.CURRENTERP = ERPsetArray;
+ ERP =observe_ERPDAT.ALLERP(ERPsetArray);
+ if ~strcmpi(ERP.erpname,'No ERPset loaded')
+ EpochStart =[];
+ EpochStop = [];
+ srate =[];
+ if ~isempty(CURRENTERP) && CURRENTERP >0 && CURRENTERP<= length(ALLERP)
+ ERP = ALLERP(CURRENTERP);
+ else
+ ERP = ALLERP(length(ALLERP));
+ end
+ try
+ EpochStart = ERP.times(1);
+ EpochStop = ERP.times(end);
+ srate = ERP.srate;
+ catch
+ end
+ if ~isempty(EpochStart) && ~isempty(EpochStop) && ~isempty(srate)
+ gui_erp_simulation.epoch_start.String = num2str(EpochStart);
+ gui_erp_simulation.epoch_stop.String = num2str(EpochStop);
+ if srate~=0
+ gui_erp_simulation.srateedit.String = num2str(srate);
+ gui_erp_simulation.srateperiodedit.String = num2str(1000/srate);
+ end
+ end
+ gui_erp_simulation.erpsetedit.String = num2str(CURRENTERP);
+ end
+ else%%the user did not select one ERPset
+ msgboxText = 'Create Artificial ERP Waveform -Real ERP: User selected cancel';
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ end
+ end
+ plot_erp_simulation();
+ end
+
+
+%%------------------------channel edit-------------------------------------
+ function channeledit(Str,~)
+ channelArray = str2num(Str.String);
+ if ~isempty(observe_ERPDAT.ALLERP)
+ if isempty(channelArray)
+ msgboxText = 'Create Artificial ERP Waveform -Real ERP: Please input one positive numeric for "Channel"';
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '1';
+ return;
+ end
+ if numel(channelArray)~=1
+ channelArray = channelArray(1);
+ end
+ if channelArray<=0
+ msgboxText = 'Create Artificial ERP Waveform -Real ERP: Please input one positive numeric for "Channel"';
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '1';
+ return;
+ end
+ Str.String = num2str(channelArray);
+ else
+ gui_erp_simulation.realerp_check.Value =0;
+ EnableFlag = 'off';
+ gui_erp_simulation.realerp_check.Enable = EnableFlag;
+ gui_erp_simulation.erpsetedit.Enable = EnableFlag;
+ gui_erp_simulation.erpsetpopup.Enable = EnableFlag;
+ gui_erp_simulation.channeledit.Enable = EnableFlag;
+ gui_erp_simulation.channelpopup.Enable = EnableFlag;
+ gui_erp_simulation.binedit.Enable = EnableFlag;
+ gui_erp_simulation.binpopup.Enable = EnableFlag;
+ msgboxText = 'Create Artificial ERP Waveform -Real ERP: ALLERPset is empty and cannot match simulation with it';
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '1';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+%%------------------------channel popup------------------------------------
+ function channelpopup(~,~)
+ if length(observe_ERPDAT.ALLERP)==1 && strcmpi(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded')
+ return;
+ end
+ if ~isempty(observe_ERPDAT.ALLERP)
+ ERPsetArray = str2num(gui_erp_simulation.erpsetedit.String);
+ if ~isempty(ERPsetArray)
+ if numel(ERPsetArray)~=1
+ ERPsetArray = ERPsetArray(1);
+ end
+ if ERPsetArray> length(observe_ERPDAT.ALLERP)
+ ERPsetArray = length(observe_ERPDAT.ALLERP);
+ end
+ gui_erp_simulation.erpsetedit.String = num2str(ERPsetArray);
+ channelArray = str2num(gui_erp_simulation.channeledit.String);
+ if isempty(channelArray)
+ channelArray=1;
+ end
+ if numel(channelArray)~=1
+ channelArray = channelArray(1);
+ end
+ if channelArray<=0
+ channelArray=1;
+ end
+ ERP = observe_ERPDAT.ALLERP(ERPsetArray);
+ if max(channelArray(:)) >ERP.nchan
+ channelArray =1;
+ end
+
+ for Numofchan = 1:observe_ERPDAT.ALLERP(ERPsetArray).nchan
+ listb{Numofchan}= strcat(num2str(Numofchan),'.',observe_ERPDAT.ALLERP(ERPsetArray).chanlocs(Numofchan).labels);
+ end
+ titlename = 'Select One Channel:';
+ channelArray = browsechanbinGUI(listb, channelArray, titlename);
+
+ if ~isempty(channelArray)
+ if numel(channelArray)~=1
+ channelArray = channelArray(1);
+ end
+ gui_erp_simulation.channeledit.String = num2str(channelArray);
+ else
+ msgboxText = 'Create Artificial ERP Waveform-Real ERP: User selected cancel';
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+ end
+ plot_erp_simulation();
+ end
+
+%%------------------------bin edit-----------------------------------------
+ function binedit(Str,~)
+ binArray = str2num(Str.String);
+ if ~isempty(observe_ERPDAT.ALLERP)
+ if isempty(binArray)
+ msgboxText = 'Create Artificial ERP Waveform -Real ERP: Please input one positive numeric for "Bin"';
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ % Str.String = '1';
+ return;
+ end
+ if numel(binArray)~=1
+ binArray = binArray(1);
+ end
+ if binArray<=0
+ msgboxText = 'Create Artificial ERP Waveform -Real ERP: Please input one positive numeric for "Bin"';
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '1';
+ return;
+ end
+ Str.String = num2str(binArray);
+ else
+ gui_erp_simulation.realerp_check.Value =0;
+ EnableFlag = 'off';
+ gui_erp_simulation.realerp_check.Enable = EnableFlag;
+ gui_erp_simulation.erpsetedit.Enable = EnableFlag;
+ gui_erp_simulation.erpsetpopup.Enable = EnableFlag;
+ gui_erp_simulation.channeledit.Enable = EnableFlag;
+ gui_erp_simulation.channelpopup.Enable = EnableFlag;
+ gui_erp_simulation.binedit.Enable = EnableFlag;
+ gui_erp_simulation.binpopup.Enable = EnableFlag;
+ msgboxText = 'Create Artificial ERP Waveform -Real ERP: ALLERPset is empty and cannot match simulation with it';
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '1';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+
+%%-----------------------bin popup-----------------------------------------
+ function binpopup(~,~)
+ if length(observe_ERPDAT.ALLERP)==1 && strcmpi(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded')
+ return;
+ end
+ if ~isempty(observe_ERPDAT.ALLERP)
+ ERPsetArray = str2num(gui_erp_simulation.erpsetedit.String);
+ if ~isempty(ERPsetArray)
+ if numel(ERPsetArray)~=1
+ ERPsetArray = ERPsetArray(1);
+ end
+ if ERPsetArray> length(observe_ERPDAT.ALLERP)
+ ERPsetArray = length(observe_ERPDAT.ALLERP);
+ end
+ gui_erp_simulation.erpsetedit.String = num2str(ERPsetArray);
+ binArray = str2num(gui_erp_simulation.binedit.String);
+ if isempty(binArray)
+ binArray=1;
+ end
+ if numel(binArray)~=1
+ binArray = binArray(1);
+ end
+ if binArray<=0
+ binArray=1;
+ end
+ ERP = observe_ERPDAT.ALLERP(ERPsetArray);
+ if max(binArray(:)) >ERP.nchan
+ binArray =1;
+ end
+
+ for Numofchan = 1:observe_ERPDAT.ALLERP(ERPsetArray).nbin
+ listb{Numofchan}= strcat(num2str(Numofchan),'.',observe_ERPDAT.ALLERP(ERPsetArray).bindescr{Numofchan});
+ end
+ titlename = 'Select One Bin:';
+ binArray = browsechanbinGUI(listb, binArray, titlename);
+
+ if ~isempty(binArray)
+ if numel(binArray)~=1
+ binArray = binArray(1);
+ end
+ gui_erp_simulation.binedit.String = num2str(binArray);
+ else
+ msgboxText = 'Create Artificial ERP Waveform-Real ERP: User selected cancel';
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ end
+ else
+ gui_erp_simulation.realerp_check.Value =0;
+ EnableFlag = 'off';
+ gui_erp_simulation.realerp_check.Enable = EnableFlag;
+ gui_erp_simulation.erpsetedit.Enable = EnableFlag;
+ gui_erp_simulation.erpsetpopup.Enable = EnableFlag;
+ gui_erp_simulation.channeledit.Enable = EnableFlag;
+ gui_erp_simulation.channelpopup.Enable = EnableFlag;
+ gui_erp_simulation.binedit.Enable = EnableFlag;
+ gui_erp_simulation.binpopup.Enable = EnableFlag;
+ msgboxText = 'Create Artificial ERP Waveform -Real ERP: ALLERPset is empty and cannot match simulation with it';
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '1';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+
+%%----------------------------epoch start----------------------------------
+ function epochstart(Str,~)
+ epochStart = str2num( gui_erp_simulation.epoch_start.String);
+ epochStop = str2num( gui_erp_simulation.epoch_stop.String);
+ if epochStart>=epochStop
+ beep;
+ msgboxText = ['Create Artificial ERP Waveform - The value for epoch start should be smaller than epoch stop'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+%%----------------------------epoch stop-----------------------------------
+ function epocstop(Str,~)
+ epochStart = str2num( gui_erp_simulation.epoch_start.String);
+ epochStop = str2num( gui_erp_simulation.epoch_stop.String);
+ if epochStart>=epochStop
+ beep;
+ msgboxText = ['Create Artificial ERP Waveform - The value for epoch start should be smaller than epoch stop'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+%%---------------------Sampling rate option--------------------------------
+ function srateop(~,~)
+ gui_erp_simulation.srate.Value =1;
+ gui_erp_simulation.srateedit.Enable = 'on';
+ gui_erp_simulation.srateperiod.Value =0;
+ gui_erp_simulation.srateperiodedit.Enable = 'off';
+ plot_erp_simulation();
+ end
+
+
+%%--------------Edit sampling rate-----------------------------------------
+ function srateedit(Str,~)
+ srate = str2num(Str.String);
+ if ~isempty(srate) && numel(srate)==1 && srate>0
+ gui_erp_simulation.srateperiodedit.String = num2str(1000/srate);
+ else
+ msgboxText = ['Create Artificial ERP Waveform>sampling rate- the input should be a positive numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ gui_erp_simulation.srateperiodedit.String = '';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+%%---------------------Sampling period-------------------------------------
+ function srateperiod(~,~)
+ gui_erp_simulation.srate.Value =0;
+ gui_erp_simulation.srateedit.Enable = 'off';
+ gui_erp_simulation.srateperiod.Value =1;
+ gui_erp_simulation.srateperiodedit.Enable = 'on';
+ plot_erp_simulation();
+ end
+
+%%----------------------Edit sampling period-------------------------------
+ function srateperiodedit(Str,~)
+ srateperiod = str2num(Str.String);
+ if ~isempty(srateperiod) && numel(srateperiod)==1 && srateperiod>0
+ gui_erp_simulation.srateedit.String = num2str(1000/srateperiod);
+ else
+ msgboxText = ['Create Artificial ERP Waveform>sampling period- the input should be a positive numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ gui_erp_simulation.srateedit.String = '';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+%%--------------------------------Select ex-gaussian function--------------
+ function exguass_op(~,~)
+ gui_erp_simulation.exgua_op.Value =1;
+ gui_erp_simulation.exgua_peakamp.Enable = 'on';
+ gui_erp_simulation.exgua_mean.Enable = 'on';
+ gui_erp_simulation.exgua_sd.Enable = 'on';
+ gui_erp_simulation.exgua_tau.Enable = 'on';
+
+ gui_erp_simulation.impulse_op.Value = 0;
+ gui_erp_simulation.impulse_peakamp.Enable = 'off';
+ gui_erp_simulation.impulse_latency.Enable = 'off';
+
+ gui_erp_simulation.square_op.Value = 0;
+ gui_erp_simulation.square_onset.Enable = 'off';
+ gui_erp_simulation.square_offset.Enable = 'off';
+ gui_erp_simulation.square_peakamp.Enable = 'off';
+ plot_erp_simulation();
+ end
+
+
+%%---------------Peak amplitude for ex-Gaussian function-------------------
+ function exgau_peakamp(Str,~)
+ PeakAmp = str2num(Str.String);
+ if isempty(PeakAmp) || numel(PeakAmp)~=1
+ msgboxText = ['Create Artificial ERP Waveform> peak amplitude for Ex-Gaussian should be a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '0';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+%%------------------Guasssian mean-----------------------------------------
+ function exgau_mean(Str,~)
+ Mean = str2num(Str.String);
+ if isempty(Mean) || numel(Mean)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Gaussian mean for Ex-Gaussian should be a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '0';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+%%-----------------SD for Ex-Gaussian function-----------------------------
+ function exgau_sd(Str,~)
+ SD = str2num(Str.String);
+ if isempty(SD) || numel(SD)~=1
+ msgboxText = ['Create Artificial ERP Waveform> SD for Ex-Gaussian should be a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '0';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+
+%%----------------Tau for Ex-Gaussian function-----------------------------
+ function exgau_tau(Str,~)
+ Tau = str2num(Str.String);
+ if isempty(Tau) || numel(Tau)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Exponential tau for Ex-Gaussian should be a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '0';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+
+%%--------------------------------impulse function-------------------------
+ function impulse_op(~,~)
+ gui_erp_simulation.exgua_op.Value =0;
+ gui_erp_simulation.exgua_peakamp.Enable = 'off';
+ gui_erp_simulation.exgua_mean.Enable = 'off';
+ gui_erp_simulation.exgua_sd.Enable = 'off';
+ gui_erp_simulation.exgua_tau.Enable = 'off';
+
+ gui_erp_simulation.impulse_op.Value = 1;
+ gui_erp_simulation.impulse_peakamp.Enable = 'on';
+ gui_erp_simulation.impulse_latency.Enable = 'on';
+ gui_erp_simulation.square_op.Value = 0;
+ gui_erp_simulation.square_onset.Enable = 'off';
+ gui_erp_simulation.square_offset.Enable = 'off';
+ gui_erp_simulation.square_peakamp.Enable = 'off';
+ plot_erp_simulation();
+ end
+
+%%-------------Impulse peak amplitude--------------------------------------
+ function impulse_peakamp(Str,~)
+ peakAmp = str2num(Str.String);
+ if isempty(peakAmp)
+ msgboxText = ['Create Artificial ERP Waveform>Impulse- peak amplitude should be a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '0';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+%%-------------------Latency for impluse-----------------------------------
+ function impulse_latency(Str,~)
+ peakLat = str2num(Str.String);
+ if isempty(peakLat)
+ msgboxText = ['Create Artificial ERP Waveform>Impulse- Latency should be a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '0';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+%%--------------------------------square function--------------------------
+ function square_op(~,~)
+ gui_erp_simulation.exgua_op.Value =0;
+ gui_erp_simulation.exgua_peakamp.Enable = 'off';
+ gui_erp_simulation.exgua_mean.Enable = 'off';
+ gui_erp_simulation.exgua_sd.Enable = 'off';
+ gui_erp_simulation.exgua_tau.Enable = 'off';
+
+ gui_erp_simulation.impulse_op.Value = 0;
+ gui_erp_simulation.impulse_peakamp.Enable = 'off';
+ gui_erp_simulation.impulse_latency.Enable = 'off';
+ gui_erp_simulation.square_op.Value = 1;
+ gui_erp_simulation.square_onset.Enable = 'on';
+ gui_erp_simulation.square_offset.Enable = 'on';
+ gui_erp_simulation.square_peakamp.Enable = 'on';
+ plot_erp_simulation();
+ end
+
+
+%%--------------Peak amplitude for square function-------------------------
+ function square_peakamp(Str,~)
+ peakAmp = str2num(Str.String);
+ if isempty(peakAmp)
+ msgboxText = ['Create Artificial ERP Waveform>Square- peak amplitude should be a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '0';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+%%------------------Square onset latency-----------------------------------
+ function square_onset(Str,~)
+ onsetlat = str2num(Str.String);
+ if isempty(onsetlat)
+ msgboxText = ['Create Artificial ERP Waveform>Boxcar- Onset latency should be a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '0';
+ return;
+ end
+ offsetLat = str2num(gui_erp_simulation.square_offset.String);
+ if onsetlat>offsetLat
+ msgboxText = ['Create Artificial ERP Waveform>Boxcar- Onset latency should be smaller than',32,num2str(offsetLat)];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '0';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+%%------------------Boxcar offset latency----------------------------------
+ function square_offset(Str,~)
+ offsetlat = str2num(Str.String);
+ if isempty(offsetlat)
+ msgboxText = ['Create Artificial ERP Waveform>Boxcar- Offset latency should be a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '0';
+ return;
+ end
+ onsetlat = str2num(gui_erp_simulation.square_onset.String);
+ if offsetlatBoxcar- Offset latency should be larger than',32,num2str(onsetlat)];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '0';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+%%-----------------update new noise if needed------------------------------
+ function newnoise_op(~,~)
+
+ %%reset the phase for sin signal
+ SimulationPhase = rand(1);
+ erpworkingmemory('SimulationPhase',SimulationPhase);
+
+ %%reset seeds for white or pink noise
+ SimulationSeed = erpworkingmemory('SimulationSeed');
+ try
+ SimulationSeed.Type = 'philox';
+ SimulationSeed.Seed = SimulationSeed.Seed+1;
+ catch
+ SimulationSeed.Type = 'twister';
+ SimulationSeed.Seed = 1;
+ end
+ erpworkingmemory('SimulationSeed',SimulationSeed);
+ gui_erp_simulation.SimulationSeed = SimulationSeed;
+ gui_erp_simulation.SimulationPhase = SimulationPhase;
+ plot_erp_simulation();
+ end
+
+%%-----------------check box of sin function-------------------------------
+ function sinoise_op(Str,~)
+ Value = Str.Value;
+ if Value==1
+ Enable = 'on';
+ else
+ Enable = 'off';
+ end
+ gui_erp_simulation.sin_amp.Enable = Enable;
+ gui_erp_simulation.sin_fre.Enable = Enable;
+ plot_erp_simulation();
+ end
+
+%%---------------Peak amplitude for sin noise------------------------------
+ function sin_amp(Str,~)
+ peakAmp = str2num(Str.String);
+ if isempty(peakAmp)
+ msgboxText = ['Create Artificial ERP Waveform>Sinusoidal noise- peak amplitude should be a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '0';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+%%------------------Frequency for sin noise--------------------------------
+ function sinoise_fre(Str,~)
+ Fresin = str2num(Str.String);
+ if isempty(Fresin) || Fresin<=0
+ msgboxText = ['Create Artificial ERP Waveform>Sinusoidal noise- frequency should be a positive numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+%%------------checkbox for white noise-------------------------------------
+ function whitenoise_op(Str,~)
+ if Str.Value ==1
+ gui_erp_simulation.white_amp.Enable ='on';
+ else
+ gui_erp_simulation.white_amp.Enable ='off';
+ end
+ plot_erp_simulation();
+ end
+
+%%-------------------Peak amplitude for white noise------------------------
+ function white_amp(Str,~)
+ peakAmp = str2num(Str.String);
+ if isempty(peakAmp)
+ msgboxText = ['Create Artificial ERP Waveform>White noise- peak amplitude should be a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '0';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+%%--------------------check box for pink noise-----------------------------
+ function pinknoise_op(Str,~)
+ if Str.Value ==1
+ gui_erp_simulation.pink_amp.Enable = 'on';
+ else
+ gui_erp_simulation.pink_amp.Enable = 'off';
+ end
+ plot_erp_simulation();
+ end
+
+%%------------------peak amplitude of pink noise---------------------------
+ function pink_amp(Str,~)
+ peakAmp = str2num(Str.String);
+ if isempty(peakAmp)
+ msgboxText = ['Create Artificial ERP Waveform>Pink noise- peak amplitude should be a numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ Str.String = '0';
+ return;
+ end
+ plot_erp_simulation();
+ end
+
+%%-----------------------Help----------------------------------------------
+ function simulation_help(~,~)
+
+ end
+
+
+%%----------------------apply----------------------------------------------
+ function simulation_apply(~,~)
+ erpworkingmemory('f_ERP_proces_messg','Create Artificial ERP waveform');
+ observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started.
+ ALLERPCOM = evalin('base','ALLERPCOM');
+
+ EpochStart = str2num(gui_erp_simulation.epoch_start.String);
+ EpochStop = str2num(gui_erp_simulation.epoch_stop.String);
+ if gui_erp_simulation.srate.Value
+ Srate = str2num(gui_erp_simulation.srateedit.String);
+ if isempty(Srate) || numel(Srate)~=1
+ msgboxText = ['Create Artificial ERP Waveform>Please define one numeric for sampling rate'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ gui_erp_simulation.srateedit.String = '';
+ return;
+ end
+ if Srate<=0
+ msgboxText = ['Create Artificial ERP Waveform>Sampling rate must be a positive numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ gui_erp_simulation.srateedit.String = '';
+ return;
+ end
+ else%% sampling period
+ Speriod = str2num(gui_erp_simulation.srateperiodedit.String);
+ if isempty(Speriod) || numel(Speriod)~=1
+ msgboxText = ['Create Artificial ERP Waveform>Please define one numeric for sampling period'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ gui_erp_simulation.srateperiodedit.String = '';
+ return;
+ end
+ if Speriod<=0
+ msgboxText = ['Create Artificial ERP Waveform>Sampling period must be a positive numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ gui_erp_simulation.srateperiodedit.String = '';
+ return;
+ end
+ Srate = 1000/Speriod;
+ end
+ if isempty(EpochStart) || numel(EpochStart)~=1
+ msgboxText = ['Create Artificial ERP Waveform>Please define one numeric for epoch start'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if isempty(EpochStop) || numel(EpochStop)~=1
+ msgboxText = ['Create Artificial ERP Waveform>Please define one numeric for epoch stop'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if EpochStop<=EpochStart
+ msgboxText = ['Create Artificial ERP Waveform> Start time of epoch must be smaller than stop time of epoch'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if 1000/Srate>= (EpochStop-EpochStart)
+ msgboxText = ['Create Artificial ERP Waveform> Please sampling period must be much smaller than ',32,num2str(EpochStop-EpochStart)];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ %%---------------------------Simulated signal------------------------------
+ ExGauTau =0;
+ SDOffset =50;
+ MeanLatOnset =0;
+ if gui_erp_simulation.exgua_op.Value ==1
+ BasFuncName = 'ExGaussian';
+ BasPeakAmp = str2num(gui_erp_simulation.exgua_peakamp.String);
+ if isempty(BasPeakAmp) || numel(BasPeakAmp)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "peak amplitude" of ex-Gaussian function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ MeanLatOnset = str2num(gui_erp_simulation.exgua_mean.String);
+ if isempty(MeanLatOnset) || numel(MeanLatOnset)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "Gaussian mean" of Ex-Gaussian function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ ExGauTau = str2num(gui_erp_simulation.exgua_tau.String);
+ if isempty(ExGauTau) || numel(ExGauTau)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "Tau" of Ex-Gaussian function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ SDOffset = str2num(gui_erp_simulation.exgua_sd.String);
+ if isempty(SDOffset) || numel(SDOffset)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "SD" of Ex-Gaussian function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ elseif gui_erp_simulation.impulse_op.Value ==1
+ BasFuncName = 'Impulse';
+ BasPeakAmp = str2num(gui_erp_simulation.impulse_peakamp.String);
+ if isempty(BasPeakAmp) || numel(BasPeakAmp)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "peak amplitude" of impulse function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ MeanLatOnset = str2num(gui_erp_simulation.impulse_latency.String);
+ if isempty(MeanLatOnset) || numel(MeanLatOnset)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "latency" of impulse function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ elseif gui_erp_simulation.square_op.Value ==1
+ BasFuncName = 'Boxcar';
+ BasPeakAmp = str2num(gui_erp_simulation.square_peakamp.String);
+ if isempty(BasPeakAmp) || numel(BasPeakAmp)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "peak amplitude" of Boxcar function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ MeanLatOnset = str2num(gui_erp_simulation.square_onset.String);
+ if isempty(MeanLatOnset) || numel(MeanLatOnset)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "onset" of Boxcar function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ SDOffset = str2num(gui_erp_simulation.square_offset.String);
+ if isempty(SDOffset) || numel(SDOffset)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "offset" of Boxcar function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if SDOffset< MeanLatOnset
+ msgboxText = ['Create Artificial ERP Waveform> Please "offset" should be larger than "onset" of Boxcar function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ end
+ %%---------------------------Noise signal----------------------------------
+ if gui_erp_simulation.sin_op.Value==1
+ SinoiseAmp = str2num(gui_erp_simulation.sin_amp.String);
+ if isempty(SinoiseAmp) || numel(SinoiseAmp)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "amplitude" of sinusoidal noise'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ SinoiseFre = str2num(gui_erp_simulation.sin_fre.String);
+ if isempty(SinoiseFre) || numel(SinoiseFre)~=1 || SinoiseFre<=0
+ msgboxText = ['Create Artificial ERP Waveform> Please define one positive numeric for "frequency" of sinusoidal noise'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ else
+ SinoiseAmp =0;
+ SinoiseFre =10;
+ end
+ if gui_erp_simulation.white_op.Value==1
+ WhiteAmp = str2num(gui_erp_simulation.white_amp.String);
+ if isempty(WhiteAmp) || numel(WhiteAmp)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "amplitude" of white noise'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ else
+ WhiteAmp =0;
+ end
+
+ if gui_erp_simulation.pink_op.Value==1
+ PinkAmp = str2num(gui_erp_simulation.pink_amp.String);
+ if isempty(PinkAmp) || numel(PinkAmp)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "amplitude" of pink noise'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ else
+ PinkAmp = 0;
+ end
+ NewnoiseFlag = gui_erp_simulation.newnoise_op.Value;
+
+ try
+ ALLERP = [];
+ [ERP, ERPCOM] = pop_ERP_simulation(ALLERP,BasFuncName,'EpochStart',EpochStart,'EpochStop',EpochStop,'Srate',Srate,'BasPeakAmp',BasPeakAmp,'MeanLatencyOnset',MeanLatOnset,'SDOffset',SDOffset,...
+ 'ExGauTau',ExGauTau,'SinoiseAmp',SinoiseAmp,'SinoiseFre',SinoiseFre,'WhiteAmp',WhiteAmp,'PinkAmp',PinkAmp,'NewnoiseFlag',NewnoiseFlag,'Saveas', 'off','History', 'gui');
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+
+ Answer = f_ERP_save_single_file(strcat(ERP.erpname),ERP.filename,length(observe_ERPDAT.ALLERP)+1);
+ if isempty(Answer)
+ beep;
+ return;
+ end
+
+ if ~isempty(Answer)
+ ERPName = Answer{1};
+ if ~isempty(ERPName)
+ ERP.erpname = ERPName;
+ end
+ fileName_full = Answer{2};
+ if isempty(fileName_full)
+ ERP.filename = ERP.erpname;
+ elseif ~isempty(fileName_full)
+ [pathstr, file_name, ext] = fileparts(fileName_full);
+ ext = '.erp';
+ if strcmp(pathstr,'')
+ pathstr = cd;
+ end
+ ERP.filename = [file_name,ext];
+ ERP.filepath = pathstr;
+ %%----------save the current sdata as--------------------
+ [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath);
+ [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);
+ end
+ end
+ assignin('base','ALLERPCOM',ALLERPCOM);
+ assignin('base','ERPCOM',ERPCOM);
+ if length(observe_ERPDAT.ALLERP)==1 && strcmpi(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded')
+ observe_ERPDAT.ALLERP = ERP;
+ else
+ observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP;
+ end
+ observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP);
+ observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP);
+ estudioworkingmemory('selectederpstudio',observe_ERPDAT.CURRENTERP);
+ erpworkingmemory('ERP_simulation',1);
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ observe_ERPDAT.Process_messg =2;
+ catch
+ % estudioworkingmemory('selectederpstudio',Selected_ERP_afd);
+ observe_ERPDAT.Process_messg =3;
+ observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1;
+ return;
+ end
+ observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1;
+ end
+
+
+%%-------------------------------------------------------------------------
+%%-----------------Plot ERP for the simulation-----------------------------
+%%-------------------------------------------------------------------------
+ function plot_erp_simulation(~,~)
+
+ MatchFlag = gui_erp_simulation.realerp_check.Value;
+ ALLERP = observe_ERPDAT.ALLERP;
+ ERP = [];
+ ERPArray = [];
+ ChannelArray = [];
+ binArray = [];
+ if MatchFlag==1 && ~isempty(ALLERP)
+ %%check ERPset
+ ERPArray = str2num(gui_erp_simulation.erpsetedit.String);
+ if ~isempty(ERPArray)
+ if numel(ERPArray)~=1
+ ERPArray = ERPArray(1);
+ end
+ if ERPArray>0 && ERPArray <=length(ALLERP)
+ else
+ ERPArray = length(ALLERP);
+ end
+ else
+ ERPArray = length(ALLERP);
+ end
+ gui_erp_simulation.erpsetedit.String= num2str(ERPArray);
+ ERP = ALLERP(ERPArray);
+ %%check channels
+ ChannelArray = str2num(gui_erp_simulation.channeledit.String);
+ if isempty(ChannelArray)
+ ChannelArray =1;
+ else
+ if numel(ChannelArray)~=1
+ ChannelArray = ChannelArray(1);
+ end
+ if ChannelArray>0 && ChannelArray<= ERP.nchan
+ else
+ ChannelArray =1;
+ end
+ end
+ gui_erp_simulation.channeledit.String = num2str(ChannelArray);
+ %%check bins
+ binArray = str2num(gui_erp_simulation.binedit.String);
+ if isempty(binArray)
+ binArray =1;
+ else
+ if numel(binArray)~=1
+ binArray = binArray(1);
+ end
+ if binArray>0 && binArray<=ERP.nbin
+ else
+ binArray =1;
+ end
+ end
+ gui_erp_simulation.binedit.String = num2str(binArray);
+ end
+
+ EpochStart = str2num(gui_erp_simulation.epoch_start.String);
+ EpochStop = str2num(gui_erp_simulation.epoch_stop.String);
+ if gui_erp_simulation.srate.Value
+ srate = str2num(gui_erp_simulation.srateedit.String);
+ if isempty(srate) || numel(srate)~=1
+ msgboxText = ['Create Artificial ERP Waveform>Please define one numeric for sampling rate'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ gui_erp_simulation.srateedit.String = '';
+ return;
+ end
+ if srate<=0
+ msgboxText = ['Create Artificial ERP Waveform>Sampling rate must be a positive numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ gui_erp_simulation.srateedit.String = '';
+ return;
+ end
+ else%% sampling period
+ Speriod = str2num(gui_erp_simulation.srateperiodedit.String);
+ if isempty(Speriod) || numel(Speriod)~=1
+ msgboxText = ['Create Artificial ERP Waveform>Please define one numeric for sampling period'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ gui_erp_simulation.srateperiodedit.String = '';
+ return;
+ end
+ if Speriod<=0
+ msgboxText = ['Create Artificial ERP Waveform>Sampling period must be positive numeric'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ gui_erp_simulation.srateperiodedit.String = '';
+ return;
+ end
+ srate = 1000/Speriod;
+ end
+ if isempty(EpochStart) || numel(EpochStart)~=1
+ msgboxText = ['Create Artificial ERP Waveform>Please define one numeric for epoch start'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if isempty(EpochStop) || numel(EpochStop)~=1
+ msgboxText = ['Create Artificial ERP Waveform>Please define one numeric for epoch stop'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ if EpochStop<=EpochStart
+ msgboxText = ['Create Artificial ERP Waveform> Start time of epoch must be smaller than stop time of epoch'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if 1000/srate>= (EpochStop-EpochStart)
+ msgboxText = ['Create Artificial ERP Waveform> Please sampling period must be much smaller than ',32,num2str(EpochStop-EpochStart)];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+
+ Times = [];
+ if EpochStart>=0
+ count =0;
+ tIndex(1,1) =0;
+ for ii = 1:10000
+ count = count+1000/srate;
+ if count<=EpochStop
+ tIndex(1,ii) = count;
+ else
+ break;
+ end
+ end
+ [xxx, latsamp, latdiffms] = closest(tIndex, [EpochStart,EpochStop]);
+ Times = tIndex(latsamp(1):end);
+ if Times(1)=EpochStart
+ tIndex(1,ii) = count;
+ else
+ break;
+ end
+ end
+ tIndex = sort(tIndex);
+ [xxx, latsamp, latdiffms] = closest(tIndex, [EpochStart,EpochStop]);
+
+ Times = tIndex(1:latsamp(2));
+ if Times(end)> EpochStop
+ Times(end) = [];
+ end
+ elseif EpochStart<0 && EpochStop>0
+ tIndex1(1,1) = 0;
+ count =0;
+ for ii = 1:10000
+ count = count-1000/srate;
+ if count>=EpochStart
+ tIndex1(1,ii+1) = count;
+ else
+ break;
+ end
+ end
+ tIndex2=[];
+ count1 =0;
+ for ii = 1:10000
+ count1 = count1+1000/srate;
+ if count1<=EpochStop
+ tIndex2(1,ii) = count1;
+ else
+ break;
+ end
+ end
+ Times = [sort(tIndex1),tIndex2];
+ end
+ if ~isempty(ERP)
+ Times= ERP.times;
+ end
+ [x1,y1] = find(roundn(Times,-3)==roundn(EpochStart,-3));
+ [x2,y2] = find(roundn(Times,-3)==roundn(EpochStop,-3));
+ if isempty(y1) || isempty(y2)
+ msgboxText = 'Create Artificial ERP Waveform> The exact time periods you have specified cannot be exactly created with the specified sampling rate. We will round to the nearest possible time values when the ERPset is created.';
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ end
+ Desiredsignal = zeros(1,numel(Times));
+ Desirednosizesin = zeros(1,numel(Times));
+ Desirednosizewhite = zeros(1,numel(Times));
+ Desirednosizepink = zeros(1,numel(Times));
+ RealData = nan(1,numel(Times));
+ %%---------------------------Simulated signal------------------------------
+ if gui_erp_simulation.exgua_op.Value ==1
+ Gua_PDF = zeros(1,numel(Times));
+ PeakAmp = str2num(gui_erp_simulation.exgua_peakamp.String);
+ if isempty(PeakAmp) || numel(PeakAmp)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "peak amplitude" of ex-Gaussian function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ Meanamp = str2num(gui_erp_simulation.exgua_mean.String);
+ if isempty(Meanamp) || numel(Meanamp)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "Gaussian mean" of Ex-Gaussian function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ Tau = str2num(gui_erp_simulation.exgua_tau.String);
+ if isempty(Tau) || numel(Tau)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "Tau" of Ex-Gaussian function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+
+ SD = str2num(gui_erp_simulation.exgua_sd.String);
+ if isempty(SD) || numel(SD)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "SD" of Ex-Gaussian function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ SD = SD/100;
+ if Tau~=0
+ Mu = Meanamp/100-Times(1)/100;
+ if Mu<0
+ Mu = Meanamp/100;
+ end
+ if Tau<0
+ Mu = abs((Times(end)/100-Times(1)/100)-Mu);
+ end
+ LegthSig = (Times(end)-Times(1))/100;
+ Sig = 0: LegthSig/numel(Times):LegthSig-LegthSig/numel(Times);
+ Gua_PDF = f_exgauss_pdf(Sig, Mu, SD, abs(Tau));
+ if Tau<0
+ Gua_PDF = fliplr(Gua_PDF);
+ end
+ elseif Tau==0 %%Gaussian signal
+ Times_new = Times/1000;
+ Gua_PDF = f_gaussian(Times_new,abs(PeakAmp),Meanamp/1000,SD/10);
+ end
+ Max = max(abs( Gua_PDF(:)));
+ Gua_PDF = PeakAmp*Gua_PDF./Max;
+ if PeakAmp~=0
+ Desiredsignal = Gua_PDF;
+ end
+ elseif gui_erp_simulation.impulse_op.Value ==1
+ PeakAmp = str2num(gui_erp_simulation.impulse_peakamp.String);
+ if isempty(PeakAmp) || numel(PeakAmp)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "peak amplitude" of impulse function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ Latency = str2num(gui_erp_simulation.impulse_latency.String);
+ if isempty(Latency) || numel(Latency)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "latency" of impulse function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if LatencyTimes(end)
+ Latency=Times(end);
+ end
+ [xxx, latsamp, latdiffms] = closest(Times, Latency);
+ Desiredsignal(latsamp) = PeakAmp;
+
+ elseif gui_erp_simulation.square_op.Value ==1
+ PeakAmp = str2num(gui_erp_simulation.square_peakamp.String);
+ if isempty(PeakAmp) || numel(PeakAmp)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "peak amplitude" of Boxcar function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ onsetLat = str2num(gui_erp_simulation.square_onset.String);
+ if isempty(onsetLat) || numel(onsetLat)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "onset" of Boxcar function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ offsetLat = str2num(gui_erp_simulation.square_offset.String);
+ if isempty(offsetLat) || numel(offsetLat)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "offset" of Boxcar function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ if offsetLat< onsetLat
+ msgboxText = ['Create Artificial ERP Waveform> Please "offset" should be larger than "onset" of Boxcar function'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ [xxx, latsamp, latdiffms] = closest(Times, [onsetLat,offsetLat]);
+ Desiredsignal(latsamp(1):latsamp(2)) = PeakAmp;
+ end
+
+ %%---------------------------Noise signal----------------------------------
+ % SimulationSeed = erpworkingmemory('SimulationSeed');
+ SimulationSeed= gui_erp_simulation.SimulationSeed ;
+ try
+ SimulationSeed_Type = SimulationSeed.Type;
+ SimulationSeed_seed=SimulationSeed.Seed;
+ catch
+ SimulationSeed_Type = 'twister';
+ SimulationSeed_seed = 1;
+ end
+ %phase for sin noise
+ % SimulationPhase = erpworkingmemory('SimulationPhase');
+ SimulationPhase = gui_erp_simulation.SimulationPhase;
+ if isempty(SimulationPhase) || ~isnumeric(SimulationPhase)
+ SimulationPhase = 0;
+ end
+ if numel(SimulationPhase)~=1
+ SimulationPhase = SimulationPhase(1);
+ end
+ if SimulationPhase<0 || SimulationPhase>1
+ SimulationPhase = 0;
+ end
+
+
+ if gui_erp_simulation.sin_op.Value==1
+ PeakAmp = str2num(gui_erp_simulation.sin_amp.String);
+ if isempty(PeakAmp) || numel(PeakAmp)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "amplitude" of sinusoidal noise'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ FreHz = str2num(gui_erp_simulation.sin_fre.String);
+
+ if isempty(FreHz) || numel(FreHz)~=1 || FreHz<=0
+ msgboxText = ['Create Artificial ERP Waveform> Please define one positive numeric for "frequency" of sinusoidal noise'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ X = Times/1000;
+ Desirednosizesin = PeakAmp*sin(2*FreHz*pi*(X)+2*pi*SimulationPhase);
+
+ end
+ if gui_erp_simulation.white_op.Value==1
+ PeakAmp = str2num(gui_erp_simulation.white_amp.String);
+ if isempty(PeakAmp) || numel(PeakAmp)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "amplitude" of white noise'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ try
+ rng(SimulationSeed_seed,SimulationSeed_Type);
+ catch
+ rng(1,'twister');
+ end
+ Desirednosizewhite = randn(1,numel(Times));%%white noise
+
+ Desirednosizewhite = PeakAmp*Desirednosizewhite./max(abs(Desirednosizewhite(:)));
+ end
+
+ if gui_erp_simulation.pink_op.Value==1
+ PeakAmp = str2num(gui_erp_simulation.pink_amp.String);
+ if isempty(PeakAmp) || numel(PeakAmp)~=1
+ msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "amplitude" of pink noise'];
+ fprintf(2,['\n Warning: ',msgboxText,'.\n']);
+ erpworkingmemory('f_ERP_proces_messg',msgboxText);
+ observe_ERPDAT.Process_messg =4;
+ return;
+ end
+ try
+ rng(SimulationSeed_seed,SimulationSeed_Type);
+ catch
+ rng(1,'twister');
+ end
+
+ Desirednosizepink = f_pinknoise(numel(Times));
+
+ Desirednosizepink = reshape(Desirednosizepink,1,numel(Desirednosizepink));
+ Desirednosizepink = PeakAmp*Desirednosizepink./max(abs(Desirednosizepink(:)));
+
+ end
+ Sig = Desirednosizesin+Desiredsignal+Desirednosizepink+Desirednosizewhite;
+
+ if ~isempty(ERP) && ~isempty(ChannelArray) && ~isempty(binArray)
+ try
+ % hold(handles.axes1,'on');
+ RealData = squeeze(ERP.bindata(ChannelArray,:,binArray));
+ plot(gui_erp_simulation.plot_erp,Times,[Sig;RealData],'linewidth',1.5);
+ % legend(gui_erp_simulation.plot_erp,{'Simulated data',['Real data at',32,ERP.chanlocs(ChannelArray).labels]},'FontSize',FonsizeDefault);
+ % legend(gui_erp_simulation.plot_erp,'boxoff');
+
+ catch
+ end
+ else
+ plot(gui_erp_simulation.plot_erp,Times,Sig,'k','linewidth',1.5);
+ % legend(gui_erp_simulation.plot_erp,{'Simulated data'},'FontSize',FonsizeDefault);
+ % legend(gui_erp_simulation.plot_erp,'boxoff');
+ end
+ gui_erp_simulation.plot_erp.FontSize =12;
+ xlim(gui_erp_simulation.plot_erp,[Times(1),Times(end)]);
+ end
+
+
+%%-------enable the panel for real data------------------------------------
+ function Count_currentERPChanged(~,~)
+ if length(observe_ERPDAT.ALLERP)==1 && strcmpi(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded')
+ gui_erp_simulation.realerp_check.Value =0;
+ EnableFlag = 'off';
+ gui_erp_simulation.realerp_check.Enable = EnableFlag;
+ gui_erp_simulation.erpsetedit.Enable = EnableFlag;
+ gui_erp_simulation.erpsetpopup.Enable = EnableFlag;
+ gui_erp_simulation.channeledit.Enable = EnableFlag;
+ gui_erp_simulation.channelpopup.Enable = EnableFlag;
+ gui_erp_simulation.binedit.Enable = EnableFlag;
+ gui_erp_simulation.binpopup.Enable = EnableFlag;
+ else
+ gui_erp_simulation.realerp_check.Enable = 'on';
+ if gui_erp_simulation.realerp_check.Value==1
+ EnableFlag = 'on';
+ else
+ EnableFlag = 'off';
+ end
+ gui_erp_simulation.erpsetedit.Enable = EnableFlag;
+ gui_erp_simulation.erpsetpopup.Enable = EnableFlag;
+ gui_erp_simulation.channeledit.Enable = EnableFlag;
+ gui_erp_simulation.channelpopup.Enable = EnableFlag;
+ gui_erp_simulation.binedit.Enable = EnableFlag;
+ gui_erp_simulation.binpopup.Enable = EnableFlag;
+ if gui_erp_simulation.realerp_check.Value==1
+ EnableFlags = 'off';
+ else
+ EnableFlags = 'on';
+ end
+ gui_erp_simulation.epoch_start.Enable = EnableFlags;
+ gui_erp_simulation.epoch_stop.Enable = EnableFlags;
+ gui_erp_simulation.srateedit.Enable = EnableFlags;
+ gui_erp_simulation.srateperiodedit.Enable = EnableFlags;
+ gui_erp_simulation.srate.Enable = EnableFlags;
+ gui_erp_simulation.srateperiod.Enable = EnableFlags;
+ if strcmpi(EnableFlags,'on')
+ if gui_erp_simulation.srate.Value ==1
+ gui_erp_simulation.srateedit.Enable = 'on';
+ gui_erp_simulation.srateperiod.Value =0;
+ gui_erp_simulation.srateperiodedit.Enable = 'off';
+ else
+ gui_erp_simulation.srate.Value=0;
+ gui_erp_simulation.srateedit.Enable = 'off';
+ gui_erp_simulation.srateperiod.Value =1;
+ gui_erp_simulation.srateperiodedit.Enable = 'on';
+ end
+ end
+ end
+ plot_erp_simulation();
+ end
+
+end
+%Progem end: ERP simulation
\ No newline at end of file
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_spectral_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_spectral_GUI.m
new file mode 100755
index 00000000..db63c73b
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_spectral_GUI.m
@@ -0,0 +1,892 @@
+%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com
+%Center for Mind and Brain
+%University of California, Davis
+%Davis, CA, USA
+%Feb. 2022
+
+% ERPLAB Studio
+
+function varargout = f_ERP_spectral_GUI(varargin)
+
+% global gui_erp_spectral;
+global observe_ERPDAT;
+% addlistener(observe_ERPDAT,'ALLERP_change',@erpschange);
+% addlistener(observe_ERPDAT,'ERP_change',@drawui_CB);
+% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange);
+addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged);
+
+% erp_m_t_p = S_OUT.geterpvalues;
+
+defaulpar = erpworkingmemory('f_ERP_spectral');
+defaulpar{1} = 0;defaulpar{2} = [];defaulpar{3} = [];defaulpar{4} = [];defaulpar{5} = [];
+defaulpar{6} = [];defaulpar{7} = [];
+erpworkingmemory('f_ERP_spectral',defaulpar);
+%%---------------------------gui-------------------------------------------
+try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+catch
+ ColorB_def = [0.95 0.95 0.95];
+end
+if nargin == 0
+ fig_title = figure(); % Parent figure
+ ERP_filtering_box = uiextras.BoxPanel('Parent', fig_title, 'Title', 'Spectral Analysis', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel
+elseif nargin == 1
+ ERP_filtering_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Spectral Analysis', 'Padding', 5,'BackgroundColor',ColorB_def);
+else
+ ERP_filtering_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Spectral Analysis', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def);
+end
+
+
+gui_erp_spectral = struct();
+
+try
+ FonsizeDefault = varargin{2};
+catch
+ FonsizeDefault = [];
+end
+if isempty(FonsizeDefault)
+ FonsizeDefault = f_get_default_fontsize();
+end
+erp_spectral_gui(FonsizeDefault);
+
+varargout{1} = ERP_filtering_box;
+%%********************Draw the GUI for ERP measurement tool*****************
+ function erp_spectral_gui(FonsizeDefault)
+ try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+ catch
+ ColorB_def = [0.95 0.95 0.95];
+ end
+
+ if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded')
+ Enable_label = 'off';
+ else
+ Enable_label = 'on';
+ end
+
+
+ gui_erp_spectral.spectral = uiextras.VBox('Parent',ERP_filtering_box,'Spacing',1,'BackgroundColor',ColorB_def);
+
+ gui_erp_spectral.amplitude_option = uiextras.HBox('Parent', gui_erp_spectral.spectral,'Spacing',1,'BackgroundColor',ColorB_def);
+
+ %%amplitude and phase
+ gui_erp_spectral.dispaly_title = uicontrol('Style','text','Parent', gui_erp_spectral.amplitude_option,...
+ 'String','Display in:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ set(gui_erp_spectral.dispaly_title,'HorizontalAlignment','left');
+ gui_erp_spectral.amplitude = uicontrol('Style', 'radiobutton','Parent', gui_erp_spectral.amplitude_option,'String','Amplitude',...
+ 'callback',@spectral_amplitude,'Value',1,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ gui_erp_spectral.phase = uicontrol('Style', 'radiobutton','Parent', gui_erp_spectral.amplitude_option,...
+ 'String','Phase','callback',@spectral_phase,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ set( gui_erp_spectral.amplitude_option, 'Sizes', [80 100 100]);
+ %%%power and dB
+ gui_erp_spectral.pow_db = uiextras.HBox('Parent', gui_erp_spectral.spectral,'Spacing',1,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_spectral.pow_db);
+ gui_erp_spectral.power = uicontrol('Style', 'radiobutton','Parent', gui_erp_spectral.pow_db ,...
+ 'String','Power','callback',@spectral_power,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ gui_erp_spectral.db = uicontrol('Style', 'radiobutton','Parent', gui_erp_spectral.pow_db ,...
+ 'String','dB','callback',@spectral_db,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ set( gui_erp_spectral.pow_db , 'Sizes', [80 100 100]);
+ %%%
+
+ gui_erp_spectral.hamwin_title_option = uiextras.HBox('Parent', gui_erp_spectral.spectral,'Spacing',1,'BackgroundColor',ColorB_def);
+ gui_erp_spectral.hamwin_title = uicontrol('Style','text','Parent', gui_erp_spectral.hamwin_title_option,'String','Hamming window:','FontSize',FonsizeDefault);
+ set( gui_erp_spectral.hamwin_title,'HorizontalAlignment','left','BackgroundColor',ColorB_def);
+ gui_erp_spectral.hamwin_on = uicontrol('Style', 'radiobutton','Parent', gui_erp_spectral.hamwin_title_option,...
+ 'String','On','callback',@spectral_hamwin_on,'Value',1,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ gui_erp_spectral.hamwin_off = uicontrol('Style', 'radiobutton','Parent', gui_erp_spectral.hamwin_title_option,...
+ 'String','Off','callback',@spectral_hamwin_off,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ uiextras.Empty('Parent', gui_erp_spectral.hamwin_title_option,'BackgroundColor',ColorB_def);
+ set( gui_erp_spectral.hamwin_title_option, 'Sizes', [120 60 60 40]);
+
+
+ gui_erp_spectral.other_option = uiextras.HBox('Parent',gui_erp_spectral.spectral,'Spacing',1,'BackgroundColor',ColorB_def);
+ gui_erp_spectral.plot = uicontrol('Style','pushbutton','Parent',gui_erp_spectral.other_option,...
+ 'String','Plot','callback',@spectral_plot,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ gui_erp_spectral.save = uicontrol('Style','pushbutton','Parent',gui_erp_spectral.other_option,...
+ 'String','Save','callback',@spectral_save,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ gui_erp_spectral.advanced = uicontrol('Parent',gui_erp_spectral.other_option,'Style','pushbutton',...
+ 'String','Advanced','callback',@spectral_advanced,'Enable',Enable_label,'FontSize',FonsizeDefault);
+
+ set(gui_erp_spectral.spectral, 'Sizes', [20 20 20 30]);
+
+ end
+%%****************************************************************************************************************************************
+%%******************* Subfunctions ***************************************************************************************************
+%%****************************************************************************************************************************************
+
+%%--------------------------------setting for amplitude------------------
+ function spectral_amplitude(source,~)
+ gui_erp_spectral.amplitude.Value =1;
+ gui_erp_spectral.phase.Value = 0;
+ gui_erp_spectral.power.Value = 0;
+ gui_erp_spectral.db.Value =0;
+ end
+
+%%--------------------------Setting for phase-----------------------------
+ function spectral_phase(source,~)
+ gui_erp_spectral.phase.Value = 1;
+ gui_erp_spectral.amplitude.Value =0;
+ gui_erp_spectral.power.Value = 0;
+ gui_erp_spectral.db.Value =0;
+ end
+
+%%--------------------Setting for power------------------------------------
+ function spectral_power(~,~)
+ gui_erp_spectral.phase.Value = 0;
+ gui_erp_spectral.amplitude.Value =0;
+ gui_erp_spectral.power.Value =1;
+ gui_erp_spectral.db.Value =0;
+ end
+
+%%--------------------Setting for dB------------------------------------
+ function spectral_db(~,~)
+ gui_erp_spectral.phase.Value = 0;
+ gui_erp_spectral.amplitude.Value =0;
+ gui_erp_spectral.power.Value =0;
+ gui_erp_spectral.db.Value =1;
+ end
+
+
+%%-------------------------Setting for hamming window:on-------------------
+ function spectral_hamwin_on(~,~)
+ gui_erp_spectral.hamwin_on.Value = 1;
+ gui_erp_spectral.hamwin_off.Value = 0;
+ end
+
+%%-------------------------Setting for hamming window:off-------------------
+ function spectral_hamwin_off(~,~)
+ gui_erp_spectral.hamwin_on.Value = 0;
+ gui_erp_spectral.hamwin_off.Value = 1;
+ end
+
+
+
+%%--------------------------Setting for plot-------------------------------
+ function spectral_plot(~,~)
+ if gui_erp_spectral.hamwin_on.Value
+ iswindowed =1;
+ else
+ iswindowed = 0;
+ end
+
+ Selected_erpset = estudioworkingmemory('selectederpstudio');
+ if isempty(Selected_erpset)
+ Selected_erpset = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ estudioworkingmemory('selectederpstudio',Selected_erpset);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ checked_ERPset_Index_bin_chan =S_binchan.checked_ERPset_Index;
+
+
+ defaulpar1 = erpworkingmemory('f_ERP_spectral');
+ BinArray = [];
+ ChanArray = [];
+ FreqRange = [];
+
+ if checked_ERPset_Index_bin_chan(1) ==1
+ BinArray = [];
+ elseif checked_ERPset_Index_bin_chan(2) ==2
+ ChanArray = [];
+ end
+
+ try
+
+ BinArray = S_binchan.bins{1};
+ ChanArray = S_binchan.elecs_shown{1};
+ catch
+ BinArray = [];
+ ChanArray = [];
+ end
+
+
+ %%Plot the spectrum for the selected ERPset
+ % try
+ for Numoferpset = 1:numel(Selected_erpset)
+ %%%
+ ERP_curret_s = observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset));
+ if strcmp(ERP_curret_s.datatype,'ERP')
+ ERP_FFT = f_getFFTfromERP(ERP_curret_s,iswindowed);
+ elseif strcmp(ERP_curret_s.datatype,'EFFT')
+ ERP_FFT = ERP_curret_s;
+ end
+
+ ColumnNum = 1;
+ if isempty(BinArray)
+ BinArray = [1:ERP_curret_s.nbin];
+ end
+
+ if isempty(ChanArray)
+ ChanArray = [1:ERP_curret_s.nchan];
+ end
+
+ if max(BinArray(:))> ERP_FFT.nbin
+ BinArray = [1:ERP_FFT.nbin];
+ end
+
+ if max(ChanArray(:))> ERP_FFT.nchan
+ ChanArray = [1:ERP_FFT.nchan];
+ end
+ RowNum = ceil(numel(ChanArray)/ColumnNum);
+
+ if gui_erp_spectral.amplitude.Value
+ ERP_FFT.bindata = abs(ERP_FFT.bindata);
+ figure_name = ['Spectral analysis: Amplitude for ',32,ERP_FFT.erpname];
+ elseif gui_erp_spectral.phase.Value
+ ERP_FFT.bindata = angle(ERP_FFT.bindata);
+ figure_name = ['Spectral analysis: Phase for ',32,ERP_FFT.erpname];
+ elseif gui_erp_spectral.power.Value
+ ERP_FFT.bindata = abs(ERP_FFT.bindata).^2;
+ figure_name = ['Spectral analysis: Power for ',32,ERP_FFT.erpname];
+ elseif gui_erp_spectral.db.Value
+ ERP_FFT.bindata = 20*log10(abs(ERP_FFT.bindata));
+ figure_name = ['Spectral analysis: dB for ',32,ERP_FFT.erpname];
+ end
+
+ fig = figure('Name',figure_name);
+ set(fig,'outerposition',get(0,'screensize'));
+
+ line_colors = erpworkingmemory('PWColor');
+ if size(line_colors,1)~= ERP_FFT.nbin
+ if ERP_FFT.nbin> size(line_colors,1)
+ line_colors = get_colors(ERP_FFT.nbin);
+ else
+ line_colors = line_colors(1:ERP_FFT.nbin,:,:);
+ end
+ end
+
+ if isempty(line_colors)
+ line_colors = get_colors(ERP_FFT.nbin);
+ end
+ FreqRange=[ERP_FFT.times(1), ERP_FFT.times(end)];
+ FreqTick = default_time_ticks(ERP_FFT, FreqRange);
+ FreqTick = str2num(FreqTick{1});
+ ERP_FFT.bindata = ERP_FFT.bindata(ChanArray,:,BinArray);
+ ERP_FFT.nbin = numel(BinArray);
+ ERP_FFT.nchan = numel(ChanArray);
+ ERP_FFT.chanlocs = ERP_FFT.chanlocs(ChanArray);
+ ERP_FFT.bindescr = ERP_FFT.bindescr(BinArray);
+
+ pbox = f_getrow_columnautowaveplot(ChanArray);
+ try
+ RowNum = pbox(1);
+ ColumnNum = pbox(2);
+ catch
+ RowNum = numel(ChanArray);
+ ColumnNum = 1;
+ end
+
+ count = 0;
+ for Numofcolumn = 1:ColumnNum
+ for Numofrow = 1: RowNum
+ count = count+1;
+ if ColumnNum*RowNum<5
+ pause(1);
+ end
+ if count>ERP_FFT.nchan
+ break;
+ end
+ p_ax = subplot(RowNum,ColumnNum,count);
+ set(gca,'fontsize',14);
+ hold on;
+ temp = squeeze(ERP_FFT.bindata);
+ for Numofplot = 1:ERP_FFT.nbin
+ h_p(Numofplot) = plot(p_ax,ERP_FFT.times,squeeze(ERP_FFT.bindata(count,:,Numofplot)),'LineWidth',1,'Color',line_colors(Numofplot,:,:));
+ end
+ axis(p_ax,[floor(ERP_FFT.times(1)),ceil(ERP_FFT.times(end)), 1.1*min(temp(:)) 1.1*max(temp(:))]);
+ xticks(p_ax,FreqTick);
+ if count == 1
+ title(p_ax,[ERP_FFT.chanlocs(count).labels],'FontSize',14); %#ok<*NODEF>
+ legend(p_ax,ERP_FFT.bindescr,'FontSize',14);
+ legend(p_ax,'boxoff');
+ else
+ title(p_ax,ERP_FFT.chanlocs(count).labels,'FontSize',14);
+ end
+ xlabel(p_ax,'Frequency/Hz','FontSize',14);
+ if gui_erp_spectral.phase.Value
+ ylabel(p_ax,'Angle/degree','FontSize',14);
+ elseif gui_erp_spectral.amplitude.Value
+ ylabel(p_ax,'Amplitude/\muV','FontSize',14);
+ elseif gui_erp_spectral.power.Value
+ ylabel(p_ax,'Power/\muV^2','FontSize',14);
+ elseif gui_erp_spectral.db.Value
+ ylabel(p_ax,'Decibels/dB','FontSize',14);
+ end
+ for NUmoflabel = 1:length(ERP_FFT.times)
+ X_label{NUmoflabel} = [];
+ end
+ set(gca,'TickDir','out');
+ set(gca,'LineWidth',2);
+ end
+ end
+
+ end%%end loop for ERPSET
+
+ end
+
+
+%%-----------------Setting for save option---------------------------------
+ function spectral_save(~,~)
+ pathName = erpworkingmemory('ERP_save_folder');
+ if isempty(pathName)
+ pathName = cd;
+ end
+
+ if gui_erp_spectral.hamwin_on.Value
+ iswindowed =1;
+ else
+ iswindowed = 0;
+ end
+ Selected_erpset = estudioworkingmemory('selectederpstudio');
+ if isempty(Selected_erpset)
+ Selected_erpset = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ estudioworkingmemory('selectederpstudio',Selected_erpset);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ checked_ERPset_Index_bin_chan =S_binchan.checked_ERPset_Index;
+
+
+ BinArray = [];
+ ChanArray = [];
+ FreqRange = [];
+
+ if checked_ERPset_Index_bin_chan(1) ==1
+ BinArray = [];
+ elseif checked_ERPset_Index_bin_chan(2) ==2
+ ChanArray = [];
+ end
+
+ try
+ BinArray = S_binchan.bins{1};
+ ChanArray = S_binchan.elecs_shown{1};
+ catch
+ BinArray = [];
+ ChanArray = [];
+ end
+ try
+ ALLERPCOM = evalin('base','ALLERPCOM');
+ catch
+ ALLERPCOM = [];
+ assignin('base','ALLERPCOM',ALLERPCOM);
+ end
+ %%Plot the spectrum for the selected ERPset
+ %-----------Setting for import-------------------------------------
+ try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+ catch
+ ColorB_def = [0.7020 0.77 0.85];
+ end
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',ColorB_def);
+ [ind,tf] = listdlg('ListString',{'".mat"','".csv"'},'SelectionMode','single','PromptString','Please select a type to export to...','Name','Export Spectrum for Selected ERPset to','OKString','Ok');
+ set(0,'DefaultUicontrolBackgroundColor',[1 1 1]);
+ if isempty(ind)
+ beep;
+ disp(['User selected cancel']);
+ return;
+ end
+ for Numoferpset = 1:numel(Selected_erpset)
+ %%%
+ ERP_curret_s = observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset));
+ if strcmp(ERP_curret_s.datatype,'ERP')
+ ERP_FFT = f_getFFTfromERP(ERP_curret_s,iswindowed);
+ else
+ ERP_FFT = ERP_curret_s;
+ end
+ if isempty(BinArray)
+ BinArray = [1:ERP_curret_s.nbin];
+ end
+
+ if isempty(ChanArray)
+ ChanArray = [1:ERP_curret_s.nchan];
+ end
+
+ if max(BinArray(:))> ERP_FFT.nbin
+ BinArray = [1:ERP_FFT.nbin];
+ end
+
+ if max(ChanArray(:))> ERP_FFT.nchan
+ ChanArray = [1:ERP_FFT.nchan];
+ end
+
+ if isempty(FreqRange) || FreqRange(2)>ERP_FFT.times(end)
+ FreqRange=[ERP_FFT.times(1), ERP_FFT.times(end)];
+ end
+ [xxx, latsamp, latdiffms] = closest(ERP_FFT.times, FreqRange);
+ tmin = latsamp(1);
+ tmax = latsamp(2);
+ ERP_FFT.bindata = ERP_FFT.bindata(ChanArray,tmin:tmax,BinArray);
+ ERP_FFT.nbin = numel(BinArray);
+ ERP_FFT.nchan = numel(ChanArray);
+ ERP_FFT.chanlocs = ERP_FFT.chanlocs(ChanArray);
+ ERP_FFT.bindescr = ERP_FFT.bindescr(BinArray);
+ ERP_FFT.times = ERP_FFT.times(tmin:tmax);
+
+ if strcmp(ERP_curret_s.datatype,'ERP')
+ if gui_erp_spectral.amplitude.Value
+ ERP_FFT.bindata = abs(ERP_FFT.bindata);
+ figure_name = [ERP_FFT.erpname,'_Spectrum_Amplitude'];
+ elseif gui_erp_spectral.phase.Value
+ ERP_FFT.bindata = angle(ERP_FFT.bindata);
+ figure_name = [ERP_FFT.erpname,'_Spectrum_Phase'];
+ elseif gui_erp_spectral.power.Value
+ ERP_FFT.bindata = abs(ERP_FFT.bindata).^2;
+ figure_name = [ERP_FFT.erpname,'_Spectrum_Power'];
+ elseif gui_erp_spectral.db.Value
+ ERP_FFT.bindata = 20*log10(abs(ERP_FFT.bindata));
+ figure_name = [ERP_FFT.erpname,'_Spectrum_ dB'];
+ end
+ else
+ if gui_erp_spectral.amplitude.Value
+ figure_name = [ERP_FFT.erpname,'_Spectrum_amplitude'];
+ elseif gui_erp_spectral.phase.Value
+ figure_name = [ERP_FFT.erpname,'_Spectrum_phase'];
+ elseif gui_erp_spectral.power.Value
+ figure_name = strcat(ERP_FFT.erpname,'Spectrum_Power');
+
+ elseif gui_erp_spectral.db.Value
+ figure_name = strcat(ERP_FFT.erpname,'_Spectrum_dB');
+ end
+ end
+
+ if ind==1
+
+ [filenamei, pathname] = uiputfile({'*.mat';'*.*'},['Save',32,'"',ERP_FFT.erpname,'"', 32,'as'],fullfile(pathName,figure_name));
+ if isequal(filenamei,0)
+ disp('User selected Cancel')
+ return
+ else
+ [pathx, filename, ext] = fileparts(filenamei);
+ ext = '.mat';
+ filename = [filename ext];
+ end
+
+ if strcmpi(ext,'.mat')
+ [ERP_FFT, issave, ERPCOM] = pop_savemyerp(ERP_FFT, 'erpname', ERP_FFT.erpname, 'filename', filename, 'filepath',pathname);
+ [~, ALLERPCOM] = erphistory(ERP_FFT, ALLERPCOM, ERPCOM);
+ end
+
+ %%save as '.csv'
+ elseif ind==2
+ def = erpworkingmemory('f_export2csvGUI');
+ if isempty(def)
+ def = {1, 1, 1, 3, ''};
+ end
+ def{5} = fullfile(pathName,ERP_FFT.filename);
+ answer_export = f_export2csvGUI(ERP_FFT,def);
+ erpworkingmemory('f_export2csvGUI',answer_export);
+ if isempty(answer_export)
+ beep;
+ disp('User selected cancel!!!');
+ return;
+ end
+ binArray = [1:ERP_FFT.nbin];
+ decimal_num = answer_export{4};
+ istime =answer_export{1} ;
+ electrodes=answer_export{2} ;
+ transpose=answer_export{3};
+ filenamei = answer_export{5};
+ [pathx, filename, ext] = fileparts(filenamei);
+ ext = '.csv';
+ if isempty(pathx)
+ pathx =cd;
+ end
+ filename = [filename ext];
+ mkdir([pathx,filesep]);
+ try
+ export2csv_spectranl_analysis(ERP_FFT,fullfile(pathx,filename), binArray,istime, electrodes,transpose, decimal_num);
+ catch
+ beep;
+ disp('Fail to save selected ERPset as ".csv"!!!');
+ return;
+ end
+ end
+
+ end
+ end
+
+
+%%-------------------Setting for advance option---------------------------
+ function spectral_advanced(~,~)
+ pathName_folder = erpworkingmemory('ERP_save_folder');
+ if isempty(pathName_folder)
+ pathName_folder = cd;
+ end
+
+ if gui_erp_spectral.hamwin_on.Value
+ iswindowed =1;
+ else
+ iswindowed = 0;
+ end
+
+ try
+ def = erpworkingmemory('f_spectral_analysis_adavance');
+ catch
+ def = {1,[], [], [1 16], 1, 1,1,0};
+ end
+ if isempty(def)
+ def = {1,[], [], [1 16], 1, 1,1,0};
+
+ end
+ try
+ ALLERPCOM = evalin('base','ALLERPCOM');
+ catch
+ ALLERPCOM = [];
+ assignin('base','ALLERPCOM',ALLERPCOM);
+ end
+
+ Selected_erpset = estudioworkingmemory('selectederpstudio');
+ if isempty(Selected_erpset)
+ Selected_erpset = observe_ERPDAT.CURRENTERP;
+ S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset);
+ estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot);
+ estudioworkingmemory('selectederpstudio',Selected_erpset);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ checked_ERPset_Index_bin_chan =S_binchan.checked_ERPset_Index;
+
+ try
+ BinArray = S_binchan.bins{1};
+ ChanArray = S_binchan.elecs_shown{1};
+ catch
+ BinArray = [];
+ ChanArray = [];
+ end
+
+ def{2} = BinArray;
+ def{3} = ChanArray;
+
+ ERP_d =f_getFFTfromERP(observe_ERPDAT.ERP,iswindowed);
+
+
+ defaulpar1 = f_spectral_analysis_advance(ERP_d,def);
+ if isempty(defaulpar1)
+ beep;
+ disp('User selected cancel!!!');
+ return;
+ end
+ erpworkingmemory('f_spectral_analysis_adavance',defaulpar1);
+
+
+ BinArray = defaulpar1{2};
+ ChanArray = defaulpar1{3};
+ if checked_ERPset_Index_bin_chan(1)==1
+ BinArray = [];
+ end
+
+ if checked_ERPset_Index_bin_chan(2) ==2
+ ChanArray = [];
+ end
+
+ FreqRange = defaulpar1{4};
+ FreqTick = defaulpar1{5};
+ RowNum = defaulpar1{6};
+ ColumnNum = defaulpar1{7};
+ Save_label = defaulpar1{8};
+
+ if Save_label
+ try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+ catch
+ ColorB_def = [0.7020 0.77 0.85];
+ end
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',ColorB_def);
+ [ind,tf] = listdlg('ListString',{'".mat"','".csv"'},'SelectionMode','single','PromptString','Please select a type to export to...','Name','Export Spctrum for Selected ERPset to','OKString','Ok');
+ set(0,'DefaultUicontrolBackgroundColor',[1 1 1]);
+
+ if isempty(ind)
+ beep;
+ disp(['User selected cancel']);
+ return;
+ end
+ end
+
+ %%Plot the spectrum for the selected ERPset
+ % Loop start for the selected ERPsets try
+ for Numoferpset = 1:numel(Selected_erpset)
+ %%%
+ ERP_curret_s = observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset));
+ if strcmp(ERP_curret_s.datatype,'ERP')
+ ERP_FFT = f_getFFTfromERP(ERP_curret_s,iswindowed);
+ elseif strcmp(ERP_curret_s.datatype,'EFFT')
+ ERP_FFT = ERP_curret_s;
+ else
+ disp(['Please selected ERPsets']);
+ return;
+ end
+ if isempty(ColumnNum)
+ ColumnNum = 1;
+ end
+
+ if isempty(ChanArray)
+ ChanArray = [1:ERP_curret_s.nchan];
+ end
+
+ if isempty(RowNum)
+ RowNum = ceil(numel(ChanArray)/ColumnNum);
+ end
+ if isempty(BinArray)
+ BinArray = [1:ERP_curret_s.nbin];
+ end
+
+ if max(BinArray(:))> ERP_FFT.nbin
+ BinArray = [1:ERP_FFT.nbin];
+ end
+
+ if max(ChanArray(:))> ERP_FFT.nchan
+ ChanArray = [1:ERP_FFT.nchan];
+ end
+
+ if isempty(FreqRange) || FreqRange(2)>ERP_FFT.times(end)
+ FreqRange=[ERP_FFT.times(1), ERP_FFT.times(end)];
+ FreqTick = default_time_ticks(ERP_FFT, FreqRange);
+ FreqTick = str2num(FreqTick{1});
+ end
+ if isempty(FreqTick)
+ FreqTick = default_time_ticks(ERP_FFT, FreqRange);
+ FreqTick = str2num(FreqTick{1});
+ end
+
+ [xxx, latsamp, latdiffms] = closest(ERP_FFT.times, FreqRange);
+ tmin = latsamp(1);
+ tmax = latsamp(2);
+ ERP_FFT.bindata = ERP_FFT.bindata(ChanArray,tmin:tmax,BinArray);
+ ERP_FFT.nbin = numel(BinArray);
+ ERP_FFT.nchan = numel(ChanArray);
+ ERP_FFT.chanlocs = ERP_FFT.chanlocs(ChanArray);
+ ERP_FFT.bindescr = ERP_FFT.bindescr(BinArray);
+ ERP_FFT.times = ERP_FFT.times(tmin:tmax);
+ ERP_FFT.xmin = ERP_FFT.times(1);
+ ERP_FFT.xmax = ERP_FFT.times(end);
+ ERP_FFT.pnts = numel(ERP_FFT.times);
+ if strcmp(ERP_curret_s.datatype,'ERP')
+ if gui_erp_spectral.amplitude.Value
+ ERP_FFT.bindata = abs(ERP_FFT.bindata);
+ figure_name = ['Spectral analysis: Amplitude for ',32,ERP_FFT.erpname];
+ elseif gui_erp_spectral.phase.Value
+ ERP_FFT.bindata = angle(ERP_FFT.bindata);
+ figure_name = ['Spectral analysis: Phase for ',32,ERP_FFT.erpname];
+ elseif gui_erp_spectral.power.Value
+ ERP_FFT.bindata = abs(ERP_FFT.bindata).^2;
+ figure_name = ['Spectral analysis: Power for ',32,ERP_FFT.erpname];
+ elseif gui_erp_spectral.db.Value
+ ERP_FFT.bindata = 20*log10(abs(ERP_FFT.bindata));
+ figure_name = ['Spectral analysis: dB for ',32,ERP_FFT.erpname];
+ end
+ else
+ if gui_erp_spectral.amplitude.Value
+ figure_name = [ERP_FFT.erpname,'_Spectrum_amplitude'];
+ elseif gui_erp_spectral.phase.Value
+ figure_name = [ERP_FFT.erpname,'_Spectrum_phase'];
+ elseif gui_erp_spectral.power.Value
+ figure_name = ['Spectral analysis: Power for ',32,ERP_FFT.erpname];
+
+ elseif gui_erp_spectral.db.Value
+ figure_name = ['Spectral analysis: dB for ',32,ERP_FFT.erpname];
+ end
+ end
+
+ if ~Save_label
+ fig = figure('Name',figure_name);
+ set(fig,'outerposition',get(0,'screensize'));
+
+ line_colors = erpworkingmemory('PWColor');
+ if size(line_colors,1)~= ERP_FFT.nbin
+ if ERP_FFT.nbin> size(line_colors,1)
+ line_colors = get_colors(ERP_FFT.nbin);
+ else
+ line_colors = line_colors(1:ERP_FFT.nbin,:,:);
+ end
+ end
+
+ if isempty(line_colors)
+ line_colors = get_colors(ERP_FFT.nbin);
+ end
+
+ count = 0;
+ for Numofcolumn = 1:ColumnNum
+ for Numofrow = 1: RowNum
+ count = count+1;
+ % waitbar(count/(ColumnNum*RowNum),Hw);
+ if ColumnNum*RowNum<5
+ pause(1);
+ end
+ if count>ERP_FFT.nchan
+ break;
+ end
+ p_ax = subplot(RowNum,ColumnNum,count);
+ set(gca,'fontsize',14);
+ hold on;
+ temp = squeeze(ERP_FFT.bindata(:,:,:));
+ for Numofplot = 1:ERP_FFT.nbin
+ h_p(Numofplot) = plot(p_ax,ERP_FFT.times,squeeze(ERP_FFT.bindata(count,:,Numofplot)),'LineWidth',1.5,'Color',line_colors(Numofplot,:,:));
+ end
+ axis(p_ax,[floor(ERP_FFT.times(1)),ceil(ERP_FFT.times(end)), 1.1*min(temp(:)) 1.1*max(temp(:))]);
+ xticks(p_ax,FreqTick);
+ xlim([floor(ERP_FFT.times(1)),ceil(ERP_FFT.times(end))]);
+ if count == 1
+ title(p_ax,[ERP_FFT.chanlocs(count).labels],'FontSize',14);
+ legend(p_ax,ERP_FFT.bindescr,'FontSize',14);
+ legend(p_ax,'boxoff');
+ else
+ title(p_ax,ERP_FFT.chanlocs(count).labels,'FontSize',14);
+ end
+ xlabel(p_ax,'Frequency/Hz','FontSize',14);
+ if gui_erp_spectral.phase.Value
+ ylabel(p_ax,'Angle/degree','FontSize',14);
+ elseif gui_erp_spectral.amplitude.Value
+ ylabel(p_ax,'Amplitude/\muV','FontSize',14);
+ elseif gui_erp_spectral.power.Value
+ ylabel(p_ax,'Power/\muV^2','FontSize',14);
+ elseif gui_erp_spectral.db.Value
+ ylabel(p_ax,'Decibels/dB','FontSize',14);
+ end
+ for Numoflabel = 1:length(ERP_FFT.times)
+ X_label{Numoflabel} = [];
+ end
+ set(gca,'TickDir','out');
+ set(gca,'LineWidth',2);
+ end
+ end
+ hold off;
+ clear h_p
+ end
+ %%Save the transformed data for the selected ERPsets as
+ if Save_label
+ if strcmp(ERP_FFT.datatype,'EFFT')
+ if gui_erp_spectral.amplitude.Value
+ figure_name = [ERP_FFT.erpname,'_Spectrum_Amplitude'];
+ elseif gui_erp_spectral.phase.Value
+ figure_name = [ERP_FFT.erpname,'_Spectrum_Phase'];
+ elseif gui_erp_spectral.power.Value
+ figure_name = [ERP_FFT.erpname,'_Spectrum_Power'];
+ elseif gui_erp_spectral.db.Value
+ figure_name = [ERP_FFT.erpname,'_Spectrum_ dB'];
+ end
+
+ end
+
+ if ind==1
+ [filenamei, pathname] = uiputfile({'*.mat';'*.*'},['Save',32,'"',ERP_FFT.erpname,'"', 32,'as'],fullfile(pathName_folder,figure_name));
+
+ if isequal(filenamei,0)
+ disp('User selected Cancel')
+ return
+ else
+ [pathx, filename, ext] = fileparts(filenamei);
+ if ~strcmpi(ext,'.mat')
+ ext = '.mat';
+ end
+ filename = [filename ext];
+ end
+
+ if strcmpi(ext,'.mat')
+ [ERP_FFT, issave, ERPCOM] = pop_savemyerp(ERP_FFT, 'erpname', ERP_FFT.erpname, 'filename', filename, 'filepath',pathname);
+ [~, ALLERPCOM] = erphistory(ERP_FFT, ALLERPCOM, ERPCOM);
+ end
+
+ %%save as '.csv'
+ elseif ind==2
+ def = erpworkingmemory('f_export2csvGUI');
+ if isempty(def)
+ def = {1, 1, 1, 3, ''};
+ end
+
+ def{5} = fullfile(pathName_folder,ERP_FFT.filename);
+ answer_export = f_export2csvGUI(ERP_FFT,def);
+ erpworkingmemory('f_export2csvGUI',answer_export);
+ if isempty(answer_export)
+ beep;
+ disp('User selected cancel!!!');
+ return;
+ end
+ binArray = [1:ERP_FFT.nbin];
+ decimal_num = answer_export{4};
+ istime =answer_export{1} ;
+ electrodes=answer_export{2} ;
+ transpose=answer_export{3};
+ filenamei = answer_export{5};
+ [pathx, filename, ext] = fileparts(filenamei);
+ if ~strcmpi(ext,'.csv')
+ ext = '.csv';
+ end
+ if isempty(pathx)
+ pathx =cd;
+ end
+ filename = [filename ext];
+ mkdir([pathx,filesep]);
+ try
+ export2csv_spectranl_analysis(ERP_FFT,fullfile(pathx,filename), binArray,istime, electrodes,transpose, decimal_num);
+ catch
+ beep;
+ disp('Fail to save selected ERPset as ".csv"!!!');
+ return;
+ end
+ end
+ end
+
+ end%%end loop for ERPSET
+
+ end
+
+
+%%-------------------Setting for the whole panel of fitering based on ALLERP and CURRENTERP--------------
+ function Count_currentERPChanged(~,~)
+ if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded')
+ gui_erp_spectral.advanced.Enable = 'off';
+ gui_erp_spectral.save.Enable = 'off';
+ gui_erp_spectral.plot.Enable = 'off';
+ gui_erp_spectral.phase.Enable = 'off';
+ gui_erp_spectral.amplitude.Enable = 'off';
+ gui_erp_spectral.hamwin_on.Enable = 'off';
+ gui_erp_spectral.hamwin_off.Enable = 'off';
+ gui_erp_spectral.power.Enable = 'off';
+ gui_erp_spectral.db.Enable = 'off';
+ else
+ gui_erp_spectral.advanced.Enable = 'on';
+ gui_erp_spectral.save.Enable = 'on';
+ gui_erp_spectral.plot.Enable = 'on';
+ gui_erp_spectral.phase.Enable = 'on';
+ gui_erp_spectral.amplitude.Enable = 'on';
+ gui_erp_spectral.power.Enable = 'on';
+ gui_erp_spectral.db.Enable = 'on';
+ gui_erp_spectral.hamwin_on.Enable = 'on';
+ gui_erp_spectral.hamwin_off.Enable = 'on';
+ end
+ end
+
+%%----Get the color for lines--------------------------------------
+ function colors = get_colors(ncolors)
+ % Each color gets 1 point divided into up to 2 of 3 groups (RGB).
+ degree_step = 6/ncolors;
+ angles = (0:ncolors-1)*degree_step;
+ colors = nan(numel(angles),3);
+ for i = 1:numel(angles)
+ if angles(i) < 1
+ colors(i,:) = [1 (angles(i)-floor(angles(i))) 0]*0.75;
+ elseif angles(i) < 2
+ colors(i,:) = [(1-(angles(i)-floor(angles(i)))) 1 0]*0.75;
+ elseif angles(i) < 3
+ colors(i,:) = [0 1 (angles(i)-floor(angles(i)))]*0.75;
+ elseif angles(i) < 4
+ colors(i,:) = [0 (1-(angles(i)-floor(angles(i)))) 1]*0.75;
+ elseif angles(i) < 5
+ colors(i,:) = [(angles(i)-floor(angles(i))) 0 1]*0.75;
+ else
+ colors(i,:) = [1 0 (1-(angles(i)-floor(angles(i))))]*0.75;
+ end
+ end
+ end
+
+end
+%Progem end: ERP Measurement tool
\ No newline at end of file
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_suffix_gui.fig b/studio_functions/GUIs/ERP Tab/f_ERP_suffix_gui.fig
new file mode 100755
index 00000000..3cdf437e
Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_ERP_suffix_gui.fig differ
diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_suffix_gui.m b/studio_functions/GUIs/ERP Tab/f_ERP_suffix_gui.m
new file mode 100755
index 00000000..a013df32
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_ERP_suffix_gui.m
@@ -0,0 +1,176 @@
+function varargout = f_ERP_suffix_gui(varargin)
+% F_ERP_SUFFIX_GUI MATLAB code for f_ERP_suffix_gui.fig
+% F_ERP_SUFFIX_GUI, by itself, creates a new F_ERP_SUFFIX_GUI or raises the existing
+% singleton*.
+%
+% H = F_ERP_SUFFIX_GUI returns the handle to a new F_ERP_SUFFIX_GUI or the handle to
+% the existing singleton*.
+%
+% F_ERP_SUFFIX_GUI('CALLBACK',hObject,eventData,handles,...) calls the local
+% function named CALLBACK in F_ERP_SUFFIX_GUI.M with the given input arguments.
+%
+% F_ERP_SUFFIX_GUI('Property','Value',...) creates a new F_ERP_SUFFIX_GUI or raises the
+% existing singleton*. Starting from the left, property value pairs are
+% applied to the GUI before f_ERP_suffix_gui_OpeningFcn gets called. An
+% unrecognized property name or invalid value makes property application
+% stop. All inputs are passed to f_ERP_suffix_gui_OpeningFcn via varargin.
+%
+% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
+% instance to run (singleton)".
+%
+% See also: GUIDE, GUIDATA, GUIHANDLES
+
+% Edit the above text to modify the response to help f_ERP_suffix_gui
+
+% Last Modified by GUIDE v2.5 02-Aug-2022 18:45:52
+
+% Begin initialization code - DO NOT EDIT
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @f_ERP_suffix_gui_OpeningFcn, ...
+ 'gui_OutputFcn', @f_ERP_suffix_gui_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+% End initialization code - DO NOT EDIT
+
+
+% --- Executes just before f_ERP_suffix_gui is made visible.
+function f_ERP_suffix_gui_OpeningFcn(hObject, eventdata, handles, varargin)
+% Choose default command line output for f_ERP_suffix_gui
+
+try
+ erpname = varargin{1};
+
+catch
+ erpname = '';
+
+end
+
+handles.erpnameor = erpname;
+handles.output = [];
+erpmenu = findobj('tag', 'erpsets');
+
+if ~isempty(erpmenu)
+ handles.menuerp = get(erpmenu);
+ set(handles.menuerp.Children, 'Enable','off');
+end
+
+erplab_studio_default_values;
+version = erplabstudiover;
+
+set(handles.gui_chassis,'Name', ['EStudio ' version ' - Add Suffix GUI'])
+set(handles.edit_erpname, 'String', '_processed');
+
+set(handles.current_erp_label,'String', ['Enter suffix, which will be added onto the name of each selected ERPset'],...
+ 'FontWeight','Bold', 'FontSize', 16);
+
+%
+% % Color GUI
+% %
+handles = painterplabstudio(handles);
+%
+% %
+% % Set font size
+% %
+handles = setfonterplabestudio(handles);
+
+% Update handles structure
+guidata(hObject, handles);
+
+
+% UIWAIT makes savemyerpGUI wait for user response (see UIRESUME)
+uiwait(handles.gui_chassis);
+
+
+
+
+% --- Outputs from this function are returned to the command line.
+function varargout = f_ERP_suffix_gui_OutputFcn(hObject, eventdata, handles)
+
+% Get default command line output from handles structure
+% try
+% set(handles.menuerp.Children, 'Enable','on');
+% catch
+% disp('ERPset menu was not found...')
+% end
+varargout{1} = handles.output;
+delete(handles.gui_chassis);
+pause(0.1)
+
+
+
+
+% --- Executes on button press in radio_erpname.
+function radio_erpname_Callback(hObject, eventdata, handles)
+% hObject handle to radio_erpname (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Hint: get(hObject,'Value') returns toggle state of radio_erpname
+
+
+function edit_erpname_Callback(hObject, eventdata, handles)
+
+
+% --- Executes during object creation, after setting all properties.
+function edit_erpname_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+% --- Executes on button press in pushbutton_Cancel.
+function pushbutton_Cancel_Callback(hObject, eventdata, handles)
+handles.output = [];
+beep;
+disp('User selected Cancel')
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+
+% --- Executes on button press in pushbutton4_okay.
+function pushbutton4_okay_Callback(hObject, eventdata, handles)
+erpname = strtrim(get(handles.edit_erpname, 'String'));
+
+if isempty(erpname)
+ msgboxText = 'You must enter a suffix at least!';
+ title = 'EStudio: f_ERP_suffix_gui empty suffix.';
+ errorfound(msgboxText, title);
+ return
+end
+
+
+handles.output = {erpname};
+% Update handles structure
+guidata(hObject, handles);
+
+uiresume(handles.gui_chassis);
+
+
+
+
+% -----------------------------------------------------------------------
+function gui_chassis_CloseRequestFcn(hObject, eventdata, handles)
+
+if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting')
+ %The GUI is still in UIWAIT, us UIRESUME
+ handles.output = '';
+ %Update handles structure
+ guidata(hObject, handles);
+ uiresume(handles.gui_chassis);
+else
+ % The GUI is no longer waiting, just close it
+ delete(handles.gui_chassis);
+end
diff --git a/studio_functions/GUIs/ERP Tab/f_appenderpGUI.fig b/studio_functions/GUIs/ERP Tab/f_appenderpGUI.fig
new file mode 100644
index 00000000..9bd183d9
Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_appenderpGUI.fig differ
diff --git a/studio_functions/GUIs/ERP Tab/f_appenderpGUI.m b/studio_functions/GUIs/ERP Tab/f_appenderpGUI.m
new file mode 100644
index 00000000..f33a5af0
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_appenderpGUI.m
@@ -0,0 +1,1157 @@
+%
+% Author: Javier Lopez-Calderon & Steven Luck & Guanghui Zhang
+% Center for Mind and Brain
+% University of California, Davis,
+% Davis, CA
+% 2009 && 2023
+
+%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b
+%
+% ERPLAB Toolbox
+% Copyright © 2007 The Regents of the University of California
+% Created by Javier Lopez-Calderon and Steven Luck
+% Center for Mind and Brain, University of California, Davis,
+% javlopez@ucdavis.edu, sjluck@ucdavis.edu
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see .
+
+function varargout = f_appenderpGUI(varargin)
+
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @f_appenderpGUI_OpeningFcn, ...
+ 'gui_OutputFcn', @f_appenderpGUI_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+
+% -----------------------------------------------------------------------
+function f_appenderpGUI_OpeningFcn(hObject, eventdata, handles, varargin)
+% Choose default command line output for f_appenderpGUI
+% def = {inp1 erpset isprefix prefixl/ist};
+
+handles.output = [];
+handles.totline = 1;
+
+try
+ totalerpset = varargin{1};
+catch
+ totalerpset = 0;
+end
+try
+ % def = {inp1 erpset prefixlist};
+ def = varargin{2};
+
+catch
+ def = {1 1 [] '', []};
+end
+
+optioni = def{1};
+ERPsetOp = def{2};
+erpset = def{3};
+prefixlist = def{4};
+erpsetPanel = def{5};
+
+handles.optioni = optioni;
+handles.erpset = erpset;
+handles.erpsetop = ERPsetOp;
+handles.prefixlist = prefixlist;
+handles.totalerpset = totalerpset;
+handles.full_list = [];
+handles.listname = [];
+handles.erpsetPanel = erpsetPanel;
+% set GUI
+handles = setbuttonsgui(hObject, eventdata, handles);
+
+erplab_studio_default_values;
+version = erplabstudiover;
+set(handles.gui_chassis,'Name', ['EStudio ' version ' - APPEND ERPs GUI'])
+
+handles = painterplabstudio(handles);
+%
+% Set font size
+%
+handles = setfonterplabestudio(handles);
+
+% help button
+% helpbutton
+
+% Update handles structure
+guidata(hObject, handles);
+
+% UIWAIT makes f_appenderpGUI wait for user response (see UIRESUME)
+uiwait(handles.gui_chassis);
+
+% -----------------------------------------------------------------------
+function varargout = f_appenderpGUI_OutputFcn(hObject, eventdata, handles)
+varargout{1} = handles.output;
+
+% The figure can be deleted now
+delete(handles.gui_chassis);
+pause(0.1)
+
+% -----------------------------------------------------------------------
+function edit_erpset_Callback(hObject, eventdata, handles)
+[chkerp] = checkERPs(hObject, eventdata, handles);
+if chkerp
+ return % problem was found
+else
+ set(handles.radiobutton_includep, 'Enable', 'on');
+end
+
+% -----------------------------------------------------------------------
+function edit_erpset_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+% -----------------------------------------------------------------------
+function pushbutton_RUN_Callback(hObject, eventdata, handles)
+% nsets = handles.totalerpset;
+if handles.radiobutton_folders.Value==0
+
+ erpset = str2num(char(get(handles.edit_erpset, 'String')));
+
+ % if isempty(erpset)
+ % msgboxText = ['No ERPset indices were specified!\n\n'...
+ % 'You must use any integer value(s) between 1 and ' num2str(nsets)];
+ % title = 'ERPLAB: geterpvaluesGUI inputs';
+ % errorfound(sprintf(msgboxText), title);
+ % return
+ % end
+ % if max(erpset)>nsets
+ % msgboxText = ['ERPset indexing out of range!\n\n'...
+ % 'You only have ' num2str(nsets) ' ERPsets loaded on your ERPset Menu.'];
+ % title = 'ERPLAB: geterpvaluesGUI inputs';
+ % errorfound(sprintf(msgboxText), title);
+ % return
+ % end
+ % if min(erpset)<1
+ % msgboxText = ['Invalid ERPset indexing!\n\n'...
+ % 'You may use any integer value between 1 and ' num2str(nsets)];
+ % title = 'ERPLAB: geterpvaluesGUI inputs';
+ % errorfound(sprintf(msgboxText), title);
+ % return
+ % end
+ %
+ % chkerp = checkERPs(hObject, eventdata, handles);
+ foption = 0; %from erpsets
+else
+ erpset = get(handles.listbox_erpnames, 'String');
+ nline = length(erpset);
+
+ if nline==1
+ msgboxText = 'You have to specify at least one erpset!';
+ etitle = 'ERPLAB: geterpvaluesGUI() -> missing input';
+ errorfound(msgboxText, etitle);
+ return
+ end
+
+ listname = handles.listname; % file conteining the list of erpsets
+
+ if isempty(listname) && nline>1
+ BackERPLABcolor = [1 0.9 0.3]; % yellow
+ question = ['You have not yet saved your list.\n'...
+ 'What would you like to do?'];
+ etitle = 'Save List of ERPsets';
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor)
+ button = questdlg(sprintf(question), etitle,'Save and Continue','Save As', 'Cancel','Save and Continue');
+ set(0,'DefaultUicontrolBackgroundColor',oldcolor)
+
+ if strcmpi(button,'Save As')
+ fullname = savelist(hObject, eventdata, handles);
+ listname = fullname;
+ set(handles.edit_filelist,'String', listname);
+ handles.listname = listname;
+
+ % Update handles structure
+ guidata(hObject, handles);
+ return
+ elseif strcmpi(button,'Save and Continue')
+ fulltext = char(get(handles.listbox_erpnames,'String'));
+ listname = char(strtrim(get(handles.edit_filelist,'String')));
+
+ if isempty(listname)
+ % save as
+ fullname = savelist(hObject, eventdata, handles);
+ listname = fullname;
+ set(handles.edit_filelist,'String', listname);
+ else
+ % just save
+ fid_list = fopen( listname , 'w');
+ for i=1:size(fulltext,1)-1
+ fprintf(fid_list,'%s\n', fulltext(i,:));
+ end
+ fclose(fid_list);
+ end
+ elseif strcmpi(button,'Cancel') || strcmpi(button,'')
+ handles.output = [];
+ handles.listname = [];
+
+ % Update handles structure
+ guidata(hObject, handles);
+ return
+ end
+ end
+ erpset = listname;
+ foption = 1; % from list
+end
+[chkerp ] = checkERPs(hObject, eventdata, handles);
+if chkerp
+ return
+else
+ if get(handles.checkbox_useerpname, 'Value')
+ prefixArray = 0; % use filenames instead.
+ else
+ prefixArray = get(handles.listbox_prefix, 'String')';
+ %totline = length(prefixArray)-1;
+ % if totline>0 && totline~=length(erpset)
+ % msgboxText = 'You must enter as many prefixes as erpsets you want to append.';
+ % title = 'ERPLAB: f_appenderpGUI few inputs';
+ % errorfound(msgboxText, title);
+ % return
+ % end
+ prefixArray = prefixArray(1:end-1);
+ end
+ ERPsetOp = handles.radiobutton_erpset.Value;
+ handles.output = {foption,ERPsetOp, erpset, prefixArray};
+
+ % Update handles structure
+ guidata(hObject, handles);
+ uiresume(handles.gui_chassis);
+end
+
+% -----------------------------------------------------------------------
+function radiobutton_includep_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+ set(handles.edit_prefix, 'Enable', 'on');
+ set(handles.pushbutton_addp, 'Enable', 'on');
+ set(handles.pushbutton_deletep, 'Enable', 'on');
+ %set(handles.togglebutton_autonumber, 'Enable', 'on');
+ set(handles.listbox_prefix, 'Enable', 'on');
+ set(handles.pushbutton_cleara, 'Enable', 'on');
+ set(handles.pushbutton_doit4me, 'Enable', 'on');
+ set(handles.checkbox_useerpname, 'Enable', 'on');
+else
+ set(handles.edit_prefix, 'Enable', 'off');
+ set(handles.pushbutton_addp, 'Enable', 'off');
+ set(handles.pushbutton_deletep, 'Enable', 'off');
+ set(handles.pushbutton_cleara, 'Enable', 'off');
+ set(handles.togglebutton_autonumber, 'Enable', 'off');
+ set(handles.listbox_prefix, 'Enable', 'off');
+ set(handles.pushbutton_doit4me, 'Enable', 'off');
+ set(handles.checkbox_useerpname, 'Value', 0);
+ set(handles.checkbox_useerpname, 'Enable', 'off');
+end
+
+% -----------------------------------------------------------------------
+function pushbutton_addp_Callback(hObject, eventdata, handles)
+newline = get(handles.edit_prefix,'String');
+if isempty(strtrim(newline))
+ return
+end
+set(handles.togglebutton_autonumber, 'Value', 0);
+set(handles.togglebutton_autonumber, 'Enable', 'on');
+currline = get(handles.listbox_prefix, 'Value');
+full_list = get(handles.listbox_prefix, 'String');
+totline = length(full_list);
+
+if currline==totline
+ % extra line forward
+ full_list = cat(1, full_list, {'new prefix'});
+ set(handles.listbox_prefix, 'Value', currline+1)
+else
+ set(handles.listbox_prefix, 'Value', currline)
+ resto = full_list(currline:totline);
+
+ full_list = cat(1, full_list, {'new prefix'});
+ set(handles.listbox_prefix, 'Value', currline+1)
+ [full_list{currline+1:totline+1}] = resto{:};
+end
+
+full_list{currline} = newline;
+totline = length(full_list);
+set(handles.listbox_prefix, 'String', full_list);
+handles.totline = totline;
+handles.full_list = full_list;
+
+% Update handles structure
+guidata(hObject, handles);
+
+% -----------------------------------------------------------------------
+function pushbutton_deletep_Callback(hObject, eventdata, handles)
+full_list = get(handles.listbox_prefix, 'String');
+totline = length(full_list) ;
+full_list = char(full_list); % string matrix
+currline = get(handles.listbox_prefix, 'Value');
+set(handles.togglebutton_autonumber, 'Enable', 'off');
+
+if currline>=1 && currline0 && (totline==nerpset || totline==1)
+ for i=1:nerpset
+ if totline==1
+ j = 1;
+ else
+ j = i;
+ end
+ full_list_new{i} = [full_list{j} ' ' num2str(i)];
+ end
+ full_list = cat(1, full_list_new', {'new prefix'});
+ set(handles.listbox_prefix, 'String', full_list);
+ elseif nerpset==0
+ set(handles.togglebutton_autonumber, 'Value', 0);
+ set(handles.togglebutton_autonumber,'Enable','off')
+ msgboxText = 'You must enter at least two datasets to use this button.';
+ etitle = 'ERPLAB: Append ERP GUI automatic prefix numbering';
+ errorfound(msgboxText, etitle);
+ set(handles.togglebutton_autonumber,'Enable','on')
+ set(handles.togglebutton_autonumber,'Enable','on')
+ return
+ else
+ set(handles.togglebutton_autonumber,'Value',0)
+ set(handles.togglebutton_autonumber,'Enable','off')
+ msgboxText = ['You have to enter 1 or ' num2str(nerpset) ' to use this button!'];
+ etitle = 'ERPLAB: Append ERP GUI automatic prefix numbering';
+ errorfound(msgboxText, etitle);
+ set(handles.togglebutton_autonumber,'Enable','on')
+ return
+ end
+ handles.backup_list = backup_list;
+ % Update handles structure
+ guidata(hObject, handles);
+else
+ set(handles.listbox_prefix, 'String', handles.backup_list);
+end
+
+% -----------------------------------------------------------------------
+function edit_prefix_Callback(hObject, eventdata, handles)
+
+% -----------------------------------------------------------------------
+function edit_prefix_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+% -----------------------------------------------------------------------
+function listbox_prefix_Callback(hObject, eventdata, handles)
+full_list = get(handles.listbox_prefix, 'String');
+totline = length(full_list) ;
+currline = get(handles.listbox_prefix, 'Value');
+
+if currline>=1 && currline' fullname ''])
+end
+try
+ fid_list = fopen( fullname );
+catch
+ fprintf('WARNING: %s was not found or is corrupted\n', fullname)
+ return
+end
+formcell = textscan(fid_list, '%[^\n]','CommentStyle','#', 'whitespace', '');
+lista = formcell{:};
+
+% extra line forward
+lista = cat(1, lista, {'new erpset'});
+lentext = length(lista);
+fclose(fid_list);
+
+if lentext>1
+ % try
+ filereadin = strtrim(lista{1});
+ ERP1 = load(filereadin, '-mat');
+ ERP = ERP1.ERP;
+
+ if ~iserpstruct(ERP)
+ error('')
+ end
+
+ set(handles.listbox_erpnames,'String',lista);
+ set(handles.edit_filelist,'String',fullname);
+ listname = fullname;
+ handles.listname = listname;
+ set(handles.button_savelistas, 'Enable','on')
+
+ set(handles.radiobutton_includep, 'Enable', 'on');
+
+
+ % Update handles structure
+ guidata(hObject, handles);
+ % catch
+ % msgboxText = 'This list is anything but an ERPset list!';
+ % title = 'ERPLAB: geterpvaluesGUI inputs';
+ % errorfound(msgboxText, title)
+ % handles.listname = [];
+ % set(handles.button_savelist, 'Enable','off')
+ %
+ % % Update handles structure
+ % guidata(hObject, handles);
+ % end
+else
+ msgboxText = 'This list is empty!';
+ etitle = 'ERPLAB: geterpvaluesGUI inputs';
+ errorfound(msgboxText, etitle);
+ handles.listname = [];
+ set(handles.button_savelist, 'Enable','off')
+
+ % Update handles structure
+ guidata(hObject, handles);
+end
+
+% -----------------------------------------------------------------------
+function button_savelist_Callback(hObject, eventdata, handles)
+fulltext = char(strtrim(get(handles.listbox_erpnames,'String')));
+
+if length(fulltext)>1
+ fullname = get(handles.edit_filelist, 'String');
+
+ if ~strcmp(fullname,'')
+ fid_list = fopen( fullname , 'w');
+ for i=1:size(fulltext,1)
+ fprintf(fid_list,'%s\n', fulltext(i,:));
+ end
+
+ fclose(fid_list);
+ handles.listname = fullname;
+
+ % Update handles structure
+ guidata(hObject, handles);
+ disp(['Saving equation list at ' fullname ' '])
+ else
+ button_savelistas_Callback(hObject, eventdata, handles)
+ return
+ end
+else
+ set(handles.button_savelistas,'Enable','off')
+ msgboxText = 'You have not written any formula yet!';
+ etitle = 'ERPLAB: chanoperGUI few inputs';
+ errorfound(msgboxText, etitle);
+ set(handles.button_savelistas,'Enable','on')
+ return
+end
+
+% -----------------------------------------------------------------------
+function button_adderpset_Callback(hObject, eventdata, handles)
+[erpfname, erppathname] = uigetfile({ '*.erp','ERPLAB-files (*.erp)'; ...
+ '*.mat','Matlab (*.mat)'; ...
+ '*.*', 'All Files (*.*)'}, ...
+ 'Select an edited file', ...
+ 'MultiSelect', 'on');
+
+if isequal(erpfname,0)
+ disp('User selected Cancel')
+ return
+else
+ % try
+ %
+ % test current directory
+ %
+ % changecd(erppathname)
+
+ if ~iscell(erpfname)
+ erpfname = {erpfname};
+ end
+
+ nerpn = length(erpfname);
+
+ for i=1:nerpn
+ newline = fullfile(erppathname, erpfname{i});
+ currline = get(handles.listbox_erpnames, 'Value');
+ fulltext = get(handles.listbox_erpnames, 'String');
+ indxline = length(fulltext);
+
+ if currline==indxline
+ % extra line forward
+ fulltext = cat(1, fulltext, {'new erpset'});
+ set(handles.listbox_erpnames, 'Value', currline+1)
+ else
+ set(handles.listbox_erpnames, 'Value', currline)
+ resto = fulltext(currline:indxline);
+ fulltext = cat(1, fulltext, {'new erpset'});
+ set(handles.listbox_erpnames, 'Value', currline+1)
+ [fulltext{currline+1:indxline+1}] = resto{:};
+ end
+
+ fulltext{currline} = newline;
+ set(handles.listbox_erpnames, 'String', fulltext)
+ end
+
+ handles.listname = [];
+ indxline = length(fulltext);
+ handles.indxline = indxline;
+ handles.fulltext = fulltext;
+ set(handles.button_savelistas, 'Enable','on')
+ set(handles.edit_filelist,'String','');
+ set(handles.radiobutton_includep, 'Enable', 'on');
+
+
+ % Update handles structure
+ guidata(hObject, handles);
+ % catch
+ % set(handles.listbox_erpnames, 'String', '');
+ % msgboxText = 'A file you are attempting to load is not an ERPset!';
+ % title = 'ERPLAB: geterpvaluesGUI2 inputs';
+ % errorfound(msgboxText, title);
+ % handles.listname = [];
+ % set(handles.button_savelist, 'Enable','off')
+ %
+ % % Update handles structure
+ % guidata(hObject, handles);
+ % end
+end
+
+% -----------------------------------------------------------------------
+function button_clearfile_Callback(hObject, eventdata, handles)
+set(handles.edit_filelist,'String','');
+set(handles.button_savelist, 'Enable', 'off')
+set(handles.radiobutton_includep, 'Enable', 'off');
+
+handles.listname = [];
+% Update handles structure
+guidata(hObject, handles);
+
+% -----------------------------------------------------------------------
+function button_savelistas_Callback(hObject, eventdata, handles)
+fulltext = char(get(handles.listbox_erpnames,'String'));
+if length(fulltext)>1
+ fullname = savelist(hObject, eventdata, handles);
+
+ if isempty(fullname)
+ return
+ end
+
+ set(handles.edit_filelist, 'String', fullname )
+ set(handles.button_savelist, 'Enable', 'on')
+ handles.listname = fullname;
+
+ % Update handles structure
+ guidata(hObject, handles);
+else
+ set(handles.button_savelistas,'Enable','off')
+ msgboxText = 'You have not specified any ERPset!';
+ etitle = 'ERPLAB: averager GUI few inputs';
+ errorfound(msgboxText, etitle);
+ set(handles.button_savelistas,'Enable','on')
+ return
+end
+
+% -----------------------------------------------------------------------
+function button_delerpset_Callback(hObject, eventdata, handles)
+fulltext = get(handles.listbox_erpnames, 'String');
+indxline = length(fulltext);
+fulltext = char(fulltext); % string matrix
+currline = get(handles.listbox_erpnames, 'Value');
+
+if currline>=1 && currline1 % put this one first on the list
+ newline = fulltext{1};
+ ERP1 = load(newline, '-mat');
+ ERP = ERP1.ERP;
+ end
+
+ set(handles.listbox_erpnames, 'String', fulltext);
+ listbox_erpnames_Callback(hObject, eventdata, handles)
+ handles.fulltext = fulltext;
+ indxline = length(fulltext);
+ handles.listname = [];
+ set(handles.edit_filelist,'String','');
+
+ % Update handles structure
+ guidata(hObject, handles);
+else
+ set(handles.button_savelistas, 'Enable','off')
+end
+
+% -----------------------------------------------------------------------
+function togglebutton_edit_list_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+ %list = get(handles.listbox_erpnames, 'String')
+ set(handles.listbox_erpnames, 'Value',1)
+ set(handles.listbox_erpnames, 'Style','edit')
+ set(handles.listbox_erpnames, 'Max',2)
+ set(handles.listbox_erpnames, 'HorizontalAlignment','left')
+ set(handles.listbox_erpnames, 'Foregroundcolor',[0 0 0.72])
+
+ set(handles.button_delerpset,'Enable','off')
+ set(handles.button_adderpset,'Enable','off')
+ set(handles.button_savelistas,'Enable','off')
+ set(handles.button_savelist,'Enable','off')
+ set(handles.button_clearfile,'Enable','off')
+ set(handles.button_loadlist,'Enable','off')
+else
+ %list = get(handles.listbox_erpnames, 'String')
+ set(handles.listbox_erpnames, 'Style','listbox')
+ set(handles.listbox_erpnames, 'Value',1)
+ set(handles.listbox_erpnames, 'Foregroundcolor',[0 0 0])
+ set(handles.button_delerpset,'Enable','on')
+ set(handles.button_adderpset,'Enable','on')
+ set(handles.button_savelistas,'Enable','on')
+ set(handles.button_savelist,'Enable','on')
+ set(handles.button_clearfile,'Enable','on')
+ set(handles.button_loadlist,'Enable','on')
+end
+
+% -----------------------------------------------------------------------
+function radiobutton_erpset_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+
+ set(hObject,'Value',1);
+ set(handles.edit_erpset,'Enable','off');
+ set(handles.radiobutton_ERPsetcustom,'Value',0);
+ set(handles.radiobutton_ERPsetcustom,'Enable','on');
+% if handles.erpsetop ==1
+ set(handles.edit_erpset, 'String',num2str(handles.erpsetPanel));
+% end
+
+ set(handles.radiobutton_folders,'Value',0)
+ set(handles.listbox_erpnames,'Enable','off')
+ set(handles.button_adderpset,'Enable','off')
+ set(handles.button_delerpset,'Enable','off')
+ set(handles.button_savelist,'Enable','off')
+ set(handles.button_clearfile,'Enable','off')
+ set(handles.button_savelistas,'Enable','off')
+ set(handles.button_loadlist,'Enable','off')
+ set(handles.edit_filelist,'Enable','off')
+ set(handles.pushbutton_flush,'Enable','off')
+else
+ set(hObject,'Value',1)
+end
+
+%--------------------------------------------------------------------------
+function [chkerp ]= checkERPs(hObject, eventdata, handles)
+chkerp = 0; % no problem
+errorerp = 0;
+nerp = handles.totalerpset;
+
+%
+% Read first ERPset
+%
+if get(handles.radiobutton_folders, 'Value')==0;
+ indexerp = unique_bc2(str2num(get(handles.edit_erpset, 'String')));
+
+ if isempty(indexerp)
+ msgboxText = ['Invalid ERPset indexing!\n\n'...
+ 'You must use any integer value between 1 and %g.'];
+ etitle = 'ERPLAB: appenderpGUI inputs';
+ errorfound(sprintf(msgboxText, num2str(nerp)), etitle);
+ chkerp = 1;
+ return
+ end
+ if max(indexerp)>nerp
+ msgboxText = ['ERPset indexing out of range!\n\n'...
+ 'You only have %g ERPsets loaded on your ERPset Menu.'];
+ etitle = 'ERPLAB: appenderpGUI inputs';
+ errorfound(sprintf(msgboxText, num2str(nerp)), etitle);
+ chkerp = 1;
+ return
+ end
+ if min(indexerp)<1
+ msgboxText = ['Invalid ERPset indexing!\n\n'...
+ 'You must use any integer value between 1 and %g' ];
+ etitle = 'ERPLAB: appenderpGUI inputs';
+ errorfound(sprintf(msgboxText, num2str(nerp)), etitle);
+ chkerp = 1;
+ return
+ end
+ if length(indexerp)<2
+ msgboxText = 'You have to specify 2 erpsets, at least!';
+ title = 'ERPLAB: appenderpGUI() -> few inputs';
+ errorfound(msgboxText, title);
+ chkerp = 1;
+ return
+ end
+
+ ALLERP = evalin('base', 'ALLERP');
+
+ if ~isempty(ALLERP)
+ nerp2 = length(indexerp);
+ numpoints = zeros(1,nerp2);
+ numchans = zeros(1,nerp2);
+ nameerp = {''};
+ for k=1:nerp2
+ numpoints(k) = ALLERP(indexerp(k)).pnts;
+ numchans(k) = ALLERP(indexerp(k)).nchan;
+ nameerp{k} = ALLERP(indexerp(k)).filename;
+ end
+ else
+ chkerp = 1;
+ return
+ end
+ clear ALLERP
+else
+ listname = strtrim(char(get(handles.edit_filelist,'String')));
+
+ %
+ % open file containing the erp list
+ %
+ fid_list = fopen( listname );
+ formcell = textscan(fid_list, '%[^\n]','CommentStyle','#', 'whitespace', '');
+ lista = formcell{:};
+
+ % extra line forward
+ lista = cat(1, lista, {'new erpset'});
+ lentext = length(lista);
+ fclose(fid_list);
+
+ if lentext>1
+ numpoints = zeros(1,lentext-1);
+ numchans = zeros(1,lentext-1);
+ nameerp = {''};
+ for j=1:lentext-1
+ ERP1 = load(strtrim(lista{j}), '-mat');
+ ERP = ERP1.ERP;
+ if ~iserpstruct(ERP)
+ %set(handles.listbox_erpnames, 'String', '');
+ msgboxText = 'A file you are attempting to load is not an ERPset!';
+ etitle = 'ERPLAB: appenderpGUI inputs';
+ errorfound(msgboxText, etitle);
+ handles.listname = [];
+
+ % Update handles structure
+ guidata(hObject, handles);
+ errorerp = 1;
+ set(handles.button_savelist, 'Enable','off')
+ break
+ else
+ numpoints(j) = ERP.pnts;
+ numchans(j) = ERP.nchan;
+ nameerp{j} = ERP.filename;
+ end
+
+ clear ERP1 ERP
+ end
+ if errorerp
+ chkerp = 1;
+ return
+ end
+ end
+ nerp2 = lentext-1;
+ handles.listname = listname;
+ % Update handles structure
+ guidata(hObject, handles);
+end
+if length(unique_bc2(numpoints))>1
+ fprintf('Detail:\n')
+ fprintf('-------\n')
+ for j=1:nerp2
+ fprintf('Erpset %s has %g points per bin\n', nameerp{j}, numpoints(j));
+ end
+ msgboxText = 'ERPsets have different number of points\n';
+ etitle = 'ERPLAB: appenderpGUI inputs';
+ errorfound(sprintf(msgboxText), etitle);
+ chkerp = 1;
+ return
+end
+if length(unique_bc2(numchans))>1
+ fprintf('Detail:\n')
+ fprintf('-------\n')
+ for j=1:nerp2
+ fprintf('Erpset %s has %g channels\n', nameerp{j}, numchans(j));
+ end
+ msgboxText = 'ERPsets have different number of channel\n';
+ etitle = 'ERPLAB: appenderpGUI inputs';
+ errorfound(sprintf(msgboxText), etitle);
+ chkerp = 1;
+ return
+end
+
+% -----------------------------------------------------------------------
+function handles = setbuttonsgui(hObject, eventdata, handles)
+optioni = handles.optioni;
+erpset = handles.erpset;
+prefixlist = handles.prefixlist;
+nsets = handles.totalerpset;
+ERPsetOp = handles.erpsetop;
+
+if nsets>0 && optioni==0 %&& isnumeric(erpset) % from erpset menu
+ set(handles.radiobutton_erpset, 'Value', ERPsetOp);
+ set(handles.radiobutton_erpset, 'Enable', 'on');
+ set( handles.radiobutton_ERPsetcustom, 'Value', ~ERPsetOp);
+ set( handles.radiobutton_ERPsetcustom, 'Enable', 'on');
+ if ERPsetOp==1
+ set( handles.edit_erpset, 'Enable', 'off');
+ else
+ set( handles.edit_erpset, 'Enable', 'on');
+ end
+
+ set(handles.radiobutton_folders, 'Value', 0);
+ set(handles.listbox_erpnames, 'Enable', 'off');
+ set(handles.button_adderpset, 'Enable', 'off');
+ set(handles.button_delerpset, 'Enable', 'off');
+ set(handles.button_savelistas, 'Enable', 'off');
+ set(handles.button_savelist, 'Enable', 'off');
+ set(handles.button_clearfile, 'Enable', 'off');
+ set(handles.button_loadlist, 'Enable', 'off');
+ set(handles.edit_erpset, 'String', vect2colon(erpset, 'Delimiter','off', 'Repeat', 'off'));
+ set(handles.listbox_erpnames, 'String', {'new erpset'});
+ set(handles.edit_filelist,'String', '')
+ set(handles.pushbutton_flush,'Enable','off')
+ set(handles.radiobutton_includep, 'Enable', 'on');
+else % from hard drive
+ set(handles.radiobutton_folders, 'Value', 1);
+ set( handles.edit_erpset, 'Enable', 'off');
+ set(handles.radiobutton_erpset, 'Value', ERPsetOp);
+ set(handles.radiobutton_erpset, 'Enable', 'off');
+ set( handles.radiobutton_ERPsetcustom, 'Value', ~ERPsetOp);
+% if ERPsetOp==1
+% set( handles.radiobutton_ERPsetcustom, 'Enable', 'off');
+% else
+ set( handles.radiobutton_ERPsetcustom, 'Enable', 'off');
+% end
+
+
+ set(handles.pushbutton_flush,'Enable','on')
+ set(handles.radiobutton_includep, 'Value', 0);
+
+ if nsets==0
+ set(handles.radiobutton_erpset, 'Enable', 'off');
+ set(handles.edit_erpset, 'String', 'no erpset');
+ else
+ set(handles.edit_erpset, 'String', vect2colon(1:nsets, 'Delimiter','off', 'Repeat', 'off'));
+ end
+ if ~isempty(erpset) && ischar(erpset)
+
+ %
+ % open file containing the erp list
+ %
+ try
+ fid_list = fopen( erpset );
+ catch
+ fprintf('WARNING: %s was not found or is corrupted\n', fullname)
+ return
+ end
+ formcell = textscan(fid_list, '%[^\n]','CommentStyle','#', 'whitespace', '');
+ fclose(fid_list);
+
+ lista = formcell{:};
+ listname = erpset;
+ set(handles.radiobutton_includep, 'Enable', 'on');
+ set(handles.edit_filelist,'String', erpset)
+ else
+ lista = {};
+ listname = [];
+ set(handles.radiobutton_includep, 'Enable', 'off');
+ end
+
+ % extra line forward
+ lista = cat(1, lista, {'new erpset'});
+ %lentext = length(lista);
+
+ handles.listname = listname;
+ set(handles.button_savelistas, 'Enable','on')
+ set(handles.listbox_erpnames,'String',lista);
+end
+if isempty(prefixlist)
+ set(handles.radiobutton_includep, 'Value', 0);
+ set(handles.edit_prefix, 'Enable', 'off');
+ set(handles.pushbutton_addp, 'Enable', 'off');
+ set(handles.pushbutton_deletep, 'Enable', 'off');
+ set(handles.pushbutton_cleara, 'Enable', 'off');
+ set(handles.togglebutton_autonumber, 'Enable', 'off');
+ set(handles.listbox_prefix, 'Enable', 'off');
+ set(handles.listbox_prefix, 'String', {'new prefix'});
+ set(handles.pushbutton_doit4me, 'Enable', 'off');
+ set(handles.checkbox_useerpname, 'Enable', 'off');
+elseif iscell(prefixlist)
+ set(handles.radiobutton_includep, 'Value', 1);
+ set(handles.edit_prefix, 'Enable', 'on');
+ set(handles.pushbutton_addp, 'Enable', 'on');
+ set(handles.pushbutton_deletep, 'Enable', 'on');
+ set(handles.pushbutton_cleara, 'Enable', 'on');
+ set(handles.togglebutton_autonumber, 'Enable', 'on');
+ set(handles.listbox_prefix, 'Enable', 'on');
+ set(handles.listbox_prefix, 'String', {prefixlist{:} 'new prefix'});
+ set(handles.pushbutton_doit4me, 'Enable', 'on');
+ set(handles.checkbox_useerpname, 'Enable', 'on');
+else
+ set(handles.radiobutton_includep, 'Value', 1);
+ set(handles.edit_prefix, 'Enable', 'off');
+ set(handles.pushbutton_addp, 'Enable', 'off');
+ set(handles.pushbutton_deletep, 'Enable', 'off');
+ set(handles.pushbutton_cleara, 'Enable', 'off');
+ set(handles.togglebutton_autonumber, 'Enable', 'off');
+ set(handles.listbox_prefix, 'Enable', 'off');
+ set(handles.listbox_prefix, 'String', {'new prefix'});
+ set(handles.pushbutton_doit4me, 'Enable', 'off');
+ set(handles.checkbox_useerpname, 'Enable', 'on');
+ set(handles.checkbox_useerpname, 'Value', 1);
+end
+
+% set(handles.radiobutton_erpset, 'Value', 1);
+
+%--------------------------------------------------------------------------
+function fullname = savelist(hObject, eventdata, handles)
+fullname = '';
+fulltext = char(get(handles.listbox_erpnames,'String'));
+
+%
+% Save OUTPUT file
+%
+[filename, filepath, filterindex] = uiputfile({'*.txt';'*.dat';'*.*'},'Save erpset list as');
+
+if isequal(filename,0)
+ disp('User selected Cancel')
+ return
+else
+ [px, fname, ext] = fileparts(filename);
+
+ if strcmp(ext,'')
+ if filterindex==1 || filterindex==3
+ ext = '.txt';
+ else
+ ext = '.dat';
+ end
+ end
+
+ fname = [ fname ext];
+ fullname = fullfile(filepath, fname);
+ disp(['To Save erpset list, user selected ', fullname])
+
+ fid_list = fopen( fullname , 'w');
+
+ for i=1:size(fulltext,1)-1
+ fprintf(fid_list,'%s\n', fulltext(i,:));
+ end
+ fclose(fid_list);
+end
+
+% -----------------------------------------------------------------------
+function checkbox_useerpname_Callback(hObject, eventdata, handles)
+if ~get(hObject,'Value')
+ set(handles.edit_prefix, 'Enable', 'on');
+ set(handles.pushbutton_addp, 'Enable', 'on');
+ set(handles.pushbutton_deletep, 'Enable', 'on');
+ %set(handles.togglebutton_autonumber, 'Enable', 'on');
+ set(handles.listbox_prefix, 'Enable', 'on');
+ set(handles.pushbutton_cleara, 'Enable', 'on');
+ set(handles.pushbutton_doit4me, 'Enable', 'on');
+else
+ set(handles.edit_prefix, 'Enable', 'off');
+ set(handles.pushbutton_addp, 'Enable', 'off');
+ set(handles.pushbutton_deletep, 'Enable', 'off');
+ set(handles.pushbutton_cleara, 'Enable', 'off');
+ set(handles.togglebutton_autonumber, 'Enable', 'off');
+ set(handles.listbox_prefix, 'Enable', 'off');
+ set(handles.pushbutton_doit4me, 'Enable', 'off');
+end
+
+% if get(hObject, 'Value')
+% set(handles.radiobutton_includep, 'Value', 1)
+% else
+% set(handles.radiobutton_includep, 'Value', 0)
+% end
+
+
+% -----------------------------------------------------------------------
+function pushbutton_help_Callback(hObject, eventdata, handles)
+web https://github.com/lucklab/erplab/wiki/Appending-ERPSETS -browser
+
+% -----------------------------------------------------------------------
+function pushbutton_cancel_Callback(hObject, eventdata, handles)
+handles.output = [];
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+% -----------------------------------------------------------------------
+function gui_chassis_CloseRequestFcn(hObject, eventdata, handles)
+
+if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting')
+ %The GUI is still in UIWAIT, us UIRESUME
+ handles.output = '';
+ %Update handles structure
+ guidata(hObject, handles);
+ uiresume(handles.gui_chassis);
+else
+ % The GUI is no longer waiting, just close it
+ delete(handles.gui_chassis);
+end
+
+
+% --- Executes on button press in radiobutton_ERPsetcustom.
+function radiobutton_ERPsetcustom_Callback(hObject, eventdata, handles)
+% hObject handle to radiobutton_ERPsetcustom (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+if get(hObject,'Value')
+ set(handles.edit_erpset,'Enable','on');
+ set(handles.radiobutton_erpset,'Value',0);
+ set(handles.radiobutton_ERPsetcustom,'Value',1);
+
+ set(handles.radiobutton_folders,'Value',0);
+ set(handles.listbox_erpnames,'Enable','off');
+ set(handles.button_adderpset,'Enable','off');
+ set(handles.button_delerpset,'Enable','off');
+ set(handles.button_savelist,'Enable','off');
+ set(handles.button_clearfile,'Enable','off');
+ set(handles.button_savelistas,'Enable','off');
+ set(handles.button_loadlist,'Enable','off');
+ set(handles.edit_filelist,'Enable','off');
+ set(handles.pushbutton_flush,'Enable','off');
+else
+ set(hObject,'Value',1);
+ set(handles.radiobutton_erpset,'Value',0);
+end
diff --git a/studio_functions/GUIs/ERP Tab/f_basicfilterGUI2.fig b/studio_functions/GUIs/ERP Tab/f_basicfilterGUI2.fig
new file mode 100755
index 00000000..01643e2b
Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_basicfilterGUI2.fig differ
diff --git a/studio_functions/GUIs/ERP Tab/f_basicfilterGUI2.m b/studio_functions/GUIs/ERP Tab/f_basicfilterGUI2.m
new file mode 100755
index 00000000..479eaec8
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_basicfilterGUI2.m
@@ -0,0 +1,3054 @@
+%
+% Author: Javier Lopez-Calderon & Steven Luck & Guanghui ZHANG
+% Center for Mind and Brain
+% University of California, Davis,
+% Davis, CA
+% 2009 %2022
+
+%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b
+%
+% ERPLAB Toolbox
+% Copyright © 2007 The Regents of the University of California
+% Created by Javier Lopez-Calderon and Steven Luck
+% Center for Mind and Brain, University of California, Davis,
+% javlopez@ucdavis.edu, sjluck@ucdavis.edu
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see .
+
+function varargout = f_basicfilterGUI2(varargin)
+
+% Begin initialization code - DO NOT EDIT
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @f_basicfilterGUI2_OpeningFcn, ...
+ 'gui_OutputFcn', @f_basicfilterGUI2_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+% End initialization code - DO NOT EDIT
+
+%--------------------------------------------------------------------------
+function f_basicfilterGUI2_OpeningFcn(hObject, eventdata, handles, varargin)
+global outstr
+warning('off','MATLAB:dispatcher:InexactMatch')
+warning('off','MATLAB:dispatcher:InexactCaseMatch')
+handles.output = [];
+outstr = []; % I know, I failed...This is just cause it eliminates some issues using handles.output...
+try
+ ERPLAB = varargin{1};
+catch
+ ERPLAB = [];
+ ERPLAB.srate = 500;
+ ERPLAB.epoch = [];
+ ERPLAB.event = [];
+ ERPLAB.chanlocs = [];
+ ERPLAB.nbchan = 1;
+ ERPLAB.nbbin = 1;
+end
+try
+ def = varargin{2};
+catch
+ % locutoff = answer{1}; % for high pass filter
+ % hicutoff = answer{2}; % for low pass filter
+ % filterorder = answer{3};
+ % chanArray = answer{4};
+ % filterallch = answer{5};
+ % fdesign = answer{6};
+ % remove_dc = answer{7};
+ % boundary = def{8};
+
+ % binArray = def{9};
+ def = {0 30 2 1 1 0 0 [] 1};
+end
+handles.ERPLAB = ERPLAB;
+if isfield(ERPLAB, 'nbchan')
+ nchan = ERPLAB.nbchan;
+elseif isfield(ERPLAB, 'nchan')
+ nchan = ERPLAB.nchan;
+else
+ nchan = 0;
+end
+
+if isfield(ERPLAB, 'nbbin')% By Guanghui 2022
+ nbin = ERPLAB.nbbin;
+elseif isfield(ERPLAB, 'nchan')
+ nbin = ERPLAB.nbin;
+else
+ nbin = 0;
+end
+
+handles.fs = ERPLAB.srate;
+handles.nchan = nchan;
+handles.nbin = nbin;
+fnyq = ERPLAB.srate/2;
+handles.maxsliders = fnyq-1;
+handles.def = def;
+handles.minboundarysamdist = inf;
+handles.xmaxfreqr = [0 round(ERPLAB.srate/4)]; %100
+handles.xmaxpimpz = [0 100];
+handles.valhp = '0';
+handles.vallp = '0';
+handles.iswarngain = 0;
+handles.iswarnroff = 0;
+handles.ishopermission = 0; % high order permission (butterworth)
+handles.autorder = 0;
+handles.datafr.chan = [];
+handles.datafr.ym = [];
+handles.datafr.yf = [];
+handles.datafr.f = [];
+handles.colorband = [];
+handles.memvaluel = 30;
+handles.memvalueh = 0;
+handles.mvaluel = 30;
+handles.mvalueh = 0;
+handles.morder = 2;
+handles.mem6dbl = '---';
+handles.mem6dbh = '---';
+handles.mem3dbl = '---';
+handles.mem3dbh = '---';
+handles.mvalueh = 0; % memory value highpass
+handles.freqdef = 60; % default NOTCH frec
+% set(handles. checkbox_filterallchannels, 'Enable', 'off');
+
+%
+% Prepare List of current Channels
+%
+if isempty(ERPLAB.chanlocs)
+ for e = 1:nchan
+ ERPLAB.chanlocs(e).labels = ['Ch' num2str(e)];
+ end
+end
+listch = {''};
+for ch =1:nchan
+ listch{ch} = [num2str(ch) ' = ' ERPLAB.chanlocs(ch).labels ];
+end
+
+handles.listch = listch;
+handles.indxlistch = def{4}; % channel array
+
+listb = {''};
+for bin =1:nbin
+ listb{bin} = strcat('BIN',num2str(bin),' = ', ERPLAB.bindescr{bin});
+end
+
+handles.listb = listb;
+handles.indxlistb = def{9}; % channel array
+
+
+
+
+
+% Update handles structure
+guidata(hObject, handles);
+
+%
+% Color GUI
+%
+% handles = painterplab(handles);
+
+%
+% pre-plot
+%
+plot(1,1)
+axis([0 ERPLAB.srate/2 -0.75 1.25])
+drawnow
+
+%
+% Set font size
+handles = painterplabstudio(handles);
+
+%
+% Set font size
+%
+handles = setfonterplabestudio(handles);
+% Update handles structure
+guidata(hObject, handles);
+
+% help
+helpbutton
+
+setall(hObject, eventdata, handles)
+
+% Update handles structure
+guidata(hObject, handles);
+drawnow
+% UIWAIT makes str2codeGUI wait for user response (see UIRESUME)
+uiwait(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+function varargout = f_basicfilterGUI2_OutputFcn(hObject, eventdata, handles)
+global outstr
+% Get default command line output from handles structure
+varargout{1} = outstr;
+
+% The figure can be deleted now
+delete(handles.gui_chassis);
+pause(0.1)
+
+%--------------------------------------------------------------------------
+function [order orderindx ]= getorder(handles)
+%
+% FILTER order
+%
+orderindx = get(handles.popupmenu_order, 'Value');
+orderlist = cellstr(get(handles.popupmenu_order, 'String'));
+order = str2num(strrep(orderlist{orderindx},'automin:','')); % get rid of auto (in case of)
+
+%--------------------------------------------------------------------------
+function slider_highpass_Callback(hObject, eventdata, handles)
+
+valueh = get(handles.slider_highpass, 'Value');
+valueh = round(valueh*10)/10;
+
+if valueh<0.1;
+ valueh = 0;
+ set(handles.slider_highpass, 'Value', 0);
+end
+if get(handles.radiobutton_butter, 'Value');
+ typef = 0; % 0 means Butterworth
+elseif get(handles.radiobutton_fir, 'Value');
+ typef = 1;% 1 means FIR
+elseif get(handles.radiobutton_PM_notch, 'Value');
+ typef = 2; % 2 means PM Notch
+end
+
+posh = get(handles.popupmenu_order,'Value'); % order pop menu current position
+autorder = handles.autorder;
+
+%
+% FILTER order
+%
+order = getorder(handles);
+
+if isempty(order)
+ return
+end
+
+tonhp = get(handles.togglebutton_highpass, 'Value');
+
+if typef==2
+ if valueh>=5 && valueh<=handles.maxsliders-5
+ set(handles.slider_lowpass, 'Value', valueh);
+ valuehstr = sprintf('%.1f', valueh);
+ set(handles.edit_highpass, 'String', valuehstr);
+ else
+ if valueh<5
+ nvaln = 5;
+ elseif valueh>handles.maxsliders-5
+ nvaln = handles.maxsliders-5;
+ end
+
+ nvalstr = sprintf('%.1f',nvaln);
+ set(handles.edit_highpass, 'String', nvalstr);
+ set(handles.slider_highpass, 'Value', nvaln);
+ end
+else
+ if tonhp
+ if valueh==0
+ set(handles.edit_highpass, 'String', '0');
+ set(handles.edit_highpass, 'Enable', 'off');
+ set(handles.togglebutton_highpass, 'Value', 0);
+ set(handles.slider_highpass, 'Enable','off');
+ set(handles.checkbox_removedc, 'Enable', 'off')
+ %set(handles.edit_highpass, 'BackgroundColor', [0.75 0.75 0.75]);
+ set(handles.togglebutton_highpass, 'BackgroundColor', [0.8 0.8 0.75]);
+ else
+ valuehstr = sprintf('%.1f', valueh);
+ set(handles.edit_highpass, 'String', valuehstr);
+ set(handles.edit_highpass, 'Enable', 'on');
+ set(handles.checkbox_removedc, 'Enable', 'on')
+ %set(handles.edit_highpass, 'BackgroundColor', [1 1 1]);
+ end
+ else
+ set(handles.edit_highpass, 'String', '0');
+ set(handles.edit_highpass, 'Enable', 'off');
+ set(handles.togglebutton_highpass, 'Value', 0);
+ set(handles.slider_highpass, 'Enable','off');
+ set(handles.checkbox_removedc, 'Enable', 'off')
+ %set(handles.edit_highpass, 'BackgroundColor', [0.75 0.75 0.75]);
+ end
+end
+if typef==0 && autorder==1
+ % order starts again for auto butter
+ orderlist = cellstr(get(handles.popupmenu_order, 'String')); % whole list
+ orderlist{1} = 'automin:2';
+ set(handles.popupmenu_order, 'String', orderlist);
+ set(handles.popupmenu_order, 'Value',1);
+ set(handles.popupmenu_dboct, 'Value',1);
+ set(handles.popupmenu_dbdec, 'Value',1);
+end
+
+%
+% Plot corresponding response
+%
+if get(handles.radiobutton_fdatafr,'Value')
+ plotresponse_fd_data(hObject, eventdata, handles)
+elseif get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_impr,'Value')
+ plotresponsefilter(hObject, eventdata, handles);
+end
+
+% -------------------------------------------------------------------------
+function slider_highpass_CreateFcn(hObject, eventdata, handles)
+
+if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor',[.9 .9 .9]);
+end
+
+%--------------------------------------------------------------------------
+function slider_lowpass_Callback(hObject, eventdata, handles)
+
+valuel = get(handles.slider_lowpass, 'Value');
+valuel = round(valuel*10)/10;
+fs = handles.fs;
+
+if valuel<0.1;
+ valuel = 0;
+ set(handles.slider_lowpass, 'Value', 0);
+end
+if valuel>round(fs/10) && (get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_fdatafr,'Value'))
+ handles.xmaxfreqr = [0 round(fs/2)]; %100
+ set(handles.edit_xmaxplot, 'String', sprintf('%d %d', handles.xmaxfreqr));
+ % Update handles structure
+ guidata(hObject, handles);
+elseif valuel<=round(fs/10) && (get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_fdatafr,'Value'))
+ handles.xmaxfreqr = [0 round(fs/10)]; %100
+ set(handles.edit_xmaxplot, 'String', sprintf('%d %d', handles.xmaxfreqr));
+ % Update handles structure
+ guidata(hObject, handles);
+end
+if get(handles.radiobutton_butter, 'Value');
+ typef = 0; % 0 means Butterworth
+elseif get(handles.radiobutton_fir, 'Value');
+ typef = 1;% 1 means FIR
+elseif get(handles.radiobutton_PM_notch, 'Value');
+ typef = 2; % 2 means PM Notch
+end
+
+autorder = handles.autorder;
+
+%
+% FILTER order
+%
+order = getorder(handles);
+
+if isempty(order)
+ return
+end
+tonlp = get(handles.togglebutton_lowpass, 'Value');
+if tonlp
+ if valuel==0
+ set(handles.edit_lowpass, 'String', '0');
+ set(handles.edit_lowpass, 'Enable', 'off');
+ set(handles.togglebutton_lowpass, 'Value', 0);
+ set(handles.slider_lowpass, 'Enable','off');
+ %set(handles.edit_lowpass, 'BackgroundColor', [0.75 0.75 0.75]);
+ set(handles.togglebutton_lowpass, 'BackgroundColor', [0.8 0.8 0.75]);
+ else
+ valuelstr = sprintf('%.1f', valuel);
+ set(handles.edit_lowpass, 'String', valuelstr);
+ set(handles.edit_lowpass, 'Enable', 'on');
+ %set(handles.edit_lowpass, 'BackgroundColor', [1 1 1]);
+ end
+else
+ set(handles.edit_lowpass, 'String', '0');
+ set(handles.edit_lowpass, 'Enable', 'off');
+ set(handles.togglebutton_lowpass, 'Value', 0);
+ set(handles.slider_lowpass, 'Enable','off');
+ %set(handles.edit_lowpass, 'BackgroundColor', [0.75 0.75 0.75]);
+end
+if typef==0 && autorder==1
+ % order starts again for auto butter
+ orderlist = cellstr(get(handles.popupmenu_order, 'String')); % whole list
+ orderlist{1} = 'automin:2';
+ set(handles.popupmenu_order, 'String', orderlist);
+ set(handles.popupmenu_order, 'Value',1);
+ set(handles.popupmenu_dboct, 'Value',1);
+ set(handles.popupmenu_dbdec, 'Value',1);
+end
+
+%
+% Plot corresponding response
+%
+if get(handles.radiobutton_fdatafr,'Value')
+ plotresponse_fd_data(hObject, eventdata, handles)
+elseif get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_impr,'Value')
+ plotresponsefilter(hObject, eventdata, handles);
+end
+
+%--------------------------------------------------------------------------
+function slider_lowpass_CreateFcn(hObject, eventdata, handles)
+
+if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor',[.9 .9 .9]);
+end
+
+%--------------------------------------------------------------------------
+function popupmenu_order_Callback(hObject, eventdata, handles)
+
+orderindx = get(handles.popupmenu_order, 'Value');
+orderlist = cellstr(get(handles.popupmenu_order, 'String'));
+
+if orderindx==1
+ orderlist = regexprep(orderlist,'automin:','','ignorecase'); %get rid of auto: (if any)
+ newlaborder = ['automin:' orderlist{2}];
+ orderlist{1} = newlaborder;
+ set(handles.popupmenu_order,'String', orderlist);
+ handles.autorder = 1;
+
+ if get(handles.radiobutton_butter,'Value')
+ order = str2num(strrep(orderlist{1},'automin:','')); % get rid of auto (in case of)
+ set(handles.popupmenu_dboct,'Value', 1);
+ set(handles.popupmenu_dbdec,'Value', 1);
+ end
+else
+ orderlist{1} = 'automin';
+ set(handles.popupmenu_order,'String', orderlist);
+ handles.autorder = 0;
+
+ if get(handles.radiobutton_butter,'Value')
+ set(handles.popupmenu_dboct,'Value', orderindx-1);
+ set(handles.popupmenu_dbdec,'Value', orderindx-1);
+ end
+end
+
+% Update handles structure
+guidata(hObject, handles);
+%
+% Plot corresponding response
+%
+if get(handles.radiobutton_fdatafr,'Value')
+ plotresponse_fd_data(hObject, eventdata, handles)
+elseif get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_impr,'Value')
+ plotresponsefilter(hObject, eventdata, handles);
+end
+
+%--------------------------------------------------------------------------
+function popupmenu_order_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function edit_highpass_Callback(hObject, eventdata, handles)
+
+valueh = str2num(get(handles.edit_highpass, 'String'));
+
+if length(valueh)~=1
+ msgboxText = 'Invalid input for high pass cutoff';
+ title = 'EStudio: basicfilterGUI2() error';
+ errorfound(msgboxText, title);
+ return
+end
+if valueh<0.001;
+ set(handles.edit_highpass, 'String', num2str(handles.maxsliders))
+ set(handles.slider_highpass, 'Value', handles.maxsliders);
+ set(handles.slider_highpass, 'Enable', 'on');
+ set(handles.togglebutton_highpass, 'Value', 1);
+ set(handles.togglebutton_highpass, 'BackgroundColor', [1 1 0.5]);
+ plotresponsefilter(hObject, eventdata, handles);
+ return
+end
+if valueh<0
+ msgboxText = 'Invalid input for high pass cutoff';
+ title = 'EStudio: basicfilterGUI2() error';
+ errorfound(msgboxText, title);
+ set(handles.edit_highpass, 'String', '0')
+ set(handles.edit_highpass, 'Enable', 'off')
+ %set(handles.edit_highpass, 'BackgroundColor', [0.75 0.75 0.75]);
+ set(handles.slider_highpass, 'Value', 0);
+ set(handles.slider_highpass, 'Enable', 'off');
+ set(handles.togglebutton_highpass, 'Value', 0);
+ set(handles.togglebutton_highpass, 'BackgroundColor', [0.8 0.8 0.75]);
+ plotresponsefilter(hObject, eventdata, handles);
+ return
+end
+if valueh>handles.maxsliders
+ msgboxText = 'Too high!!!';
+ title = 'EStudio: basicfilterGUI2() error';
+ errorfound(msgboxText, title);
+ set(handles.edit_highpass, 'String', num2str(handles.maxsliders))
+ set(handles.slider_highpass, 'Value', handles.maxsliders);
+ set(handles.slider_highpass, 'Enable', 'on');
+ set(handles.togglebutton_highpass, 'Value', 1);
+ set(handles.togglebutton_highpass, 'BackgroundColor', [1 1 0.5]);
+ plotresponsefilter(hObject, eventdata, handles);
+ return
+end
+
+set(handles.edit_highpass, 'String', num2str(valueh));
+autorder = handles.autorder;
+
+if get(handles.radiobutton_butter, 'Value');
+ typef = 0; % 0 means Butterworth
+elseif get(handles.radiobutton_fir, 'Value');
+ typef = 1;% 1 means FIR
+elseif get(handles.radiobutton_PM_notch, 'Value');
+ typef = 2; % 2 means PM Notch
+end
+
+notchpm = get(handles.radiobutton_PM_notch,'Value');
+
+if notchpm
+ if valueh>=5 && valueh<=handles.maxsliders-5
+ set(handles.slider_highpass, 'Value', valueh);
+ else
+ if valueh<5
+ nvaln = 5;
+ elseif valueh>handles.maxsliders-5
+ nvaln = handles.maxsliders-5;
+ end
+
+ nvalstr = sprintf('%.1f',nvaln);
+ set(handles.edit_highpass, 'String', nvalstr);
+ set(handles.slider_highpass, 'Value', nvaln);
+ end
+
+ %
+ % Plot corresponding response
+ %
+
+ if get(handles.radiobutton_fdatafr,'Value')
+ plotresponse_fd_data(hObject, eventdata, handles)
+ elseif get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_impr,'Value')
+ plotresponsefilter(hObject, eventdata, handles);
+ end
+else
+ set(handles.slider_highpass, 'Value', valueh);
+
+ if typef==0 && autorder==1
+ % order starts again for auto butter
+ orderlist = cellstr(get(handles.popupmenu_order, 'String')); % whole list
+ orderlist{1} = 'automin:2';
+ set(handles.popupmenu_order, 'String', orderlist);
+ set(handles.popupmenu_order, 'Value',1);
+ end
+
+ %
+ % Plot corresponding response
+ %
+ if get(handles.radiobutton_fdatafr,'Value')
+ plotresponse_fd_data(hObject, eventdata, handles)
+ elseif get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_impr,'Value')
+ plotresponsefilter(hObject, eventdata, handles);
+ end
+end
+
+%--------------------------------------------------------------------------
+function edit_highpass_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function edit_lowpass_Callback(hObject, eventdata, handles)
+
+valuel = str2num(get(handles.edit_lowpass, 'String'));
+
+if length(valuel)~=1
+ msgboxText = 'Invalid input for low pass cutoff';
+ title = 'EStudio: basicfilterGUI2() error';
+ errorfound(msgboxText, title);
+ return
+end
+if valuel<0.001;
+ set(handles.edit_lowpass, 'String', num2str(handles.maxsliders))
+ set(handles.slider_lowpass, 'Value', handles.maxsliders);
+ set(handles.slider_lowpass, 'Enable', 'on');
+ set(handles.togglebutton_lowpass, 'Value', 1);
+ set(handles.togglebutton_lowpass, 'BackgroundColor', [1 1 0.5]);
+ plotresponsefilter(hObject, eventdata, handles);
+ return
+end
+if valuel<0
+ msgboxText = 'Invalid input for low pass cutoff';
+ title = 'EStudio: basicfilterGUI2() error';
+ errorfound(msgboxText, title);
+ set(handles.edit_lowpass, 'String', '0')
+ set(handles.edit_lowpass, 'Enable', 'off')
+ %set(handles.edit_lowpass, 'BackgroundColor', [0.75 0.75 0.75]);
+ set(handles.slider_lowpass, 'Value', 0);
+ set(handles.slider_lowpass, 'Enable', 'off');
+ set(handles.togglebutton_lowpass, 'Value', 0);
+ set(handles.togglebutton_lowpass, 'BackgroundColor', [0.8 0.8 0.75]);
+ plotresponsefilter(hObject, eventdata, handles);
+ return
+end
+if valuel>handles.maxsliders
+ msgboxText = 'Too high!!!';
+ title = 'EStudio: basicfilterGUI2() error';
+ errorfound(msgboxText, title);
+ set(handles.edit_lowpass, 'String', num2str(handles.maxsliders))
+ set(handles.slider_lowpass, 'Value', handles.maxsliders);
+ set(handles.slider_lowpass, 'Enable', 'on');
+ set(handles.togglebutton_lowpass, 'Value', 1);
+ set(handles.togglebutton_lowpass, 'BackgroundColor', [1 1 0.5]);
+ plotresponsefilter(hObject, eventdata, handles);
+ return
+end
+
+set(handles.edit_lowpass, 'String', num2str(valuel));
+autorder = handles.autorder;
+set(handles.slider_lowpass, 'Value', valuel);
+
+if get(handles.radiobutton_butter, 'Value');
+ typef = 0; % 0 means Butterworth
+elseif get(handles.radiobutton_fir, 'Value');
+ typef = 1;% 1 means FIR
+elseif get(handles.radiobutton_PM_notch, 'Value');
+ typef = 2; % 2 means PM Notch
+end
+if typef==0 && autorder==1
+ % order starts again for auto butter
+ orderlist = cellstr(get(handles.popupmenu_order, 'String')); % whole list
+ orderlist{1} = 'automin:2';
+ set(handles.popupmenu_order, 'String', orderlist);
+ set(handles.popupmenu_order, 'Value',1);
+end
+
+%
+% Plot corresponding response
+%
+if get(handles.radiobutton_fdatafr,'Value')
+ plotresponse_fd_data(hObject, eventdata, handles)
+elseif get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_impr,'Value')
+ plotresponsefilter(hObject, eventdata, handles);
+end
+
+%--------------------------------------------------------------------------
+function edit_lowpass_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+% % % function popupmenu_channels_Callback(hObject, eventdata, handles)
+% % %
+% % % numch = get(hObject, 'Value');
+% % % nums = str2num(get(handles.edit_channels, 'String'));
+% % % nums = [nums numch];
+% % % if isempty(nums)
+% % % msgboxText{1} = 'Invalid channel indexing.';
+% % % title = 'EStudio: f_basicfilter GUI error:';
+% % % errorfound(msgboxText, title);
+% % % return
+% % % end
+% % % chxstr = vect2colon(nums,'Delimiter','off', 'Repeat', 'off');
+% % % set(handles.edit_channels,'String', chxstr)
+% % % if get(handles.radiobutton_ufdatafr,'Value');
+% % % plotresponse_uf_data(hObject, eventdata, handles);
+% % % end
+
+%--------------------------------------------------------------------------
+% % function popupmenu_channels_CreateFcn(hObject, eventdata, handles)
+% %
+% % if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+% % set(hObject,'BackgroundColor','white');
+% % end
+
+%--------------------------------------------------------------------------
+function edit_channels_Callback(hObject, eventdata, handles)
+
+nchan = handles.nchan;
+chx = str2num(get(handles.edit_channels,'String'));
+tf = checkchannels(chx, nchan);
+if tf
+ return
+end
+ERPLAB = handles.ERPLAB;
+[chk, msgboxText] = f_ERP_chckbinandchan(ERPLAB, [], chx,2);
+if chk(2)
+ title = 'EStudio: f_basicfilterGUI2';
+ errorfound(msgboxText, title);
+ return;
+end
+handles.indxlistch = chx; % channel array
+% if length(chx)==nchan
+% % set(handles.checkbox_filterallchannels, 'Value', 1)
+% set(handles.edit_channels, 'String', vect2colon([1:nchan], 'Delimiter', 'off'));
+% set(handles.edit_channels, 'Enable', 'off');
+% set(handles.pushbutton_browsechan, 'Enable', 'off');
+% else
+chxstr = vect2colon(chx,'Delimiter','off', 'Repeat', 'off');
+set(handles.edit_channels,'String', chxstr)
+% end
+if get(handles.radiobutton_ufdatafr,'Value');
+ plotresponse_uf_data(hObject, eventdata, handles);
+elseif get(handles.radiobutton_fdatafr,'Value');
+ plotresponse_fd_data(hObject, eventdata, handles);
+end
+
+%--------------------------------------------------------------------------
+function tf = checkchannels(chx, nchan, showmsg)
+
+if nargin<3
+ showmsg = 1;
+end
+tf = 0; % no problem by default
+if isempty(chx)
+ if showmsg
+ msgboxText = 'Invalid channel indexing.';
+ title = 'EStudio: f_basicfilterGUI2 error:';
+ errorfound(msgboxText, title);
+ end
+ tf = 1; %
+ return
+end
+if ~isempty(find(chx>nchan))
+ if showmsg
+ msgboxText = ['You only have %g channels,\n'...
+ 'so you cannot specify indices greater than this.'];
+ title = 'EStudio: f_basicfilterGUI2 error:';
+ errorfound(sprintf(msgboxText, nchan), title);
+ end
+ tf = 1; %
+ return
+end
+if ~isempty(find(chx<1))
+ if showmsg
+ msgboxText = 'You cannot use zero or a negative number as a channel indexing';
+ title = 'EStudio: f_basicfilterGUI2 error:';
+ errorfound(msgboxText, title);
+ end
+ tf = 1; %
+ return
+end
+if length(chx)>length(unique_bc2(chx))
+ if showmsg
+ msgboxText = ['Repeated channels are not allowed.\n'...
+ 'Therefore, ERPLAB will get rid of them.'];
+ title = 'EStudio: f_basicfilterGUI2 error:';
+ errorfound(sprintf(msgboxText), title, [1 1 0], [0 0 0], 0)
+ end
+ tf = 0; %
+ return
+end
+return
+
+%--------------------------------------------------------------------------
+function edit_channels_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function pushbutton_cancel_Callback(hObject, eventdata, handles)
+
+handles.output= [];
+
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+
+%--------------------------------------------------------------------------
+function pushbutton_help_Callback(hObject, eventdata, handles)
+% doc pop_basicfilter
+web https://github.com/lucklab/erplab/wiki/Filtering -browser
+%--------------------------------------------------------------------------
+function pushbutton_apply_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function pushbutton_apply_Callback(hObject, eventdata, handles)
+global outstr
+outstr=[];
+
+[readobjects v] = read_GUI(hObject, eventdata, handles); % v=1 means everythink is ok.
+
+if v~=1 % means something was wrong
+ return
+end
+
+channelArray = readobjects{1};
+filterallch = readobjects{2};
+highpasscutoff = readobjects{3};
+lowpasscutoff = readobjects{4};
+order = readobjects{5};
+typefilter = readobjects{6};
+remove_dc = readobjects{7};
+boundarycheck = readobjects{8};
+boundarystr = readobjects{9};
+
+binArray = str2num(get(handles.edit_bins,'String'));
+% tf = checkchannels(chx, nchan);
+def = handles.def;
+
+ERPLAB = handles.ERPLAB;
+if def{5}
+ binArray = [1:ERPLAB.nbin];
+ channelArray = [1:ERPLAB.nchan];
+end
+
+
+[chk, msgboxText] = f_ERP_chckbinandchan(ERPLAB, binArray,[],1);
+if chk(1)
+ title = 'EStudio: f_basicfilterGUI2';
+ errorfound(msgboxText, title);
+ return;
+end
+
+iswarngain = handles.iswarngain;
+iswarnroff = handles.iswarnroff;
+
+if (iswarngain==1 || iswarngain==2) && ~strcmpi(typefilter,'notch')
+
+ BackERPLABcolor = [1 0.9 0.3]; % yellow
+
+ if iswarngain==1
+ question = ['With this filter setting, there will be significant \n'...
+ 'attenuation at passband. This is almost always a \n'...
+ 'bad thing. This problem can usually be eliminated by \n'...
+ 'selecting a lower high-pass cuttoff, higher low-pass \n'...
+ 'cuttoff, and/or a higher filter order. '];
+ elseif iswarngain==2
+ question = ['With this filter setting, there will be some \n'...
+ 'amplification at the passband frequencies. \n'...
+ 'This problem can be eliminated by selecting \n'...
+ 'a higher filter order. '];
+ end
+
+ title = 'WARNING!';
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor)
+ button = questdlg(sprintf(question), title,'Proceed anyway', 'Cancel','Proceed anyway');
+ set(0,'DefaultUicontrolBackgroundColor',oldcolor)
+
+ if ~strcmpi(button,'Proceed anyway')
+ disp('User selected Cancel')
+ return
+ end
+end
+if highpasscutoff==0 && lowpasscutoff==0
+ msgboxText = ['I beg your pardon?\n\n'...
+ 'You must define one frequency cutoff at least.'];
+ title = 'EStudio: f_basicfilter GUI error:';
+ errorfound(sprintf(msgboxText), title);
+ return
+end
+if strcmp(typefilter, 'fir') || strcmp(typefilter, 'notch')
+
+ minboundarysamdist = handles.minboundarysamdist;
+ if boundarycheck==1
+ if minboundarysamdist<3*order
+ BackERPLABcolor = [ 1 1 0];
+ question = ['You have set the checkbox for filtering between boundary events.\n'...
+ 'Event codes ''boundary'' or -99 were found in you dataset.\n\n'...
+ 'However, at least one of the segments among boundaries \n'...
+ 'has less samples than 3 times the filter order you are currently setting.\n\n'...
+ 'You may either decrese the order of the filter - if it is possible - (recommended),\n'...
+ 'or uncheck the option for filtering between boundary events (not recommended).'];
+
+ questionstr = sprintf(question);
+ titlex = 'EStudio: Filter order vs number of samples';
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor)
+ button = questdlg(questionstr, titlex,'OK','OK');
+ set(0,'DefaultUicontrolBackgroundColor',oldcolor)
+ return
+ end
+ end
+end
+if boundarycheck==1
+ if strcmpi(boundarystr,'boundary')||strcmpi(boundarystr,'''boundary''')
+ boundary = 'boundary';
+ else
+ if ~strcmp(boundarystr,'')
+ boundary = str2num(boundarystr);
+ if isempty(boundary);
+ boundary = boundarystr;
+ end
+ else
+ %boundary = [];
+ msgboxText = ['You have set the checkbox for filtering between boundary events.\n'...
+ 'So, you must define a boundary event code.'];
+ title = 'EStudio: f_basicfilter GUI error:';
+ errorfound(sprintf(msgboxText), title);
+ return
+ end
+ end
+else
+ boundary = [];
+end
+
+nchan = handles.nchan;
+tf = checkchannels(channelArray, nchan, 0); % 0 means no problems
+
+if tf
+ return
+end
+if ~isempty(highpasscutoff) && ~isempty(lowpasscutoff) && ~isempty(order) && ~isempty(channelArray) && ~isempty(binArray)
+ %v=1;
+ outstr = {highpasscutoff, lowpasscutoff, order, channelArray, filterallch, typefilter, remove_dc, boundary,binArray};
+ %handles.output = outstr;
+ %guidata(hObject, handles);
+ uiresume(handles.gui_chassis);
+else
+ msgboxText = 'Something went wrong...Please try again';
+ title = 'EStudio: f_basicfilter GUI error:';
+ errorfound(msgboxText, title);
+ return
+end
+
+%--------------------------------------------------------------------------
+function [readobjects v] = read_GUI(hObject, eventdata, handles)
+% global readobjects
+v = 1; % everything ok by default
+readobjects = {};
+channelArray = str2num(get(handles.edit_channels, 'string'));
+channelArray = unique_bc2(channelArray);
+len1 = length(channelArray);
+% filterallch = get(handles.checkbox_filterallchannels, 'Value');
+% if filterallch
+% nchan = handles.nchan;
+% channelArray = 1:nchan; % all channels
+% len2 = length(channelArray);
+% if len1~=len2
+% fprintf('Index of channels to be filtered was adjusted since current %s has %g channels.\n', typedata, nchan);
+% end
+% if len2==nchan
+% set(handles.checkbox_filterallchannels, 'Value', 1)
+% set(handles.edit_channels, 'String', vect2colon([1:nchan], 'Delimiter', 'off'));
+% set(handles.edit_channels, 'Enable', 'off');
+% set(handles.pushbutton_browsechan, 'Enable', 'off');
+% end
+% end
+filterallch = 1;
+highpasscutoff = str2num(get(handles.edit_highpass, 'string'));
+if length(highpasscutoff)~=1
+ msgboxText = 'Invalid input for high pass cutoff';
+ title = 'EStudio: basicfilterGUI2() error';
+ errorfound(msgboxText, title);
+ v=0;
+ return
+end
+remove_dc = get(handles.checkbox_removedc, 'Value');
+boundarystr = get(handles.edit_boundary, 'String');
+boundarycheck = get(handles.checkbox_boundary,'Value');
+if get(handles.radiobutton_butter, 'Value'); % 0 means Butterworth
+ typefilter = 'butter';
+elseif get(handles.radiobutton_fir, 'Value'); % 1 means FIR
+ typefilter = 'fir';
+elseif get(handles.radiobutton_PM_notch, 'Value'); % 2 means PM Notch
+ typefilter = 'notch';
+end
+if strcmp(typefilter, 'notch')
+ lowpasscutoff = highpasscutoff;
+ order = 180;
+else
+ lowpasscutoff = str2num(get(handles.edit_lowpass, 'string'));
+
+ if length(lowpasscutoff)~=1
+ msgboxText = 'Invalid input for low pass cutoff';
+ title = 'EStudio: basicfilterGUI2() error';
+ errorfound(msgboxText, title);
+ v=0;
+ return
+ end
+ order = getorder(handles);
+end
+readobjects = {channelArray, filterallch, highpasscutoff, lowpasscutoff, order, typefilter, remove_dc, boundarycheck, boundarystr};
+
+%--------------------------------------------------------------------------
+function checkbox_removedc_Callback(hObject, eventdata, handles)
+
+% -------------------------------------------------------------------------
+function togglebutton_highpass_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+ set(handles.edit_highpass, 'Enable', 'on');
+ set(handles.edit2_highpass, 'Enable', 'on');
+ set(handles.edit2_highpass, 'BackgroundColor', [1 1 0.5]);
+ set(handles.edit2_highpass, 'Enable', 'inactive');
+ set(handles.togglebutton_highpass, 'Value', 1);
+ set(handles.slider_highpass, 'Enable','on');
+ mvalueh = round(handles.mvalueh*10)/10;
+
+ if mvalueh<0.1
+ handles.mvalueh = 0.1;
+ end
+
+ set(handles.slider_highpass, 'Value', handles.mvalueh);
+ set(handles.edit_highpass, 'String', num2str(handles.mvalueh));
+ set(handles.checkbox_removedc, 'Enable', 'on')
+ set(handles.togglebutton_highpass, 'BackgroundColor', [1 1 0.5]);
+
+ %
+ % Roll off
+ %
+ set(handles.popupmenu_dboct, 'Enable', 'on');
+ set(handles.popupmenu_dbdec, 'Enable', 'on');
+ set(handles.popupmenu_order, 'Enable', 'on');
+
+ %
+ % Plot filter related responses
+ %
+ set(handles.radiobutton_freqr, 'Enable', 'on');
+ set(handles.radiobutton_impr, 'Enable', 'on');
+ set(handles.radiobutton_fdatafr, 'Enable', 'on');
+
+ % Update handles structure
+ guidata(hObject, handles);
+else
+ set(handles.togglebutton_highpass, 'Value', 0);
+ set(handles.slider_highpass, 'Value', 0);
+ set(handles.slider_highpass, 'Enable','off');
+ set(handles.edit_highpass, 'String', '0');
+ set(handles.edit_highpass, 'Enable', 'off');
+ set(handles.edit2_highpass, 'String', '---');
+ set(handles.edit2_highpass, 'Enable', 'off');
+ set(handles.checkbox_removedc, 'Enable', 'off')
+ %set(handles.edit_highpass, 'BackgroundColor', [0.75 0.75 0.75]);
+ set(handles.togglebutton_highpass, 'BackgroundColor', [0.8 0.8 0.75]);
+end
+if get(handles.radiobutton_fdatafr,'Value')
+ plotresponse_fd_data(hObject, eventdata, handles)
+else
+ plotresponsefilter(hObject, eventdata, handles);
+end
+
+%--------------------------------------------------------------------------
+function togglebutton_lowpass_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+ set(handles.edit_lowpass, 'Enable', 'on');
+ set(handles.edit2_lowpass, 'Enable', 'on');
+ set(handles.edit2_lowpass, 'BackgroundColor', [1 1 0.5]);
+ set(handles.edit2_lowpass, 'Enable', 'inactive');
+ set(handles.slider_lowpass, 'Enable','on');
+ fc = round(handles.mvaluel*10)/10;
+
+ if fc==0
+ fc = round(handles.maxsliders*5)/10;
+ end
+
+ set(handles.slider_lowpass, 'Value', fc);
+ set(handles.edit_lowpass, 'String', num2str(fc));
+ %set(handles.edit_lowpass, 'BackgroundColor', [1 1 1]);
+ set(handles.togglebutton_lowpass, 'BackgroundColor', [1 1 0.5]);
+
+ %
+ % Roll off
+ %
+ set(handles.popupmenu_dboct, 'Enable', 'on');
+ set(handles.popupmenu_dbdec, 'Enable', 'on');
+ set(handles.popupmenu_order, 'Enable', 'on');
+
+ %
+ % Plot filter related responses
+ %
+ set(handles.radiobutton_freqr, 'Enable', 'on');
+ set(handles.radiobutton_impr, 'Enable', 'on');
+ set(handles.radiobutton_fdatafr, 'Enable', 'on');
+else
+ set(handles.edit_lowpass, 'String', '0');
+ set(handles.edit_lowpass, 'Enable', 'off');
+ set(handles.edit2_lowpass, 'String', '---');
+ set(handles.edit2_lowpass, 'Enable', 'off');
+ set(handles.slider_lowpass, 'Enable','off');
+ set(handles.slider_lowpass, 'Value', 0);
+ %set(handles.edit_lowpass, 'BackgroundColor', [0.75 0.75 0.75]);
+ set(handles.togglebutton_lowpass, 'BackgroundColor', [0.8 0.8 0.75]);
+end
+if get(handles.radiobutton_fdatafr,'Value')
+ plotresponse_fd_data(hObject, eventdata, handles)
+else
+ plotresponsefilter(hObject, eventdata, handles);
+end
+
+%--------------------------------------------------------------------------
+function radiobutton_freqr_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+ set(handles.radiobutton_impr,'Value', 0);
+ set(handles.radiobutton_ufdatafr,'Value', 0);
+ set(handles.radiobutton_fdatafr,'Value', 0);
+ %set(handles.popupmenu_FRscale,'Value', 1);
+ set(handles.popupmenu_FRscale,'Enable', 'on');
+ set(handles.radiobutton_butter, 'Enable', 'on')
+ set(handles.radiobutton_fir, 'Enable', 'on')
+ set(handles.radiobutton_PM_notch,'Enable','on')
+ set(handles.radiobutton_ideal, 'Enable','on')
+ plotresponsefilter(hObject, eventdata, handles);
+else
+ set(handles.radiobutton_freqr,'Value', 1);
+end
+
+%--------------------------------------------------------------------------
+function radiobutton_impr_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+ set(handles.radiobutton_freqr,'Value', 0);
+ set(handles.radiobutton_ufdatafr,'Value', 0);
+ set(handles.radiobutton_fdatafr,'Value', 0);
+ %set(handles.popupmenu_FRscale,'Value', 1);
+ set(handles.popupmenu_FRscale,'Enable', 'off');
+ set(handles.radiobutton_butter, 'Enable', 'on')
+ set(handles.radiobutton_fir, 'Enable', 'on')
+ set(handles.radiobutton_PM_notch,'Enable','on')
+ set(handles.radiobutton_ideal, 'Enable','off')
+ plotresponsefilter(hObject, eventdata, handles);
+else
+ set(handles.radiobutton_impr,'Value', 1);
+end
+
+%--------------------------------------------------------------------------
+function radiobutton_ufdatafr_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+ set(handles.radiobutton_freqr,'Value', 0);
+ set(handles.radiobutton_impr,'Value', 0);
+ set(handles.radiobutton_fdatafr,'Value', 0);
+ % set(handles.popupmenu_FRscale,'Value', 1);
+ set(handles.popupmenu_FRscale,'Enable', 'on');
+ set(handles.radiobutton_butter, 'Enable', 'off')
+ set(handles.radiobutton_fir, 'Enable', 'off')
+ set(handles.radiobutton_PM_notch,'Enable','off')
+ set(handles.radiobutton_ideal, 'Enable','off')
+ drawnow
+ plotresponse_uf_data(hObject, eventdata, handles);
+else
+ set(handles.radiobutton_ufdatafr,'Value', 1);
+end
+
+%--------------------------------------------------------------------------
+function radiobutton_fdatafr_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+ set(handles.radiobutton_freqr,'Value', 0);
+ set(handles.radiobutton_impr,'Value', 0);
+ set(handles.radiobutton_ufdatafr,'Value', 0);
+ % set(handles.popupmenu_FRscale,'Value', 1);
+ set(handles.popupmenu_FRscale,'Enable', 'on');
+ set(handles.radiobutton_butter, 'Enable', 'on')
+ set(handles.radiobutton_fir, 'Enable', 'on')
+ set(handles.radiobutton_PM_notch,'Enable','on')
+ set(handles.radiobutton_ideal, 'Enable','on')
+ drawnow
+ plotresponse_fd_data(hObject, eventdata, handles);
+else
+ set(handles.radiobutton_fdatafr,'Value', 1);
+end
+
+%--------------------------------------------------------------------------
+function checkbox_boundary_Callback(hObject, eventdata, handles)
+if get(hObject, 'Value')
+
+ set(handles.edit_boundary,'Enable', 'on');
+ %set(handles.edit_boundary,'BackgroundColor', [1 1 1]);
+
+ if get(handles.radiobutton_butter, 'Value'); % 0 means Butterworth
+ typef = 0;
+ elseif get(handles.radiobutton_fir, 'Value'); % 1 means FIR
+ typef = 1;
+ elseif get(handles.radiobutton_PM_notch, 'Value'); % 2 means PM Notch
+ typef = 2;
+ end
+ if typef==1 || typef==2
+
+ %
+ % FILTER order
+ %
+ order = getorder(handles);
+
+ minboundarysamdist = handles.minboundarysamdist;
+
+ if get(handles.checkbox_boundary,'Value')
+ if minboundarysamdist<3*order
+ BackERPLABcolor = [ 1 1 0];
+ question = ['You have set the checkbox for filtering between boundary events.\n'...
+ 'Event codes ''boundary'' or -99 were found in you dataset.\n\n'...
+ 'However, at least one of the segments among boundaries \n'...
+ 'has less samples than 3 times the filter order you are currently setting.\n\n'...
+ 'You may either decrese the order of the filter - if it is possible - (recommended),\n'...
+ 'or uncheck the option for filtering between boundary events (not recommended).'];
+ questionstr = sprintf(question);
+ titlex = 'EStudio: Filter order vs number of samples';
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor)
+ button = questdlg(questionstr, titlex,'OK','OK');
+ set(0,'DefaultUicontrolBackgroundColor',oldcolor)
+ return
+ end
+ end
+ end
+else
+ set(handles.edit_boundary,'Enable', 'off');
+ set(handles.edit_boundary,'BackgroundColor', [0.75 0.75 0.75]);
+end
+
+%--------------------------------------------------------------------------
+function checkbox_notch_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function no_filter(hObject,handles, msgtx)
+plot(1, 1, 'w');
+text(0.32,0.5, msgtx,'FontSize',18, 'color', [1 0 0])
+axis([0 1 0 1])
+set(handles.slider_highpass, 'Value', 0);
+set(handles.slider_lowpass, 'Value', 0);
+set(handles.slider_highpass, 'Enable', 'off')
+set(handles.slider_lowpass, 'Enable', 'off')
+set(handles.togglebutton_highpass, 'Value', 0)
+set(handles.togglebutton_lowpass, 'Value', 0)
+set(handles.edit_highpass,'String','0')
+set(handles.edit_highpass,'Enable','off')
+set(handles.edit2_highpass,'String','---')
+set(handles.edit2_highpass,'Enable','off')
+set(handles.edit_lowpass,'String','0')
+set(handles.edit_lowpass,'Enable','off')
+set(handles.edit2_lowpass,'String','---')
+set(handles.edit2_lowpass,'Enable','off')
+set(handles.checkbox_removedc, 'Enable','off')
+handles.memvalueh = 0.1;
+handles.mvalueh = 0.1; % memory value highpass
+fc = round(handles.maxsliders*5)/10;
+handles.memvaluel = fc;
+handles.mvaluel = fc; % memory value lowpass
+
+% Update handles structure
+guidata(hObject, handles);
+return
+
+%##########################################################################
+%##########################################################################
+%##########################################################################
+%##########################################################################
+
+function [hfr labelf] = plotresponsefilter(hObject, eventdata, handles)
+
+%
+% IMPORTANT: This function plot the filter response of FILTFILT function only.
+%
+hfr = [];
+valueh = get(handles.slider_highpass, 'Value');
+valuel = get(handles.slider_lowpass, 'Value');
+axes(handles.axes1);
+
+if valueh==0 && valuel==0
+ if get(handles.radiobutton_freqr, 'Value') ||...
+ get(handles.radiobutton_impr, 'Value') ||...
+ get(handles.radiobutton_fdatafr, 'Value')
+ msgtx = '--NO FILTERING--';
+ no_filter(hObject, handles, msgtx)
+ end
+ return
+else
+ xmaxp = handles.xmaxfreqr;
+ if nargout==0
+ %if ~isempty(xmaxp)
+ if get(handles.radiobutton_freqr, 'Value') || get(handles.radiobutton_impr, 'Value')
+ % posaxes1 = get(gca,'YLim');
+ msgtx = 'Working, please wait...';
+ text(mean(xmaxp)/3, 1.12, msgtx,'FontSize',14, 'color', 'k')
+ drawnow
+ end
+ %end
+ end
+end
+
+fs = handles.fs;
+fnyq = fs/2;
+
+%
+% FILTER order
+%
+order = getorder(handles);
+
+if isempty(order)
+ disp('Still busy...')
+ return
+end
+if get(handles.radiobutton_butter, 'Value'); % 0 means Butterworth
+ typef = 0;
+elseif get(handles.radiobutton_fir, 'Value'); % 1 means FIR
+ typef = 1;
+elseif get(handles.radiobutton_PM_notch, 'Value'); % 2 means PM Notch
+ typef = 2;
+end
+
+n = round(fnyq); % number of points for frequency response.
+hpzoom = diff(str2num(char(get(handles.edit_xmaxplot,'String'))));
+
+%
+% Augmented number of points for frequency response.
+%
+if hpzoom<=5
+ n = n*50;
+elseif hpzoom<=0.5
+ n = n*1000;
+end
+if typef==2 % PM Notch
+ valuel = valueh;
+end
+
+bt = [];
+at = [];
+
+[bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, order, valuel, valueh, fs);
+
+if ~v % something is wrong or turned off
+ disp('Filter coefficient calculation failed...')
+ if get(handles.radiobutton_freqr, 'Value') ||...
+ get(handles.radiobutton_impr, 'Value') ||...
+ get(handles.radiobutton_fdatafr, 'Value')
+ msgtx = '--NO FILTERING--';
+ no_filter(hObject, handles, msgtx)
+ end
+
+ handles.autorder = 0;
+ % Update handles structure
+ guidata(hObject, handles);
+ return
+else
+ autorder = handles.autorder;
+end
+if ~isempty(orderx)
+ if orderx~=order
+ order = orderx;
+ str = ['\nWARNING: Odd order symmetric FIR filters must have a gain of zero \n'...
+ 'at the Nyquist frequency. The order has been increased to %g.\n'];
+ fprintf(str, order);
+ end
+end
+
+%
+% Automin for FIR
+%
+if autorder == 1 && typef==1
+ slidersoff(hObject, eventdata, handles)
+ orderlist = cellstr(get(handles.popupmenu_order,'String'));
+ orderlist{1} = 'automin...';
+ set(handles.popupmenu_order, 'String', orderlist)
+ set(handles.popupmenu_order, 'Value', 1)
+ set(handles.text_halfamp, 'String','updating...');
+ set(handles.text_halfpow, 'String','updating...');
+ drawnow
+ xdB_at_fx = 0;
+ order = 4;
+ j=1;
+
+ while mean(xdB_at_fx)~=-6 && order<=4096-2 && j<=2000% && get(handles.popupmenu_order,'Value')==1
+
+ if mean(xdB_at_fx)==0
+ order = order + 32;
+ elseif mean(xdB_at_fx)>-3 && mean(xdB_at_fx)<0
+ order = order + 8;
+ else
+ order = order + 4;
+ end
+
+ [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, order, valuel, valueh, fs);
+
+ if isempty(xdB_at_fx)
+ xdB_at_fx = 0;
+ end
+ if v
+ if orderx~=order
+ if mod(orderx,4)==0
+ order = orderx;
+ else
+ order = orderx + 2;
+ end
+ str = ['\nWARNING: Odd order symmetric FIR filters must have a gain of zero \n'...
+ 'at the Nyquist frequency. The order has been increased to %g.\n'];
+ fprintf(str, order);
+ end
+ end
+ end
+ if mean(xdB_at_fx)==-6
+ orderlist{1} = ['automin:' num2str(order)];
+ set(handles.popupmenu_order, 'String', orderlist)
+ set(handles.popupmenu_order, 'Value', 1)
+ disp('min order was found.')
+ iswarnroff = 0;
+ else
+ orderlist{1} = 'automin';
+ set(handles.popupmenu_order, 'String', orderlist)
+ set(handles.popupmenu_order, 'Value', length(orderlist))
+ handles.autorder = 0;
+ iswarnroff = 1; % atenuation at frquency cutoff was impposible...
+
+ % Update handles structure
+ guidata(hObject, handles);
+ disp('min order was not found...')
+ end
+
+ sliderson(hObject, eventdata, handles)
+ drawnow
+else
+ if mean(xdB_at_fx)==-6
+ iswarnroff =0;
+ else
+ iswarnroff =1;
+ end
+end
+if ~v % something is wrong or turned off (1 means everything is ok)
+ if get(handles.radiobutton_freqr, 'Value') ||...
+ get(handles.radiobutton_impr, 'Value') ||...
+ get(handles.radiobutton_fdatafr, 'Value')
+
+ msgtx = '--NO FILTERING--';
+ no_filter(hObject, handles, msgtx)
+ end
+ disp('Filter coefficient calculation failed....')
+ handles.autorder = 0;
+ % Update handles structure
+ guidata(hObject, handles);
+ return
+end
+
+%
+% Final filter coefficients
+%
+if size(bt,1)==2
+ if strcmpi(labelf,'Band-Pass')
+ % cascade filter transfer function
+ b = conv(bt(1,:),bt(2,:));
+ a = conv(at(1,:),at(2,:));
+ else
+ % parallel filter transfer function
+ b = conv(bt(1,:),at(2,:)) + conv(bt(2,:),at(1,:));
+ a = conv(at(1,:),at(2,:));
+ end
+else
+ b = bt;
+ a = at;
+end
+
+%
+% Half power cuttoff (-3 dB) (ONLY FOR FILTFILT!)
+%
+if ~isempty(frec3dB)
+ if strcmpi(labelf, 'Low-pass')
+ f3str = sprintf('%7.2f', frec3dB);
+ set(handles.edit2_highpass,'String','---')
+ set(handles.edit2_highpass,'Enable','off')
+ set(handles.edit2_lowpass,'String', f3str)
+ set(handles.edit2_lowpass, 'BackgroundColor', [1 1 0.5]);
+ elseif strcmpi(labelf, 'High-pass')
+ f3str = sprintf('%7.2f', frec3dB);
+ set(handles.edit2_highpass,'String',f3str)
+ set(handles.edit2_highpass, 'BackgroundColor', [1 1 0.5]);
+ set(handles.edit2_lowpass,'String', '---')
+ set(handles.edit2_lowpass,'Enable','off')
+ else
+ try
+ f3str1 = sprintf('%7.2f', frec3dB(1));
+ f3str2 = sprintf('%7.2f', frec3dB(2));
+ set(handles.edit2_highpass,'String', f3str2)
+ set(handles.edit2_lowpass,'String', f3str1)
+ %set(handles.edit2_lowpass, 'BackgroundColor', [1 1 0.5]);
+ set(handles.edit2_highpass, 'BackgroundColor', [1 1 0.5]);
+ set(handles.edit2_lowpass, 'BackgroundColor', [1 1 0.5]);
+ catch
+ set(handles.edit2_highpass,'String','---')
+ set(handles.edit2_lowpass,'String', '---')
+ set(handles.edit2_highpass,'Enable','off')
+ set(handles.edit2_lowpass,'Enable','off')
+ end
+ end
+else
+ set(handles.edit2_highpass,'String','---')
+ set(handles.edit2_lowpass,'String','---')
+ set(handles.edit2_highpass,'Enable','off')
+ set(handles.edit2_lowpass,'Enable','off')
+end
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Filter responses. Thanks to Sean Little from MathWorks Technical Support Department.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%
+% filtfilt frequency response
+%
+[hfr,f1] = freqz(b,a,n,fs);
+hfr = abs(hfr).^2; % Filter responses is squared in order to fit with FILTFILT
+
+% filtfilt impulse response
+[hira,f3] = freqz(b,a,n,'whole',fs);
+hir2 = abs(hira).^2;
+hir = ifft(hir2);
+
+%
+% Gain constraint. Gain should be close to 1 at the passband region.
+%
+gain_postL = 1-0.05; % 5% criteria
+gain_postU = 1+0.05; % 5% criteria
+
+if max(abs(hfr))>=gain_postL && max(abs(hfr))<=gain_postU && (max(abs(hfr))-min(abs(hfr)))>0.95
+
+ iswarngain = 0; % gain is fine
+
+ %
+ % Slider memory
+ %
+ handles.memvaluel = round(valuel);
+ handles.memvalueh = round(valueh);
+ handles.mem6dbl = num2str(ceil(str2num(get(handles.edit_lowpass,'String'))));
+ handles.mem6dbh = num2str(floor(str2num(get(handles.edit_highpass,'String'))));
+ handles.mem3dbl = num2str(ceil(str2num(get(handles.edit2_lowpass,'String'))));
+ handles.mem3dbh = num2str(floor(str2num(get(handles.edit2_highpass,'String'))));
+
+elseif max(abs(hfr))>=gain_postL && max(abs(hfr))<=gain_postU && (max(abs(hfr))-min(abs(hfr)))<=0.75
+ iswarngain = 3;
+ xdB_at_fx = [];
+else
+ if max(abs(hfr))=4096
+ BackERPLABcolor = [ 1 1 0];
+
+ question = ['Unable to achieve specified cutoff (-6dB). Higher filter order is needed,\n'...
+ 'but order greater than 4096 is not allowed for this ERPLAB version.\n'...
+ 'You may either select a wider passband with automin (recommended),\n'...
+ 'or turn off automin and leave with the reduced attenuation (not recommended)'];
+
+ questionstr = sprintf(question);
+ titlex = 'EStudio: Filter order';
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor)
+ button = questdlg(questionstr, titlex,'OK','Reset filters','OK');
+ set(0,'DefaultUicontrolBackgroundColor',oldcolor)
+
+ %
+ % reset order
+ %
+ orderlist = cellstr(get(handles.popupmenu_order, 'String'));
+ orderindx = get(handles.popupmenu_order, 'Value');
+ order = str2num(strrep(orderlist{orderindx},'automin:',''));
+ orderlist{1} = 'automin';
+ [tfx, posord] = ismember_bc2(order,[-1 4:4:4096]);
+
+ set(handles.popupmenu_order, 'String',orderlist)
+ set(handles.popupmenu_order, 'Value',posord)
+ set(handles.popupmenu_dboct, 'String','---')
+ set(handles.popupmenu_dbdec, 'String','---')
+ set(handles.popupmenu_dboct, 'Value',1)
+ set(handles.popupmenu_dbdec, 'Value',1)
+ handles.autorder = 0;
+
+ if strcmpi(button,'OK')
+ set(handles.slider_highpass, 'Value', handles.memvalueh);
+ set(handles.slider_lowpass, 'Value', handles.memvaluel);
+ chksliders(hObject, eventdata, handles)
+ set(handles.edit_highpass, 'String', handles.mem6dbh);
+ set(handles.edit_lowpass, 'String', handles.mem6dbl);
+ set(handles.edit2_highpass, 'String', handles.mem3dbh);
+ set(handles.edit2_lowpass, 'String', handles.mem3dbl);
+ set(handles.edit2_highpass, 'BackgroundColor', [1 1 0.5]);
+ set(handles.edit2_lowpass, 'BackgroundColor', [1 1 0.5]);
+ sliderson(hObject, eventdata, handles)
+
+ % Update handles structure
+ guidata(hObject, handles);
+ plotresponsefilter(hObject, eventdata, handles);
+ return
+ else
+ sliderson(hObject, eventdata, handles)
+ set(handles.slider_highpass, 'Value', 0);
+ set(handles.slider_lowpass, 'Value', fnyq/2);
+ chksliders(hObject, eventdata, handles)
+ handles.memvalueh = 0.1;
+ handles.mvalueh = 0.1; % memory value highpass
+
+ % Update handles structure
+ guidata(hObject, handles);
+ plotresponsefilter(hObject, eventdata, handles);
+ return
+ end
+ end
+elseif iswarngain~=0 && iswarnroff==0
+ if autorder == 1 && typef==0
+ slidersoff(hObject, eventdata, handles)
+
+ %
+ % Filter order
+ %
+ order = getorder(handles);
+
+ if isempty(order)
+ disp('Ops, I could not read the filter order...')
+ sliderson(hObject, eventdata, handles)
+ return
+ end
+
+ order = order + 2; % increase the order
+ ishopermission = handles.ishopermission; % permission for higher order when high-pass filter cutoff is <=0.5
+
+ if order>2 && order<=8 && valueh>0 && valueh<=0.5 && ~ishopermission
+ question = ['We do not recommend a filter order greater than 2 for a Butterworth filter\n '...
+ 'when the high-pass cutoff is <= 0.5 Hz\n'...
+ 'Continue anyway?'];
+ titlex = 'EStudio: Filter order';
+ button = askquest(sprintf(question), titlex);
+
+ if ~strcmpi(button,'yes')
+ set(handles.slider_highpass, 'Value', 0);
+ set(handles.slider_lowpass, 'Value', handles.memvaluel);
+
+ if handles.memvaluel==0
+ set(handles.slider_lowpass, 'Enable', 'off');
+ set(handles.togglebutton_lowpass,'Value',0)
+ set(handles.edit_lowpass, 'String', '0');
+ set(handles.edit_lowpass, 'Enable', 'off');
+ set(handles.edit2_lowpass, 'String', '---');
+ set(handles.edit2_lowpass, 'Enable', 'off');
+ else
+ set(handles.edit_lowpass, 'String', handles.mem6dbl);
+ set(handles.edit2_lowpass, 'String', handles.mem3dbl);
+ set(handles.edit2_lowpass, 'BackgroundColor', [1 1 0.5]);
+ end
+
+ set(handles.edit_highpass, 'String', handles.mem6dbh);
+ set(handles.edit2_highpass, 'String', handles.mem3dbh);
+ set(handles.edit2_highpass, 'BackgroundColor', [1 1 0.5]);
+ set(handles.popupmenu_order, 'Value', 2);
+ handles.autorder = 0;
+ handles.ishopermission =0;
+ chksliders(hObject, eventdata, handles)
+
+ % Update handles structure
+ guidata(hObject, handles);
+ plotresponsefilter(hObject, eventdata, handles);
+ sliderson(hObject, eventdata, handles)
+ return
+ else
+ chksliders(hObject, eventdata, handles)
+ handles.ishopermission = 1;
+ % Update handles structure
+ guidata(hObject, handles);
+ end
+
+ sliderson(hObject, eventdata, handles)
+ return
+ end
+ if order>8
+
+ BackERPLABcolor = [ 1 1 0];
+
+ if iswarngain==3
+ line01 = 'You are losing stopband attenuation!';
+ else
+ line01 = 'You are losing passband gain!';
+ end
+
+ question = ['WARNING: %s \n\n'...
+ 'In order to use the automin feature, a higher Butterworth filter order is needed, '...
+ 'but an order greater than 8 is not allowed for this ERPLAB version. '...
+ 'You may select a wider passband with automin (recommended), '...
+ 'or turn off automin and leave with the reduced gain (not recommended).'];
+
+ titlex = 'EStudio: Filter order';
+
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor)
+ button = questdlg(sprintf(question, line01), titlex,'OK','Reset filters','OK');
+ set(0,'DefaultUicontrolBackgroundColor',oldcolor)
+
+ %
+ % reset order
+ %
+ orderlist = cellstr(get(handles.popupmenu_order, 'String'));
+ orderindx = get(handles.popupmenu_order, 'Value');
+ order = str2num(strrep(orderlist{orderindx},'automin:',''));
+ orderlist{1} = 'automin';
+ [tfx, posord] = ismember_bc2(order,[-1 2 4 6 8]);
+
+ set(handles.popupmenu_order, 'String',orderlist)
+ set(handles.popupmenu_order, 'Value',posord)
+ set(handles.popupmenu_dboct, 'Value',posord-1)
+ set(handles.popupmenu_dbdec, 'Value',posord-1)
+ handles.autorder = 0;
+
+ if strcmpi(button,'OK')
+ set(handles.slider_highpass, 'Value', handles.memvalueh);
+ set(handles.slider_lowpass, 'Value', handles.memvaluel);
+ chksliders(hObject, eventdata, handles)
+ set(handles.edit_highpass, 'String', handles.mem6dbh);
+ set(handles.edit_lowpass, 'String', handles.mem6dbl);
+ set(handles.edit2_highpass, 'String', handles.mem3dbh);
+ set(handles.edit2_lowpass, 'String', handles.mem3dbl);
+ set(handles.edit2_highpass, 'BackgroundColor', [1 1 0.5]);
+ set(handles.edit2_lowpass, 'BackgroundColor', [1 1 0.5]);
+ % Update handles structure
+ guidata(hObject, handles);
+
+ sliderson(hObject, eventdata, handles)
+ plotresponsefilter(hObject, eventdata, handles);
+ return
+ else
+ sliderson(hObject, eventdata, handles)
+ set(handles.slider_highpass, 'Value', 0);
+ set(handles.slider_lowpass, 'Value', fnyq/2);
+ chksliders(hObject, eventdata, handles)
+ handles.memvalueh = 0.1;
+ handles.mvalueh = 0.1; % memory value highpass
+
+ ordervector = 2:2:8;
+ set(handles.popupmenu_order,'String', char([{'automin'}; cellstr(num2str(ordervector'))])) % set order list
+ set(handles.popupmenu_order,'Value', 2);
+
+ % Update handles structure
+ guidata(hObject, handles);
+
+ plotresponsefilter(hObject, eventdata, handles);
+ return
+ end
+ else
+ rolloffindx = get(handles.popupmenu_dboct,'Value');
+ rolloffindx = rolloffindx + 1;
+ set(handles.popupmenu_dboct,'Value', rolloffindx);
+ set(handles.popupmenu_dbdec,'Value', rolloffindx);
+ end
+
+ orderlist = cellstr(get(handles.popupmenu_order, 'String'));
+ orderlist{1} = ['automin:' num2str(order)];
+ set(handles.popupmenu_order, 'String', orderlist)
+ set(handles.popupmenu_order, 'Value', 1)
+ sliderson(hObject, eventdata, handles)
+
+ plotresponsefilter(hObject, eventdata, handles);
+ return
+ end
+end
+
+% hfig = axes(handles.axes1);
+
+if get(handles.radiobutton_freqr,'Value')
+ h = hfr;
+ f = f1;
+ color = [0 0 0.75];
+ FRscale = get(handles.popupmenu_FRscale, 'Value');
+
+ if FRscale==1
+ ymax = 1.25;
+ ymin = -0.075; %6.25% of ymax -
+ ymaxb = 1;
+ yminb = 0;
+ plot(f, h, 'linewidth', 2, 'LineSmoothing','on','Color', color)
+ ylabel('passband gain')
+ else
+ ymax = 10;
+ ymin = -65;
+ ymaxb = 0;
+ yminb = -90;
+ plot(f, 20*log10(h), 'linewidth', 2, 'LineSmoothing','on','Color', color)
+ ylabel('passband gain in dB')
+ end
+
+ xlabel('frequency (Hz)')
+
+ if get(handles.radiobutton_ideal, 'Value')
+ drawidealresp(handles, labelf, fnyq, valuel, valueh, yminb, ymaxb)
+ end
+ if typef~=2
+ if iswarngain==1
+ yym = max(hfr);
+
+ if yym>1
+ yym=0.3;
+ end
+
+ xxm = hpzoom/5;
+ text(xxm, yym+0.2,' Losing passband gain!','FontSize',10)
+ text(xxm, yym+0.1,' Increase the order of the filter or select automin.','FontSize',10)
+ set(gca,'Color', 'y')
+
+ elseif iswarngain==2
+
+ yym = max(hfr);
+
+ if yym>1
+ yym=0.3;
+ end
+
+ xxm = hpzoom/5;
+ text(xxm, yym+0.2,' Passband gain of 1 was overpassed!','FontSize',10)
+ text(xxm, yym+0.1,' Increase the order of the filter or select automin.','FontSize',10)
+ set(gca,'Color', 'y')
+
+ elseif iswarngain==3
+
+ yym = max(hfr);
+
+ if yym>1
+ yym=0.3;
+ end
+
+ xxm = hpzoom/5;
+ text(xxm, yym+0.2,' Losing stopband attenuation','FontSize',10)
+ text(xxm, yym+0.1,' Increase the order of the filter or select automin.','FontSize',10)
+ set(gca,'Color', 'y')
+
+ elseif iswarnroff==0 && iswarngain==0
+ set(gca,'Color', 'w')
+ end
+ else
+ set(gca,'Color', 'w')
+ end
+
+elseif get(handles.radiobutton_impr,'Value')
+ h = hir; % impulse
+ f = f3; %1:length(h);
+ ymax = max(h)*1.2;
+ ymin = min(h)*1.2;
+ color = [0.78 0 0.1];
+ stem(f, h, 'linewidth', 2, 'Color', color);
+ xlabel('time (msec)')
+ ylabel('amplitude')
+else
+ return
+end
+
+%
+% True attenuation value at specified cutoff frequency (it must be -6db, otherwise...)
+%
+if ~isempty(xdB_at_fx)
+
+ attvaldB = round(mean(xdB_at_fx));
+
+ if attvaldB==-6 && typef==0
+ string4HA = ['Half-Amp(' num2str(attvaldB) 'dB)'];
+ coloratt = 'k';
+ else
+ if typef~=2
+ attvalgain = 10^(attvaldB/20);
+ string4HA = [sprintf('%.2f',attvalgain) '-Amp(' num2str(attvaldB) 'dB)'];
+
+ if attvaldB==-6 && typef==1
+ coloratt = 'k';
+ else
+ coloratt = 'r';
+ end
+ else
+ string4HA = 'Center frequency';
+ coloratt = 'k';
+ end
+ end
+ set(handles.text_halfamp,'String', string4HA, 'ForegroundColor', coloratt)
+ set(handles.text_halfpow,'String', 'Half-Power(-3dB)', 'ForegroundColor', 'k')
+else
+ set(handles.text_halfamp,'String', '--- ???dB ---', 'ForegroundColor', 'r')
+ set(handles.text_halfpow,'String', '--- ???dB ---', 'ForegroundColor', 'r')
+end
+
+%
+% Axis limits for frequency response
+%
+xmaxp = str2num(char(get(handles.edit_xmaxplot, 'String')));
+
+if isempty(xmaxp)
+ xmaxp = [0 max(f)];
+ if get(handles.radiobutton_fdatafr,'Value') || get(handles.radiobutton_freqr,'Value')
+ handles.xmaxfreqr = xmaxp;
+ else
+ handles.xmaxpimpz = xmaxp;
+ end
+else
+ if get(handles.radiobutton_fdatafr,'Value') || get(handles.radiobutton_freqr,'Value')
+ xmaxp = handles.xmaxfreqr;
+ else
+ xmaxp = handles.xmaxpimpz;
+ end
+end
+
+set(handles.edit_xmaxplot, 'String', num2str(xmaxp));
+
+%
+% Axis limits
+%
+axis([xmaxp ymin ymax])
+hle = legend(labelf);
+set(hle, 'Color', 'none', 'Box', 'off')
+handles.memvalueh = valueh;
+handles.mvaluel = valuel;
+handles.morder = order;
+handles.iswarngain = iswarngain;
+handles.iswarnroff = iswarnroff;
+sliderson(hObject, eventdata, handles)
+handles.datafr.yf = hfr;
+
+if typef==1 || typef==2
+
+ minboundarysamdist = handles.minboundarysamdist;
+
+ if get(handles.checkbox_boundary,'Value')
+ if minboundarysamdist<3*order
+ BackERPLABcolor = [ 1 1 0];
+ question = ['You have set the checkbox for filtering between boundary events.\n'...
+ 'Event codes ''boundary'' or -99 were found in your dataset.\n\n'...
+ 'However, at least one of the segments among boundaries \n'...
+ 'has fewer samples than 3 times the filter order you are currently setting.\n\n'...
+ 'You may either decrese the order of the filter - if it is possible - (recommended),\n'...
+ 'or uncheck the option for filtering between boundary events.'];
+ questionstr = sprintf(question);
+ titlex = 'EStudio: Filter order vs number of samples';
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor)
+ button = questdlg(questionstr, titlex,'OK','OK');
+ set(0,'DefaultUicontrolBackgroundColor',oldcolor)
+ return
+ end
+ end
+end
+
+% Update handles structure
+guidata(hObject, handles);
+
+% -------------------------------------------------------------------------
+function drawidealresp(handles, labelf, fnyq, valuel, valueh, yminb, ymaxb)
+
+axes(handles.axes1)
+
+% draw ideal filter response
+%
+colorband = [0.9922 0.9176 0.7961];
+alphaval = 0.7;
+
+if ismember_bc2(labelf, {'Low-pass','High-pass','Band-pass'})
+
+ if strcmpi(labelf,'High-pass')
+ valuelx = fnyq;
+ else
+ valuelx = valuel;
+ end
+
+ patch([valueh valueh valuelx valuelx],[yminb ymaxb ymaxb yminb],'r',...
+ 'facecolor',colorband,...
+ 'edgecolor',colorband,...
+ 'facealpha',alphaval)
+elseif ismember_bc2(labelf,'Stop-band (Parks-McClellan Notch)')
+ patch([0 0 valuel-1.5 valuel-1.5],[yminb ymaxb ymaxb yminb],'r',...
+ 'facecolor',colorband,...
+ 'edgecolor',colorband,...
+ 'facealpha',alphaval)
+ patch([valueh+1.5 valueh+1.5 fnyq fnyq],[yminb ymaxb ymaxb yminb],'r',...
+ 'facecolor',colorband,...
+ 'edgecolor',colorband,...
+ 'facealpha',alphaval)
+else
+ patch([0 0 valuel valuel],[yminb ymaxb ymaxb yminb],'r',...
+ 'facecolor',colorband,...
+ 'edgecolor',colorband,...
+ 'facealpha',alphaval)
+ patch([valueh valueh fnyq fnyq],[yminb ymaxb ymaxb yminb],'r',...
+ 'facecolor',colorband,...
+ 'edgecolor',colorband,...
+ 'facealpha',alphaval)
+end
+return
+
+% -------------------------------------------------------------------------
+function popupmenu_dboct_Callback(hObject, eventdata, handles)
+
+dboct = get(handles.popupmenu_dboct,'Value');
+
+if get(handles.radiobutton_butter,'Value')
+ set(handles.popupmenu_order,'Value', dboct+1)
+ set(handles.popupmenu_dbdec,'Value', dboct)
+end
+
+%
+% Plot corresponding response
+%
+if get(handles.radiobutton_fdatafr,'Value')
+ plotresponse_fd_data(hObject, eventdata, handles)
+elseif get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_impr,'Value')
+ plotresponsefilter(hObject, eventdata, handles);
+end
+
+%--------------------------------------------------------------------------
+function popupmenu_dboct_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function popupmenu_dbdec_Callback(hObject, eventdata, handles)
+
+dbdec = get(handles.popupmenu_dbdec,'Value');
+
+if get(handles.radiobutton_butter,'Value')
+ set(handles.popupmenu_order,'Value', dbdec+1);
+ set(handles.popupmenu_dboct,'Value', dbdec);
+end
+
+%
+% Plot corresponding response
+%
+if get(handles.radiobutton_fdatafr,'Value')
+ plotresponse_fd_data(hObject, eventdata, handles)
+elseif get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_impr,'Value')
+ plotresponsefilter(hObject, eventdata, handles);
+end
+
+%--------------------------------------------------------------------------
+function popupmenu_dbdec_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function radiobutton_butter_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+
+ unsetnotchpm(hObject, eventdata, handles)
+
+ if get(handles.togglebutton_lowpass,'Value')==1 && get(handles.togglebutton_highpass,'Value')==0
+ set(handles.checkbox_removedc, 'Value', 0);
+ set(handles.checkbox_removedc, 'Enable', 'off');
+ set(handles.slider_highpass, 'Value', 0);
+ set(handles.slider_highpass, 'Enable', 'off')
+ set(handles.togglebutton_highpass, 'Value', 0)
+ set(handles.edit_highpass,'String','0')
+ set(handles.edit_highpass,'Enable','off')
+ %set(handles.edit_highpass, 'BackgroundColor', [0.75 0.75 0.75]);
+ set(handles.togglebutton_highpass, 'BackgroundColor', [0.8 0.8 0.75]);
+
+ elseif get(handles.togglebutton_lowpass,'Value')==0 && get(handles.togglebutton_highpass,'Value')==1
+ colorband = [0.9922 0.9176 0.7961];
+ set(handles.checkbox_removedc, 'Value', 1);
+ set(handles.checkbox_removedc, 'Enable', 'on');
+ set(handles.slider_highpass, 'Enable', 'on')
+ set(handles.togglebutton_highpass, 'Value', 1)
+ %set(handles.edit_highpass, 'BackgroundColor', [1 1 1]);
+ end
+
+ set(handles.radiobutton_fir,'Value',0)
+ ordervector = 2:2:8;
+ set(handles.popupmenu_order,'Enable','on')
+ set(handles.popupmenu_dboct,'Enable','on')
+ set(handles.popupmenu_dbdec,'Enable','on')
+ set(handles.popupmenu_order,'String', char([{'automin'}; cellstr(num2str(ordervector'))])) % set order list
+ set(handles.popupmenu_dboct,'String', num2str(6*ordervector')) % set db/oct list
+ set(handles.popupmenu_dbdec,'String', num2str(20*ordervector')) % set db/dec list
+ set(handles.popupmenu_order,'Value',2)
+ set(handles.popupmenu_dboct,'Value',1)
+ set(handles.popupmenu_dbdec,'Value',1)
+ if get(handles.radiobutton_ufdatafr,'Value')
+ plotresponse_uf_data(hObject, eventdata, handles);
+ else
+ plotresponsefilter(hObject, eventdata, handles);
+ end
+else
+ set(handles.radiobutton_butter,'Value',1)
+end
+
+%--------------------------------------------------------------------------
+function radiobutton_fir_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+
+ unsetnotchpm(hObject, eventdata, handles)
+
+ if get(handles.togglebutton_lowpass,'Value')==1 && get(handles.togglebutton_highpass,'Value')==0
+ set(handles.checkbox_removedc, 'Value', 0);
+ set(handles.checkbox_removedc, 'Enable', 'off');
+ set(handles.slider_highpass, 'Value', 0);
+ set(handles.slider_highpass, 'Enable', 'off')
+ set(handles.togglebutton_highpass, 'Value', 0)
+ set(handles.edit_highpass,'String','0')
+ %set(handles.edit_highpass, 'BackgroundColor', [0.75 0.75 0.75]);
+ set(handles.togglebutton_highpass, 'BackgroundColor', [0.8 0.8 0.75]);
+ elseif get(handles.togglebutton_lowpass,'Value')==0 && get(handles.togglebutton_highpass,'Value')==1
+ colorband = [0.9922 0.9176 0.7961];
+ set(handles.checkbox_removedc, 'Value', 1);
+ set(handles.checkbox_removedc, 'Enable', 'on');
+ set(handles.slider_highpass, 'Enable', 'on')
+ set(handles.togglebutton_highpass, 'Value', 1)
+ %set(handles.edit_highpass, 'BackgroundColor', [1 1 1])
+ else
+ %...
+ end
+
+ highpasscutoff = str2num(get(handles.edit_highpass, 'string'));
+ %lowpasscutoff = str2num(get(handles.edit_lowpass, 'string'));
+
+ if highpasscutoff>0 && highpasscutoff<0.2
+ set(handles.edit_highpass, 'string','0.4')
+ set(handles.slider_highpass, 'Value', 0.4)
+ end
+
+ set(handles.radiobutton_butter,'Value',0)
+ ordervector = 4:4:4096;
+ set(handles.popupmenu_order,'String', char([{'automin'}; cellstr(num2str(ordervector'))])) % set order list
+ set(handles.popupmenu_dboct,'String', '---') % set db/oct list
+ set(handles.popupmenu_dbdec,'String', '---') % set db/dec list
+ set(handles.popupmenu_order,'Value',10)
+ set(handles.popupmenu_dboct,'Value',1)
+ set(handles.popupmenu_dbdec,'Value',1)
+
+ handles.ishopermission = 0;
+ % Update handles structure
+ guidata(hObject, handles);
+ if get(handles.radiobutton_ufdatafr,'Value')
+ plotresponse_uf_data(hObject, eventdata, handles);
+ else
+ plotresponsefilter(hObject, eventdata, handles);
+ end
+else
+ set(handles.radiobutton_fir,'Value',1)
+end
+
+%--------------------------------------------------------------------------
+function radiobutton_PM_notch_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+ valhp = get(handles.edit_highpass,'String');
+ vallp = get(handles.edit_lowpass,'String');
+ handles.valhp = valhp;
+ handles.vallp = vallp;
+
+ % Update handles structure
+ guidata(hObject, handles);
+ setnotchpm(handles)
+ if get(handles.radiobutton_ufdatafr,'Value')
+ plotresponse_uf_data(hObject, eventdata, handles);
+ else
+ plotresponsefilter(hObject, eventdata, handles);
+ end
+else
+ set(handles.radiobutton_PM_notch,'Value',1)
+end
+
+%--------------------------------------------------------------------------
+function radiobutton_gaussian_Callback(hObject, eventdata, handles)
+
+%------------------------------------------------------------------------
+function setnotchpm(handles)
+
+freqdef = handles.freqdef;
+set(handles.radiobutton_butter,'Value',0)
+set(handles.radiobutton_fir,'Value',0)
+set(handles.slider_highpass, 'Enable', 'on')
+set(handles.slider_highpass, 'Value', freqdef);
+set(handles.slider_lowpass, 'Value', freqdef);
+set(handles.slider_lowpass, 'Visible', 'off')
+set(handles.togglebutton_highpass, 'Value', 0)
+set(handles.togglebutton_lowpass, 'Value', 0)
+set(handles.togglebutton_lowpass, 'Visible', 'off')
+set(handles.togglebutton_highpass, 'Visible', 'off')
+set(handles.edit_highpass,'Enable','on')
+set(handles.edit_highpass,'String',num2str(freqdef))
+set(handles.edit_lowpass,'Visible','off')
+set(handles.edit_lowpass,'String',num2str(freqdef))
+set(handles.edit2_lowpass,'Visible','off')
+set(handles.edit2_highpass,'Visible','off')
+set(handles.checkbox_removedc, 'Enable', 'on');
+set(handles.text_hzlp,'Visible','off')
+%set(handles.edit_highpass, 'BackgroundColor', [1 1 1]);
+set(handles.popupmenu_order,'String', '180') % set db/oct list
+set(handles.popupmenu_dbdec,'String', '---') % set db/dec list
+set(handles.popupmenu_dboct,'String', '---') % set db/oct list
+set(handles.popupmenu_order,'Value',1)
+set(handles.popupmenu_dboct,'Value',1)
+set(handles.popupmenu_dbdec,'Value',1)
+set(handles.popupmenu_dboct,'Enable','off')
+set(handles.popupmenu_dbdec,'Enable','off')
+set(handles.text_halfpow,'Visible','off')
+set(handles.text_halfamp,'Visible','off')
+set(handles.text_cutoff_1,'Visible','off')
+return
+
+%------------------------------------------------------------------------
+function unsetnotchpm(hObject, eventdata, handles)
+if strcmp(get(handles.slider_lowpass,'Visible'),'off')
+ set(handles.togglebutton_highpass, 'Visible', 'on')
+ set(handles.togglebutton_highpass,'Value',1)
+ set(handles.togglebutton_highpass, 'BackgroundColor', [1 1 0.5]);
+ set(handles.checkbox_removedc, 'Enable', 'on');
+ set(handles.togglebutton_lowpass, 'BackgroundColor', [0.8 0.8 0.75]);
+ vals = get(handles.slider_highpass, 'Value');
+ set(handles.edit_highpass,'String',sprintf('%.1f',vals));
+ set(handles.slider_lowpass, 'Visible', 'on')
+ set(handles.slider_lowpass, 'Value', 0)
+ set(handles.slider_lowpass, 'Enable', 'off')
+ set(handles.togglebutton_lowpass, 'Visible', 'on')
+ set(handles.togglebutton_lowpass,'Value',0)
+ set(handles.edit_lowpass,'String','0');
+ set(handles.edit_lowpass,'Enable','off');
+ %set(handles.edit_lowpass, 'BackgroundColor', [1 1 1]);
+ set(handles.text_hzlp,'Visible','on')
+else
+ set(handles.togglebutton_highpass, 'Visible', 'on')
+ set(handles.togglebutton_lowpass, 'Visible', 'on')
+ %set(handles.edit_lowpass, 'BackgroundColor', [1 1 1]);
+ set(handles.text_hzlp,'Visible','on')
+end
+
+set(handles.edit_lowpass,'Visible','on');
+set(handles.edit2_lowpass,'Visible','on');
+set(handles.edit2_highpass,'Visible','on');
+set(handles.edit2_highpass, 'BackgroundColor', [1 1 0.5]);
+set(handles.edit2_lowpass, 'BackgroundColor', [1 1 0.5]);
+set(handles.text_halfpow,'Visible','on')
+set(handles.text_halfamp,'Visible','on')
+set(handles.text_cutoff_1,'Visible','on')
+
+%--------------------------------------------------------------------------
+function edit_boundary_Callback(hObject, eventdata, handles)
+
+% -------------------------------------------------------------------------
+function edit_boundary_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function a_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function edit_xmaxplot_Callback(hObject, eventdata, handles)
+xmaxpstr = strtrim(get(handles.edit_xmaxplot, 'String'));
+xmaxp = str2num(xmaxpstr);
+
+if isempty(xmaxp)
+ msgboxText{1} = 'Your must enter a positive number greater than 0.1!';
+ title = 'EStudio: Basic Filter Error';
+ errorfound(msgboxText, title);
+ set(handles.edit_xmaxplot, 'String', num2str(handles.xmaxfreqr))
+
+ if get(handles.radiobutton_ufdatafr,'Value')
+ plotresponse_uf_data(hObject, eventdata, handles);
+ elseif get(handles.radiobutton_fdatafr,'Value')
+ plotresponse_fd_data(hObject, eventdata, handles);
+ else
+ plotresponsefilter(hObject, eventdata, handles);
+ end
+ return
+elseif length(xmaxp)==1
+ if xmaxp<0.1
+ msgboxText{1} = 'Your must enter a positive number greater than 0.1!';
+ title = 'EStudio: Basic Filter Error';
+ errorfound(msgboxText, title);
+ set(handles.edit_xmaxplot, 'String', num2str(handles.xmaxfreqr))
+
+ if get(handles.radiobutton_ufdatafr,'Value')
+ plotresponse_uf_data(hObject, eventdata, handles);
+ elseif get(handles.radiobutton_fdatafr,'Value')
+ plotresponse_fd_data(hObject, eventdata, handles);
+ else
+ plotresponsefilter(hObject, eventdata, handles);
+ end
+ return
+ end
+ xmaxp = [0 xmaxp];
+elseif length(xmaxp)==2
+ if xmaxp(1)>=xmaxp(2)
+ msgboxText{1} = 'Frenquency range must be sorted [minf maxf].';
+ title = 'EStudio: Basic Filter Error';
+ errorfound(msgboxText, title);
+ set(handles.edit_xmaxplot, 'String', num2str(handles.xmaxfreqr))
+
+ if get(handles.radiobutton_ufdatafr,'Value')
+ plotresponse_uf_data(hObject, eventdata, handles);
+ elseif get(handles.radiobutton_fdatafr,'Value')
+ plotresponse_fd_data(hObject, eventdata, handles);
+ else
+ plotresponsefilter(hObject, eventdata, handles);
+ end
+ return
+ end
+ if xmaxp(1)<0 || xmaxp(2)<0
+ msgboxText{1} = 'Your must enter 1 or 2 positive numbers.';
+ title = 'EStudio: Basic Filter Error';
+ errorfound(msgboxText, title);
+ set(handles.edit_xmaxplot, 'String', num2str(handles.xmaxfreqr))
+
+ if get(handles.radiobutton_ufdatafr,'Value')
+ plotresponse_uf_data(hObject, eventdata, handles);
+ elseif get(handles.radiobutton_fdatafr,'Value')
+ plotresponse_fd_data(hObject, eventdata, handles);
+ else
+ plotresponsefilter(hObject, eventdata, handles);
+ end
+ return
+ end
+ if abs(xmaxp(2)-xmaxp(1))<0.1
+ msgboxText{1} = 'Bandwidth for plotting must be greater than 0.1 Hz.';
+ title = 'EStudio: Basic Filter Error';
+ errorfound(msgboxText, title);
+ set(handles.edit_xmaxplot, 'String', num2str(handles.xmaxfreqr))
+
+ if get(handles.radiobutton_ufdatafr,'Value')
+ plotresponse_uf_data(hObject, eventdata, handles);
+ elseif get(handles.radiobutton_fdatafr,'Value')
+ plotresponse_fd_data(hObject, eventdata, handles);
+ else
+ plotresponsefilter(hObject, eventdata, handles);
+ end
+ return
+ end
+else
+ msgboxText = 'Wrong frenquency range!';
+ title = 'EStudio: Basic Filter Error';
+ errorfound(msgboxText, title);
+ set(handles.edit_xmaxplot, 'String', num2str(handles.xmaxfreqr))
+ return
+end
+if get(handles.radiobutton_impr,'Value')
+ handles.xmaxpimpz = xmaxp;
+else
+ handles.xmaxfreqr = xmaxp;
+end
+
+% Update handles structure
+guidata(hObject, handles);
+
+
+if get(handles.radiobutton_ufdatafr,'Value')
+ plotresponse_uf_data(hObject, eventdata, handles);
+elseif get(handles.radiobutton_fdatafr,'Value')
+ plotresponse_fd_data(hObject, eventdata, handles);
+else
+ plotresponsefilter(hObject, eventdata, handles);
+end
+return
+
+%--------------------------------------------------------------------------
+function edit_xmaxplot_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function noncausal_Callback(hObject, eventdata, handles)
+if ~get(hObject,'Value')
+ set(hObject,'Value',1)
+end
+
+%--------------------------------------------------------------------------
+function causal_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function popupmenu_FRscale_Callback(hObject, eventdata, handles)
+if get(handles.radiobutton_ufdatafr,'Value')
+ plotresponse_uf_data(hObject, eventdata, handles);
+elseif get(handles.radiobutton_fdatafr,'Value')
+ plotresponse_fd_data(hObject, eventdata, handles);
+else
+ plotresponsefilter(hObject, eventdata, handles);
+end
+
+%--------------------------------------------------------------------------
+function chksliders(hObject, eventdata, handles)
+sH = get(handles.slider_highpass,'Value');
+sL = get(handles.slider_lowpass,'Value');
+if sH<0.001
+ set(handles.slider_highpass,'Value', 0)
+ set(handles.edit_highpass,'String', '0')
+ set(handles.edit2_highpass,'String', '---')
+ set(handles.slider_highpass,'Enable', 'off')
+ set(handles.edit_highpass,'Enable', 'off')
+ set(handles.edit2_highpass,'Enable', 'off')
+ set(handles.togglebutton_highpass,'Value', 0)
+ set(handles.checkbox_removedc,'Value', 0)
+else
+ set(handles.edit_highpass, 'String', sprintf('%.1f',sH));
+ set(handles.edit2_highpass, 'BackgroundColor', [1 1 0.5]);
+end
+if sL<0.001
+ set(handles.slider_lowpass,'Value', 0)
+ set(handles.edit_lowpass,'String', '0')
+ set(handles.edit2_lowpass,'String', '---')
+ set(handles.slider_lowpass,'Enable', 'off')
+ set(handles.edit_lowpass,'Enable', 'off')
+ set(handles.edit2_lowpass,'Enable', 'off')
+ set(handles.togglebutton_lowpass,'Value', 0)
+else
+ set(handles.edit_lowpass, 'String', sprintf('%.1f',sL));
+ set(handles.edit2_lowpass, 'BackgroundColor', [1 1 0.5]);
+end
+if sL<0.001 && sH<0.001
+ set(handles.popupmenu_order,'Value', 2)
+end
+drawnow
+return
+
+%--------------------------------------------------------------------------
+function pushbutton_refresh_Callback(hObject, eventdata, handles)
+sHstr = sprintf('%.1f',get(handles.slider_highpass,'Value'));
+sLstr = sprintf('%.1f',get(handles.slider_lowpass,'Value'));
+set(handles.edit_lowpass,'String', sLstr)
+set(handles.edit_highpass,'String', sHstr)
+drawnow
+
+plotresponsefilter(hObject, eventdata, handles);
+
+%--------------------------------------------------------------------------
+function sliderson(hObject, eventdata, handles)
+if get(handles.togglebutton_highpass,'value')
+ set(handles.slider_highpass,'Enable','on')
+end
+
+if get(handles.togglebutton_lowpass,'value')
+ set(handles.slider_lowpass,'Enable','on')
+end
+drawnow
+
+%--------------------------------------------------------------------------
+function slidersoff(hObject, eventdata, handles)
+if get(handles.togglebutton_highpass,'value')
+ set(handles.slider_highpass,'Enable','off')
+end
+
+if get(handles.togglebutton_lowpass,'value')
+ set(handles.slider_lowpass,'Enable','off')
+end
+drawnow
+
+%--------------------------------------------------------------------------
+function uipanel8_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function edit_tip_cutoff_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function [ym f ylim] = plotresponse_uf_data(hObject, eventdata, handles)
+
+[ym f ylim] = deal([]);
+frecp = str2num(get(handles.edit_xmaxplot,'String'));
+
+if isempty(frecp)
+ return
+end
+
+ch = str2num(get(handles.edit_channels,'String'));
+
+if isempty(ch)
+ return
+end
+
+axes(handles.axes1);
+posaxes1 = get(gca,'YLim');
+msgtx = 'Working, please wait...';
+text(mean(frecp)/3, posaxes1(2)/2, msgtx,'FontSize',14, 'color', 'k')
+drawnow
+
+if isempty(setxor(ch, [handles.datafr.chan])) % are equal?
+ ym = handles.datafr.ym;
+ f = handles.datafr.f;
+else
+ ERPLAB = handles.ERPLAB;
+ np = round(ERPLAB.srate/2);
+
+ if iserpstruct(ERPLAB) % for erpset
+ % [ym f] = fourierp(ERPLAB,ch,frecp(1),np,np);
+ [ym f] = fourierp(ERPLAB,ch,[], 0,np,np);
+ elseif iseegstruct(ERPLAB) % for erpset
+ % [ym f] = fourieeg(ERPLAB,ch,frecp(1),np,np);
+ [ym f] = fourieeg(ERPLAB,ch,[],0,np,np);
+ else
+ return
+ end
+end
+
+[frecpxx frecpsam2] = min(abs(f-frecp(2)));
+[frecpxx frecpsam1] = min(abs(f-frecp(1)));
+
+FRscale = get(handles.popupmenu_FRscale, 'Value');
+color = [0 0.2 0];
+
+if FRscale==1
+ ymax = max(ym)+0.2;
+ ymin = -0.0625*ymax; %6.25% of ymax -
+ plot(f(frecpsam1:frecpsam2), ym(frecpsam1:frecpsam2), 'linewidth', 2, 'LineSmoothing','on','Color', color)
+ ylabel('Data amplitude')
+else
+ ymax = 20*log(max(ym))+0.2;
+ ymin = -65;
+ plot(f(frecpsam1:frecpsam2), 20*log10(ym(frecpsam1:frecpsam2)), 'linewidth', 2, 'LineSmoothing','on','Color', color)
+ ylabel('Data amplitude in dB')
+end
+
+ylim = [ymin ymax];
+xlabel('frequency (Hz)')
+axis([frecp ymin ymax])
+hle = legend('Unfiltered data');
+set(hle, 'Color', 'none', 'Box', 'off')
+drawnow
+handles.datafr.chan = ch;
+handles.datafr.ym = ym;
+handles.datafr.f = f;
+
+% Update handles structure
+guidata(hObject, handles);
+
+%--------------------------------------------------------------------------
+function plotresponse_fd_data(hObject, eventdata, handles)
+
+valueh = get(handles.slider_highpass, 'Value');
+valuel = get(handles.slider_lowpass, 'Value');
+
+if valueh==0 && valuel==0
+ msgtx = '--NO FILTERING--';
+ no_filter(hObject, handles, msgtx)
+ return
+end
+frecp = str2num(get(handles.edit_xmaxplot,'String'));
+if isempty(frecp)
+ return
+end
+ch = str2num(get(handles.edit_channels,'String'));
+if isempty(ch)
+ return
+end
+
+axes(handles.axes1);
+
+[ydata f ylim] = plotresponse_uf_data(hObject, eventdata, handles);
+[yfilter labelf] = plotresponsefilter(hObject, eventdata, handles);
+yfildata = ydata.*yfilter';
+
+FRscale = get(handles.popupmenu_FRscale, 'Value');
+color = [0.2 0 0];
+ymin = ylim(1);
+ymax = ylim(2);
+
+if FRscale==1
+ %ymax = max(yfildata)+0.2;
+ %ymin = -0.075;
+ ymaxb = 1;
+ yminb = 0;
+ plot(f, yfildata, 'linewidth', 2, 'LineSmoothing','on','Color', color)
+ ylabel('Data amplitude')
+else
+ %ymax = 20*log(ymax)+0.2;
+ %ymin = -65;
+ ymaxb = 0;
+ yminb = -90;
+ plot(f, 20*log10(yfildata), 'linewidth', 2, 'LineSmoothing','on','Color', color)
+ ylabel('Data amplitude in dB')
+end
+fnyq = round(handles.fs/2);
+if get(handles.radiobutton_ideal, 'Value')
+ drawidealresp(handles, labelf, fnyq, valuel, valueh, yminb, ymaxb)
+end
+
+% text(mean(frecp), posaxes1(2)/2, msgtx,'FontSize',14, 'color', 'w') % erase text...temporary...
+xlabel('frequency (Hz)')
+axis([frecp ymin ymax])
+hle = legend('Filtered data');
+set(hle, 'Color', 'none', 'Box', 'off')
+drawnow
+
+%--------------------------------------------------------------------------
+function minboundarysamdist = boundarydistance(EVENTSTRUCT)
+
+%
+% Minimum number of sample among boundaries
+%
+if isempty(EVENTSTRUCT)
+ minboundarysamdist = inf;
+ return
+end
+if ischar(EVENTSTRUCT(1).type)
+ ecpos = strmatch('boundary', {EVENTSTRUCT.type});
+else
+ ecpos = find([EVENTSTRUCT.type]==-99);
+end
+if isempty(ecpos)
+ minboundarysamdist = inf;
+else
+ minboundarysamdist = min(diff([EVENTSTRUCT(ecpos).latency]));
+end
+
+%--------------------------------------------------------------------------
+function setall(hObject, eventdata, handles, ERPLAB, def)
+
+if nargin<5
+ def = handles.def;
+end
+if nargin<4
+ ERPLAB = handles.ERPLAB;
+end
+if isempty(ERPLAB)
+ try
+ ERPLAB = handles.ERPLAB;
+ catch
+ ERPLAB = buildERPstruct([]);
+ end
+end
+fs = ERPLAB.srate;
+if isempty(fs)
+ fs=1000;
+end
+
+% def = {highpasscutoff, lowpasscutoff, order, channelArray, typefilter, remove_dc, boundary};
+% setall(hObject, eventdata, handles, [], def)
+
+locutoff = def{1}; % for high pass filter
+hicutoff = def{2}; % for low pass filter
+filterorder = def{3};
+chanArray = def{4};
+filterallch = def{5};
+typefilter = def{6};
+remove_dc = def{7};
+boundary = def{8};
+binArray = def{9};
+colorband = [0.9922 0.9176 0.7961];
+
+if iserpstruct(ERPLAB) % for erpset
+ typedata = 'ERP';
+ set(handles.checkbox_removedc, 'Visible', 'on')
+ set(handles.checkbox_removedc, 'Value', remove_dc)
+ set(handles.checkbox_removedc, 'String', 'Remove mean value (DC bias) before filtering (not usually appropriate for baseline-corrected data)')
+ %set(handles.checkbox_removedc, 'Enable', 'off')
+ set(handles.checkbox_boundary, 'Visible', 'off')
+ set(handles.edit_boundary,'Visible', 'off');
+ set(handles.text_boundary,'Visible', 'off');
+ minboundarysamdist = inf;
+ %nchan = ERPLAB.nchan;
+else
+ if isempty(ERPLAB.epoch) % for continuous dataset
+ set(handles.checkbox_boundary, 'Enable', 'on')
+
+ if isempty(boundary)
+ set(handles.checkbox_boundary, 'Value', 0)
+ set(handles.edit_boundary, 'string', 'boundary'); % default
+ set(handles.edit_boundary,'Enable', 'off');
+ %set(handles.edit_boundary,'BackgroundColor', [0.75 0.75 0.75]);
+ else
+ set(handles.checkbox_boundary, 'Value', 1)
+ set(handles.edit_boundary,'Enable', 'on');
+ %set(handles.edit_boundary,'BackgroundColor', [1 1 1]);
+ set(handles.edit_boundary, 'string', boundary);
+ end
+
+ label1 = 'Apply filter to segments defined';
+ label2 = 'by boundary events (Strongly Recommended)';
+ set(handles.checkbox_boundary, 'string',[label1 ' ' label2]);
+ set(handles.checkbox_removedc, 'Value', remove_dc)
+ typedata = 'continuous EEG';
+ minboundarysamdist = boundarydistance(ERPLAB.event);
+ else % for epoched dataset
+ set(handles.checkbox_boundary, 'Value', 0)
+ set(handles.checkbox_boundary, 'Enable', 'off')
+ set(handles.edit_boundary, 'string', '');
+ set(handles.edit_boundary,'Enable', 'off');
+ %set(handles.edit_boundary,'BackgroundColor', [0.75 0.75 0.75]);
+ label1 = 'Apply filter to segments defined ';
+ label2 = 'by boundary events (Strongly Recommended) ';
+ set(handles.checkbox_boundary, 'string',[label1 ' ' label2]);
+ set(handles.text_boundary,'Enable', 'off');
+ set(handles.checkbox_removedc, 'String', 'Remove mean value (DC bias) before filtering (not usually appropriate for baseline-corrected data)')
+ set(handles.checkbox_removedc, 'Value', remove_dc)
+ %set(handles.checkbox_removedc, 'Enable', 'off')
+ typedata = 'epoched EEG';
+ minboundarysamdist = inf;
+ end
+ %nchan = ERPLAB.nbchan;
+end
+
+%
+% Name & version
+%
+erplab_studio_default_values;
+version = erplabstudiover;
+set(handles.gui_chassis,'Name', ['EStudio V.', version ' - ERP Filtering > Advanced' ])
+highpasscutoff = locutoff;
+lowpasscutoff = hicutoff;
+maxsliders = handles.maxsliders;
+handles.minboundarysamdist = minboundarysamdist;
+handles.memvaluel = lowpasscutoff;
+handles.memvalueh = highpasscutoff;
+handles.morder = filterorder;
+handles.mvalueh = highpasscutoff; % memory value highpass
+
+slider_step(1) = 0.1/maxsliders;
+slider_step(2) = 0.5/maxsliders;
+
+switch typefilter
+ case 'butter'
+ set(handles.radiobutton_butter, 'Value', 1); % 0 means Butterworth
+ ordervector = 2:2:8;
+ [tf, ordenp] = ismember_bc2(filterorder, ordervector);
+ set(handles.popupmenu_order,'String', char([{'automin'}; cellstr(num2str(ordervector'))])) % set order list
+ set(handles.popupmenu_order,'Value', ordenp+1);
+ set(handles.popupmenu_dboct,'String', num2str(6*ordervector')) % set db/oct list
+ set(handles.popupmenu_dbdec,'String', num2str(20*ordervector')) % set db/dec list
+ set(handles.popupmenu_dboct,'Value', ordenp) % set db/oct list
+ set(handles.popupmenu_dbdec,'Value', ordenp) % set db/dec list
+ case 'fir'
+ set(handles.radiobutton_fir, 'Value', 1); % 1 means FIR
+ ordervector = 4:4:4096;
+ [tf, ordenp] = ismember_bc2(filterorder, ordervector);
+ set(handles.popupmenu_order,'String', char([{'automin'}; cellstr(num2str(ordervector'))])) % set order list
+ set(handles.popupmenu_order,'Value', ordenp+1);
+ set(handles.popupmenu_dboct,'String', '---') % set db/oct list
+ set(handles.popupmenu_dbdec,'String', '---') % set db/dec list
+ case 'notch'
+ set(handles.radiobutton_PM_notch, 'Value', 1);
+ setnotchpm(handles)
+ handles.freqdef = highpasscutoff;
+end
+
+set(handles.slider_highpass, 'Value', highpasscutoff, 'Max', maxsliders, 'Min', 0, 'SliderStep', slider_step)
+set(handles.slider_lowpass, 'Value', lowpasscutoff, 'Max', maxsliders, 'Min', 0, 'SliderStep', slider_step)
+%set(handles.edit_channels,'String', vect2colon(chanArray, 'Delimiter','off', 'Repeat', 'off'))
+% % % set(handles.popupmenu_channels,'String', listch)
+set(handles.radiobutton_freqr,'Value', 1);
+set(handles.radiobutton_impr,'Value', 0);
+set(handles.radiobutton_ufdatafr,'Value', 0);
+set(handles.radiobutton_fdatafr,'Value', 0);
+set(handles.radiobutton_ideal, 'Enable','on')
+nchan = handles.nchan;
+% if filterallch
+% % set(handles.checkbox_filterallchannels, 'Value', 1)
+% set(handles.edit_channels, 'String', vect2colon([1:nchan], 'Delimiter', 'off'));
+% set(handles.edit_channels, 'Enable', 'off');
+% set(handles.pushbutton_browsechan, 'Enable', 'off');
+% else
+ERPLAB = handles.ERPLAB;
+len1 = length(chanArray);
+chanArray = chanArray(chanArray<=nchan);
+% len2 = length(chanArray);
+% if len1~=len2
+% fprintf('Index of channels to be filtered was adjusted since current %s has only %g channels.\n', typedata, nchan);
+% end
+[chk, msgboxText] = f_ERP_chckbinandchan(ERPLAB, [],chanArray,2);
+if chk(2)
+ chanArray = [1:ERPLAB.nchan];
+ handles.indxlistch = chanArray;
+end
+% if len2==nchan
+% set(handles.checkbox_filterallchannels, 'Value', 1)
+if filterallch
+ set(handles.edit_channels, 'String','All');
+else
+set(handles.edit_channels, 'String', vect2colon(chanArray, 'Delimiter', 'off'));
+end
+set(handles.edit_channels, 'Enable', 'off');
+set(handles.pushbutton_browsechan, 'Enable', 'off');
+% else
+% chanArraystr = vect2colon(chanArray, 'Delimiter','off', 'Repeat', 'off');
+% set(handles.edit_channels, 'String', chanArraystr)
+% end
+% end
+
+
+[chk, msgboxText] = f_ERP_chckbinandchan(ERPLAB, binArray,[],1);
+if chk(1)
+ binArray = [1:ERPLAB.nbin];
+ handles.indxlistb = binArray;
+end
+if filterallch
+ set(handles.edit_bins,'String','All');
+else
+set(handles.edit_bins,'String',vect2colon(binArray, 'Delimiter','off', 'Repeat', 'off'));
+end
+set(handles.edit_bins, 'Enable', 'off');
+set(handles.pushbutton_broswe_bin, 'Enable', 'off');
+%
+% Causality (pending)
+%
+set(handles.noncausal,'Value',1); % only noncausal, for now.
+set(handles.causal,'Value',0);
+set(handles.causal,'Enable','off');
+
+tooltip1 = 'Cutoff frequency = frequency where the magnitude response of the filter is either 0.5 (-6dB) or 0.707 (-3dB)';
+tooltip2 = ['The filter does not attenuate all frequencies outside the desired frequency range completely; '...
+ 'in particular, there is a region just outside the intended passband where frequencies are attenuated, '...
+ 'but not rejected. This is known as the filter roll-off, and it is usually expressed in dB of attenuation '...
+ 'per octave or decade of frequency. In general, the roll-off for an order-n filter is 6n dB per octave or '...
+ '20n dB per decade.'];
+
+set(handles.edit_tip_cutoff, 'tooltip',tooltip1);
+set(handles.edit_tip_rolloff, 'tooltip',tooltip2);
+
+if highpasscutoff== 0
+ set(handles.togglebutton_highpass, 'Value',0);
+ set(handles.togglebutton_highpass, 'BackgroundColor', [0.8 0.8 0.75]);
+ set(handles.slider_highpass, 'Enable', 'off');
+ set(handles.edit_highpass, 'String', '0');
+
+ set(handles.edit_highpass, 'Enable', 'off');
+ %set(handles.edit_highpass, 'BackgroundColor', [0.75 0.75 0.75]);
+else
+ set(handles.togglebutton_highpass, 'Value',1);
+ set(handles.togglebutton_highpass, 'BackgroundColor', [1 1 0.5]);
+ set(handles.edit_highpass, 'Enable', 'on');
+
+ set(handles.edit_highpass, 'String', sprintf('%.1f',highpasscutoff));
+ %set(handles.edit_highpass, 'BackgroundColor', [1 1 1]);
+end
+if lowpasscutoff== 0
+ set(handles.togglebutton_lowpass, 'Value',0);
+ set(handles.togglebutton_lowpass, 'BackgroundColor', [0.8 0.8 0.75]);
+ set(handles.slider_lowpass, 'Enable', 'off');
+ set(handles.edit_lowpass, 'String', '0');
+ set(handles.edit_lowpass, 'Enable', 'off');
+ %set(handles.edit_lowpass, 'BackgroundColor', [0.75 0.75 0.75]);
+else
+ set(handles.togglebutton_lowpass, 'Value',1);
+ set(handles.togglebutton_lowpass, 'BackgroundColor', [1 1 0.5]);
+ set(handles.edit_lowpass, 'Enable', 'on');
+
+ set(handles.edit_lowpass, 'String', sprintf('%.1f',lowpasscutoff));
+ %set(handles.edit_lowpass, 'BackgroundColor', [1 1 1]);
+end
+
+set(handles.radiobutton_gaussian,'Enable','off')
+% set(handles.togglebutton_lowpass, 'Value',1);
+% set(handles.togglebutton_lowpass, 'BackgroundColor', [1 1 0.5]);
+set(handles.popupmenu_FRscale, 'String', {'Linear' 'Decibels'});
+set(handles.popupmenu_FRscale,'Value', 1);
+set(handles.popupmenu_FRscale,'Enable', 'on');
+set(handles.edit_xmaxplot, 'String', num2str([0 fs]))
+drawnow
+
+% Update handles structure
+guidata(hObject, handles);
+plotresponsefilter(hObject, eventdata, handles);
+
+%--------------------------------------------------------------------------
+% --- Executes on button press in radiobutton_ideal.
+function radiobutton_ideal_Callback(hObject, eventdata, handles)
+%
+% Plot corresponding response
+%
+if get(handles.radiobutton_fdatafr,'Value')
+ plotresponse_fd_data(hObject, eventdata, handles)
+elseif get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_impr,'Value')
+ plotresponsefilter(hObject, eventdata, handles);
+end
+
+%--------------------------------------------------------------------------
+function pushbutton_import_settings_Callback(hObject, eventdata, handles)
+[filename, pathname] = uigetfile({'*.bfil','Basic Filter seetings (*.bfil)'}, 'Load settings');
+if isequal(filename,0)
+ disp('User selected Cancel')
+ return
+end
+L = load(fullfile(pathname, filename), '-mat');
+readobjects = L.outstr;
+
+% outstr = {highpasscutoff, lowpasscutoff, order, channelArray, typefilter, remove_dc, boundary};
+highpasscutoff = readobjects{1};
+lowpasscutoff = readobjects{2};
+order = readobjects{3};
+channelArray = readobjects{4};
+filterallch = readobjects{5};
+typefilter = readobjects{6};
+remove_dc = readobjects{7};
+boundary = readobjects{8};
+def = {highpasscutoff, lowpasscutoff, order, channelArray, filterallch, typefilter, remove_dc, boundary};
+setall(hObject, eventdata, handles, [], def)
+
+%--------------------------------------------------------------------------
+function pushbutton_save_settings_Callback(hObject, eventdata, handles)
+
+% readobjects = {channelArray, highpasscutoff, lowpasscutoff, order, typefilter, remove_dc, boundarycheck, boundarystr};
+
+% global readobjects
+[readobjects v] = read_GUI(hObject, eventdata, handles);
+if v~=1 % means something was going wrong
+ msgboxText = 'Setting is not ready to be saved. Please check it out.';
+ title = 'EStudio: f_basicfilter GUI error:';
+ errorfound(sprintf(msgboxText), title);
+ return
+end
+
+channelArray = readobjects{1};
+filterallch = readobjects{2};
+if filterallch
+ nchan = handles.nchan;
+ channelArray = 1:nchan;
+end
+highpasscutoff = readobjects{3};
+lowpasscutoff = readobjects{4};
+order = readobjects{5};
+typefilter = readobjects{6};
+remove_dc = readobjects{7};
+boundarycheck = readobjects{8};
+boundarystr = readobjects{9};
+
+if boundarycheck==1
+ if strcmpi(boundarystr,'boundary')||strcmpi(boundarystr,'''boundary''')
+ boundary = 'boundary';
+ else
+ if ~strcmp(boundarystr,'')
+ boundary = str2num(boundarystr);
+ if isempty(boundary);
+ boundary = boundarystr;
+ end
+ else
+ %boundary = [];
+ msgboxText = ['You have set the checkbox for filtering between boundary events.\n'...
+ 'So, you must define a boundary event code.'];
+ title = 'EStudio: f_basicfilter GUI error:';
+ errorfound(sprintf(msgboxText), title);
+ return
+ end
+ end
+else
+ boundary = [];
+end
+
+%
+% Save OUTPUT file
+%
+[filename, filepath, filterindex] = uiputfile({'*.bfil','Basic Filter settings (*.bfil)'},'Save filter settings as');
+
+if isequal(filename,0)
+ disp('User selected Cancel')
+ return
+else
+ outstr = {highpasscutoff, lowpasscutoff, order, channelArray, filterallch, typefilter, remove_dc, boundary};
+
+ [px, fname, ext] = fileparts(filename);
+ if strcmp(ext,'')
+ if filterindex==1
+ ext = '.bfil';
+ end
+ end
+
+ fname = [ fname ext];
+ fullname = fullfile(filepath, fname);
+ save(fullname, 'outstr');
+
+ % fid_list = fopen( fullname , 'w');
+ %
+ % for i=1:size(fulltext,1)
+ % fprintf(fid_list,'%s\n', fulltext(i,:));
+ % end
+ %
+ % fclose(fid_list);
+ % set(handles.button_savelist, 'Enable','on')
+end
+
+%--------------------------------------------------------------------------
+function edit2_highpass_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function edit2_lowpass_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function togglebutton_lowpass_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function togglebutton_highpass_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function gui_chassis_CloseRequestFcn(hObject, eventdata, handles)
+
+if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting')
+ % The GUI is still in UIWAIT, us UIRESUME
+ uiresume(handles.gui_chassis);
+else
+ % The GUI is no longer waiting, just close it
+ delete(handles.gui_chassis);
+end
+
+
+function pushbutton_browsechan_Callback(hObject, eventdata, handles)
+
+listch = handles.listch;
+indxlistch = handles.indxlistch;
+indxlistch = indxlistch(indxlistch<=length(listch));
+titlename = 'Select Channel(s)';
+
+if get(hObject, 'Value')
+ if ~isempty(listch)
+ ch = browsechanbinGUI(listch, indxlistch, titlename);
+ if ~isempty(ch)
+ set(handles.edit_channels, 'String', vect2colon(ch, 'Delimiter', 'off'));
+ handles.indxlistch = ch;
+ % Update handles structure
+ guidata(hObject, handles);
+ else
+ disp('User selected Cancel')
+ return
+ end
+ else
+ msgboxText = 'No channel information was found';
+ title = 'EStudio: f_basicfilter GUI input';
+ errorfound(msgboxText, title);
+ return
+ end
+end
+
+%
+% function checkbox_filterallchannels_Callback(hObject, eventdata, handles)
+% if get(hObject, 'Value')
+% nchan = handles.nchan;
+% set(handles.edit_channels, 'String', vect2colon([1:nchan], 'Delimiter', 'off'));
+% set(handles.edit_channels, 'Enable', 'off');
+% set(handles.pushbutton_browsechan, 'Enable', 'off');
+% else
+% set(handles.edit_channels, 'Enable', 'on');
+% set(handles.pushbutton_browsechan, 'Enable', 'on');
+% end
+
+
+
+function edit_bins_Callback(hObject, eventdata, handles)
+% nbin = handles.nbin;
+binx = str2num(get(handles.edit_bins,'String'));
+% tf = checkchannels(chx, nchan);
+
+ERPLAB = handles.ERPLAB;
+[chk, msgboxText] = f_ERP_chckbinandchan(ERPLAB, binx,[],1);
+if chk(2)
+ title = 'EStudio: f_basicfilterGUI2';
+ errorfound(msgboxText, title);
+ return;
+end
+handles.indxlistb = binx; % bin array
+
+
+
+% --- Executes during object creation, after setting all properties.
+function edit_bins_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+% --- Executes on button press in pushbutton_broswe_bin.
+function pushbutton_broswe_bin_Callback(hObject, eventdata, handles)
+listch = handles.listb;
+indxlistch = handles.indxlistb;
+indxlistch = indxlistch(indxlistch<=length(listch));
+titlename = 'Select Bin(s)';
+
+if get(hObject, 'Value')
+ if ~isempty(listch)
+ bin = browsechanbinGUI(listch, indxlistch, titlename);
+ if ~isempty(ch)
+ set(handles.edit_bins, 'String', vect2colon(bin, 'Delimiter', 'off'));
+ handles.indxlistb = bin;
+ % Update handles structure
+ guidata(hObject, handles);
+ else
+ disp('User selected Cancel')
+ return
+ end
+ else
+ msgboxText = 'No bin information was found';
+ title = 'EStudio: f_basicfilter GUI input';
+ errorfound(msgboxText, title);
+ return
+ end
+end
diff --git a/studio_functions/GUIs/ERP Tab/f_chan_testsyntaxtype.m b/studio_functions/GUIs/ERP Tab/f_chan_testsyntaxtype.m
new file mode 100755
index 00000000..91e6ece5
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_chan_testsyntaxtype.m
@@ -0,0 +1,92 @@
+function [val, formulaArray] = f_chan_testsyntaxtype(FormulaArrayIn, whocall)
+val = 1;
+formulaArray = FormulaArrayIn;
+
+if isempty(formulaArray)
+ return
+else
+ formulaArray = strtrim(cellstr(formulaArray));
+end
+nformulas = length(formulaArray);
+
+[expspliter parts] = regexp(formulaArray, '=','match','split');
+ask4fix = 1;
+wantfix = 0;
+newnumchan = 1;
+
+for t=1:nformulas
+ fcomm = formulaArray{t};
+ tokcommentb = regexpi(fcomm, '^#', 'match'); % comment symbol (June 3, 2013)
+
+ if isempty(tokcommentb) % skip comment symbol
+ pleft = regexpi(parts{t}{1}, '(\s*nch[an]*\d+)', 'tokens');
+ plcom = regexpi(parts{t}{1}, '(\s*ch[an]*\d+)', 'tokens');
+
+ if isempty(pleft) && ~isempty(plcom) && strcmpi(whocall,'norecu')
+ if ask4fix
+ BackERPLABcolor = [1 0.9 0.3]; % yellow
+ question = ['For non recursive mode, left side of equation\nmust be define as a new channel.\n'...
+ 'For instance, nchan1 = ...\n\n'...
+ 'Do you want that EStudio corrects the syntax for you?'];
+ title = 'WARNING: Syntax is not proper for non recursive mode';
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor)
+ button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes');
+ set(0,'DefaultUicontrolBackgroundColor',oldcolor)
+
+ if strcmpi(button,'Yes')
+ ask4fix = 0;
+ wantfix = 1;
+ elseif strcmpi(button,'Cancel')
+ val = 0; % cancel
+ break
+ else
+ ask4fix = 0;
+ wantfix = 0;
+ end
+ %else
+ % wantfix =1;
+ end
+ elseif ~isempty(pleft) && strcmpi(whocall,'recu')
+ if ask4fix
+ BackERPLABcolor = [1 0.9 0.3]; % yellow
+ question = ['For recursive mode, left side of equation cannot\nbe define as a new channel.\n'...
+ 'For instance, you must write chan1 = ...\n\n'...
+ 'Do you want that EStudio corrects the syntax for you?'];
+ title = 'WARNING: Syntax is not proper for recursive mode';
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor)
+ button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes');
+ set(0,'DefaultUicontrolBackgroundColor',oldcolor)
+
+ if strcmpi(button,'Yes')
+ ask4fix = 0;
+ wantfix =1;
+ elseif strcmpi(button,'Cancel')
+ val = 0; % cancel
+ break
+ else
+ ask4fix = 0;
+ wantfix = 0;
+ end
+ %else
+ % wantfix =1;
+ end
+ %else
+ % wantfix = 0;
+ end
+ if wantfix && (~isempty(pleft) || ~isempty(plcom))% fixed (June 3, 2013): JLC
+ fprintf('WARNING: equation %s ', formulaArray{t})
+ if strcmpi(whocall,'recu') % for recursive mode delete the n in nch
+ formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*','','ignorecase')), strtrim(parts{t}{2}));
+ else
+ formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*ch(\D*)(\d*)',['nch$1' num2str(newnumchan)],'ignorecase')), strtrim(parts{t}{2}));
+ newnumchan = newnumchan+1;
+ end
+ fprintf('was changed to equation %s \n', formulaArray{t})
+ end
+ end
+end
+% if val==1
+% set(handles.editor,'String', char(formulaArray));
+% end
\ No newline at end of file
diff --git a/studio_functions/GUIs/ERP Tab/f_chanoperGUI.fig b/studio_functions/GUIs/ERP Tab/f_chanoperGUI.fig
new file mode 100755
index 00000000..f3ea7ae0
Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_chanoperGUI.fig differ
diff --git a/studio_functions/GUIs/ERP Tab/f_chanoperGUI.m b/studio_functions/GUIs/ERP Tab/f_chanoperGUI.m
new file mode 100755
index 00000000..20cec6c7
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_chanoperGUI.m
@@ -0,0 +1,1021 @@
+
+% Begin initialization code - DO NOT EDIT
+function varargout = f_chanoperGUI(varargin)
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @f_chanoperGUI_OpeningFcn, ...
+ 'gui_OutputFcn', @f_chanoperGUI_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+% End initialization code - DO NOT EDIT
+
+%--------------------------------------------------------------------------
+function f_chanoperGUI_OpeningFcn(hObject, eventdata, handles, varargin)
+
+handles.output = [];
+example{1} = 'ch@ = ch6 - ch5 label HEOG';
+example{2} = 'chan@ = ch6 - ch5 label = HEOG';
+example{3} = 'ch@ = 0.5*chan7 + 0.5*chan9 label LINKM';
+example{4} = 'ch@ = mahaleeg(ch1,ch2) label MAHAL01';
+example{5} = 'CH@ = mahaleeg(ch40) label SELFMAHAL';
+example{6} = 'ch@ = (ch11+ch12+ch13)/3 label = ROI temporal';
+example{7} = 'CHAN@ = (ch11 + ch12 + ch13)/3 label ROI temporal';
+example{8} = 'ch@ = abs(ch110) label E110 rectified ';
+
+
+try
+ ERPLAB = varargin{1};
+
+ if iserpstruct(ERPLAB)
+ nchan = ERPLAB.nchan; % Total number of channels
+ typedata = 'ERP';
+ datastr = 'ERPset';
+ formtype = 'erpchanformulas';
+ example{5} = 'ch@ = mgfperp(ERP) label MGFPower';
+ else
+ example{3} = 'ch@ = chinterpol';
+ nchan = ERPLAB.nbchan; % Total number of channels
+ typedata = 'EEG';
+ datastr = 'dataset';
+ formtype = 'eegchanformulas';
+ end
+catch
+ ERPLAB.chanlocs = [];
+ listch = '';
+ nchan = 1;
+ formtype = [];
+ typedata = 'unspecific data';
+ datastr = 'who-knows-what';
+end
+try
+ def = varargin{2};
+ formulas = def{1};
+ wchmsgon = def{2};
+catch
+ formulas = [];
+ wchmsgon = 1;
+end
+
+handles.nchan = nchan;
+% handles.listname = [];
+handles.example = example;
+handles.exacounter = 0;
+handles.typedata = typedata;
+handles.formtype = formtype;
+
+%
+% Name & version
+%
+version = geterplabstudioversion;
+set(handles.gui_chassis,'Name', ['EStudio ' version ' - Channel Operation GUI for ' typedata])
+
+% formulas = erpworkingmemory(formtype);
+
+if isempty(formulas)
+ set(handles.editor,'String','');
+else
+ set(handles.editor, 'String', formulas)
+end
+
+% For undo & redo
+% handles.formulas{1} = get(handles.editor, 'String');
+% handles.undocount = 1;
+% set(handles.pushbutton_undo,'Enable','off')
+% set(handles.pushbutton_redo,'Enable','off')
+
+%
+% Prepare List of current Channels
+%
+listch=[];
+if isempty(ERPLAB.chanlocs)
+ for e=1:nchan
+ ERPLAB.chanlocs(e).labels = ['Ch' num2str(e)];
+ end
+end
+listch = cell(1,nchan);
+for ch =1:nchan
+ listch{ch} = [num2str(ch) ' = ' ERPLAB.chanlocs(ch).labels ];
+end
+
+set(handles.listboxchan1,'String', listch)
+label1 = 'Send file rather than individual equations';
+label2 = '(creates compact history)';
+set(handles.checkbox_sendfile2history, 'string',[label1 ' ' label2])
+handles.listch = listch;
+
+%
+% Mode buttons
+%
+set(handles.button_recursive, 'String', sprintf('Modify existing %s (recursive updating)', datastr));
+set(handles.button_no_recu, 'String', sprintf('Create new %s (independent transformations)',datastr));
+
+%
+% Gui memory
+%
+chanopGUI = erpworkingmemory('chanopGUI');
+
+if isempty(chanopGUI)
+ set(handles.button_recursive,'Value', 1); % default is Modify existing ERPset (recursive updating)
+ set(handles.button_savelist, 'Enable','off')
+ set(handles.chkeeplocs,'Value', 1) %default is Preserve Channel locations
+
+ %
+ % File List
+ %
+ set(handles.edit_filelist,'String','');
+ set(handles.checkbox_sendfile2history,'Value',0)
+ handles.listname = [];
+else
+ if chanopGUI.emode==0
+ set(handles.button_recursive,'Value', 1);
+ set(handles.button_no_recu,'Value', 0);
+ else
+ set(handles.button_recursive,'Value', 0);
+ set(handles.button_no_recu,'Value', 1);
+ end
+ if chanopGUI.hmode==0
+ set(handles.checkbox_sendfile2history,'Value', 0);
+ else
+ set(handles.checkbox_sendfile2history,'Value', 1);
+ end
+ if chanopGUI.keeplocs ==1
+ set(handles.chkeeplocs,'Value',1);
+ else
+ set(handles.chkeeplocs,'Value',0);
+ end
+ listname = chanopGUI.listname;
+ set(handles.edit_filelist,'String', listname );
+ handles.listname = listname; % JLC Sept 1, 2012
+end
+
+% wchmsgon = erpworkingmemory('wchmsgon');
+
+if isempty(wchmsgon) || wchmsgon==0
+ set(handles.chwarning,'Value', 0)
+elseif wchmsgon==1
+ set(handles.chwarning,'Value', 1)
+else
+ error('Oops...checkbox_warning memory failed')
+end
+
+handles.locs = ERPLAB.chanlocs;
+
+%
+% Color GUI
+%
+handles = painterplabstudio(handles);
+
+%
+% Set font size
+%
+handles = setfonterplabestudio(handles);
+
+% Update handles structure
+guidata(hObject, handles);
+
+% help
+helpbutton
+
+drawnow
+uiwait(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+function varargout = f_chanoperGUI_OutputFcn(hObject, eventdata, handles)
+% Get default command line output from handles structure
+
+varargout{1} = handles.output;
+
+% The figure can be deleted now
+delete(handles.gui_chassis);
+pause(0.1)
+
+%--------------------------------------------------------------------------
+function editor_Callback(hObject, eventdata, handles)
+
+set(handles.edit_filelist, 'String','');
+compacteditor(hObject, eventdata, handles);
+
+% handles = editorbackup(hObject, eventdata, handles);
+% formulas = get(handles.editor, 'String');
+% undocount = handles.undocount;
+% undocount = undocount + 1;
+% handles.formulas{undocount} = formulas;
+% handles.undocount = undocount;
+
+handles.listname = [];
+
+% Update handles structure
+guidata(hObject, handles);
+
+%--------------------------------------------------------------------------
+function editor_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function pushbutton_help_Callback(hObject, eventdata, handles)
+% doc pop_eegchanoperator
+web https://github.com/lucklab/erplab/wiki/EEG-and-ERP-Channel-Operations -browser
+
+%--------------------------------------------------------------------------
+function pushbutton_RUN_Callback(hObject, eventdata, handles)
+listname = handles.listname;
+compacteditor(hObject, eventdata, handles);
+formulalist = get(handles.editor,'String');
+wchmsgon = get(handles.chwarning,'Value');
+keeplocs = get(handles.chkeeplocs,'Value');
+
+
+if strcmp(formulalist,'')
+ msgboxText = 'You have not written any formula!';
+ title = 'ERPLAB: chanoperGUI few inputs';
+ errorfound(msgboxText, title);
+ return
+end
+if size(formulalist,2)>256
+ msgboxText = ['Formulas length exceed 256 characters.\n\n'...
+ 'Be sure to press [Enter] after you have entered each formula.'];
+ title = 'ERPLAB: chanoperGUI few inputs';
+ errorfound(sprintf(msgboxText), title);
+ return
+end
+
+%
+% Check formulas
+%
+if get(handles.button_recursive,'Value')
+ editormode = 0;
+else
+ editormode = 1;
+end
+
+typedata = lower(handles.typedata);
+[option, recall, goeson] = checkformulas(cellstr(formulalist), [typedata 'chanoperGUI'], editormode);
+
+if goeson==0
+ return
+end
+if isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==1
+ BackERPLABcolor = [1 0.9 0.3]; % yellow
+ question = ['Equations at editor window have not been saved yet.\n\n'...
+ 'What would you like to do?'];
+ title = 'WARNING: Save List of edited chans';
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor)
+ button = questdlg(sprintf(question), title,'Save and run','Run without saving', 'Cancel','Run without saving');
+ set(0,'DefaultUicontrolBackgroundColor',oldcolor)
+
+ if strcmpi(button,'Save and run')
+ fullname = savelist(hObject, eventdata, handles);
+ listname = fullname;
+ handles.output = {listname, wchmsgon}; % sent filenam string)
+ elseif strcmpi(button,'Run without saving')
+ handles.output = {cellstr(formulalist), wchmsgon}; % sent like a cell string (with formulas)
+ elseif strcmpi(button,'Cancel') || strcmpi(button,'')
+ handles.output = [];
+ handles.listname = [];
+ % Update handles structure
+ guidata(hObject, handles);
+ return
+ end
+elseif isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==0
+ handles.output = {cellstr(formulalist), wchmsgon}; % sent like a cell string (with formulas)
+
+elseif ~isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==1
+ handles.output = {listname, wchmsgon}; % sent filename string
+
+elseif ~isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==0
+ handles.output = {cellstr(formulalist), wchmsgon}; % sent like a cell string (with formulas)
+end
+
+% handles.output
+% formtype = handles.formtype;
+% erpworkingmemory(formtype, formulalist);
+
+%
+% memory for Gui
+%
+chanopGUI.emode = editormode;
+chanopGUI.hmode = get(handles.checkbox_sendfile2history,'Value');
+chanopGUI.listname = listname;
+chanopGUI.keeplocs = keeplocs;
+chanopGUI.chanlocs = handles.locs;
+disp(chanopGUI.chanlocs)
+erpworkingmemory('chanopGUI', chanopGUI);
+
+try
+ handles.output{3} = keeplocs;
+catch
+ disp('Problem setting location preference')
+end
+
+
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+function cancel_Callback(hObject, eventdata, handles)
+
+handles.output = [];
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+function eraser_Callback(hObject, eventdata, handles)
+% %
+% % for undo
+% %
+% formulas = get(handles.editor, 'String');
+% undocount = handles.undocount;
+% handles.formulas{undocount} = formulas;
+% undocount = undocount + 1;
+% handles.undocount = undocount;
+formulas = get(handles.editor, 'String');
+if isempty(formulas)
+ return
+end
+
+% handles = editorbackup(hObject, eventdata, handles);
+set(handles.editor, 'String','')
+handles.output = [];
+disp('Formulas were erased.')
+set(handles.button_savelist, 'Enable','off')
+handles.listname = [];
+% Update handles structure
+guidata(hObject, handles);
+
+%--------------------------------------------------------------------------
+function help_Callback(hObject, eventdata, handles)
+
+fprintf('\n\n\n\n\n')
+help pop_chanoperator
+
+%--------------------------------------------------------------------------
+function button_saveaslist_Callback(hObject, eventdata, handles)
+
+compacteditor(hObject, eventdata, handles);
+fulltext = strtrim(get(handles.editor,'String'));
+
+if size(fulltext,2)>256
+ msgboxText = ['Formulas length exceed 256 characters.\n\n'...
+ 'Be sure to press [Enter] after you have entered each formula.'];
+ title = 'ERPLAB: chanoperGUI few inputs';
+ errorfound(sprintf(msgboxText), title);
+ return
+end
+if ~strcmp(fulltext,'')
+ fullname = savelist(hObject, eventdata, handles);
+ if isempty(fullname)
+ return
+ end
+ set(handles.edit_filelist, 'String', fullname )
+ set(handles.button_savelist, 'Enable', 'on')
+ handles.listname = fullname;
+ % Update handles structure
+ guidata(hObject, handles);
+else
+ set(handles.button_saveaslist,'Enable','off')
+ msgboxText = 'You have not written any formula yet!';
+ title = 'ERPLAB: chanoperGUI few inputs';
+ errorfound(msgboxText, title);
+ set(handles.button_saveaslist,'Enable','on')
+ return
+end
+
+%--------------------------------------------------------------------------
+function button_loadlist_Callback(hObject, eventdata, handles)
+[filename, filepath] = uigetfile({'*.txt';'*.*'},'Select a formulas-file');
+
+if isequal(filename,0)
+ disp('User selected Cancel')
+ return
+else
+ fullname = fullfile(filepath, filename);
+ disp(['pop_chanoperation(): For formulas-file, user selected ', fullname])
+end
+
+set(handles.edit_filelist,'String',fullname);
+fid_formula = fopen( fullname );
+
+try
+ formcell = textscan(fid_formula, '%s','delimiter', '\r');
+ formulas = char(formcell{:});
+catch
+ serr = lasterror;
+ msgboxText = ['Please, check your file: \n';
+ fullname '\n'...
+ serr.message];
+ title = 'ERPLAB: pop_chanoperation() error:';
+ errorfound(sprintf(msgboxText), title);
+ return
+end
+if size(formulas,2)>256
+ msgboxText = ['Formulas length exceed 256 characters.\n\n'...
+ 'Be sure to press [Enter] after you have entered each formula.'];
+ title = 'ERPLAB: chanoperGUI few inputs';
+ errorfound(sprintf(msgboxText), title);
+ return
+end
+
+compacteditor(hObject, eventdata, handles);
+set(handles.editor,'String',formulas);
+fclose(fid_formula);
+set(handles.button_savelist, 'Enable','on')
+handles.listname = fullname;
+
+% Update handles structure
+guidata(hObject, handles);
+
+%--------------------------------------------------------------------------
+function listboxchan1_Callback(hObject, eventdata, handles)
+
+numchan = get(hObject, 'Value');
+if isempty(numchan)
+ return
+end
+
+linet = get(handles.editor, 'Value');
+
+if nnz(linet) == 0
+ linet = 1;
+end
+
+formulas = cellstr(get(handles.editor, 'String'));
+formulas{linet} = [formulas{linet} 'ch' num2str(numchan)];
+set(handles.editor, 'String', char(formulas));
+
+%--------------------------------------------------------------------------
+function listboxchan1_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function button_example_Callback(hObject, eventdata, handles)
+
+% %
+% % for undo
+% %
+% formulas = get(handles.editor, 'String');
+% undocount = handles.undocount;
+% handles.formulas{undocount} = formulas;
+% undocount = undocount + 1;
+% handles.undocount = undocount;
+
+nchan = handles.nchan;
+example = handles.example;
+exacounter = handles.exacounter;
+exacounter = exacounter + 1;
+text = cellstr(get(handles.editor, 'String'));
+
+if get(handles.button_no_recu,'Value')
+ prechar = 'n';
+else
+ prechar = '';
+end
+if isempty([text{:}]) || exacounter>length(example)
+ exacounter = 1;
+end
+if length(text)==1 && strcmp(text{1}, '')
+ exacurr = char(regexprep(example{exacounter},'@',num2str(nchan+exacounter)));
+ text{1} = [prechar exacurr];
+else
+ exacurr = char(regexprep(example{exacounter},'@',num2str(nchan+exacounter)));
+ text{end+1} = [prechar exacurr];
+end
+
+set(handles.editor, 'String', char(text));
+% handles = editorbackup(hObject, eventdata, handles);
+handles.exacounter = exacounter;
+% Update handles structure
+guidata(hObject, handles);
+
+%--------------------------------------------------------------------------
+function fullname = savelist(hObject, eventdata, handles)
+fulltext = char(get(handles.editor,'String'));
+
+if isempty(fulltext)
+ return
+end
+
+fullnamepre = get(handles.edit_filelist,'String');
+
+%
+% Save OUTPUT file
+%
+[filename, filepath, filterindex] = uiputfile({'*.txt';'*.dat';'*.*'},'Save formulas-file as', fullnamepre);
+
+if isequal(filename,0)
+ disp('User selected Cancel')
+ fullname = [];
+ return
+else
+ [px, fname, ext] = fileparts(filename);
+
+ if strcmp(ext,'')
+ if filterindex==1 || filterindex==3
+ ext = '.txt';
+ else
+ ext = '.dat';
+ end
+ end
+
+ fname = [ fname ext];
+ fullname = fullfile(filepath, fname);
+
+ fid_list = fopen( fullname , 'w');
+
+ for i=1:size(fulltext,1)
+ fprintf(fid_list,'%s\n', fulltext(i,:));
+ end
+
+ fclose(fid_list);
+ set(handles.button_savelist, 'Enable','on')
+end
+
+%--------------------------------------------------------------------------
+function compacteditor(hObject, eventdata, handles)
+texteditor = strtrim(get(handles.editor,'String'));
+
+if isempty(texteditor)
+ return
+end
+
+formul = cellstr(texteditor);
+nfl = length(formul);
+k = 1;
+formulalist = cell(1);
+
+% removes blank lines
+for i=1:nfl
+ if ~strcmp(formul{i},'')
+ % removes blank lines
+ formulalist{k} = regexprep(formul{i},'[^\s](label)[^\s]',' $1 ', 'ignorecase');
+ k = k+1;
+ end
+end
+
+formulalist = strtrimx(formulalist); % special white space removing
+set(handles.editor,'String', char(formulalist));
+drawnow
+
+%--------------------------------------------------------------------------
+function check_aoperations(hObject, eventdata, handles)
+texteditor = strtrim(get(handles.editor,'String'));
+if isempty(texteditor)
+ return
+end
+
+formul = cellstr(texteditor);
+nfl = length(formul);
+k = 1;
+formulalist = cell(1);
+
+for i=1:nfl
+ if ~strcmp(formul{i},'')
+ formulalist{k} = formul{i};
+ k = k+1;
+ end
+end
+
+formulalist = strtrimx(formulalist);
+set(handles.editor,'String', char(formulalist));
+
+%--------------------------------------------------------------------------
+function button_savelist_Callback(hObject, eventdata, handles)
+compacteditor(hObject, eventdata, handles);
+fulltext = strtrim(get(handles.editor,'String'));
+
+if size(fulltext,2)>256
+ msgboxText = ['Formulas length exceed 256 characters.\n\n'...
+ 'Be sure to press [Enter] after you have entered each formula.'];
+ title = 'ERPLAB: chanoperGUI few inputs';
+ errorfound(sprintf(msgboxText), title);
+ return
+end
+if ~isempty(fulltext)
+
+ fullname = get(handles.edit_filelist, 'String');
+
+ if ~strcmp(fullname,'')
+ fid_list = fopen( fullname , 'w');
+
+ for i=1:size(fulltext,1)
+ fprintf(fid_list,'%s\n', fulltext(i,:));
+ end
+
+ fclose(fid_list);
+ handles.listname = fullname;
+ % Update handles structure
+ guidata(hObject, handles);
+ disp(['Saving equation list at ' fullname ' '])
+ else
+ button_saveaslist_Callback(hObject, eventdata, handles)
+ return
+ end
+else
+ set(handles.button_saveaslist,'Enable','off')
+ msgboxText = 'You have not written any formula yet!';
+ title = 'ERPLAB: chanoperGUI few inputs';
+ errorfound(msgboxText, title);
+ set(handles.button_saveaslist,'Enable','on')
+ return
+end
+
+%--------------------------------------------------------------------------
+function checkbox_sendfile2history_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function edit_filelist_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function edit_filelist_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function button_clearfile_Callback(hObject, eventdata, handles)
+set(handles.edit_filelist,'String','');
+set(handles.button_savelist, 'Enable', 'off')
+
+%--------------------------------------------------------------------------
+function button_recursive_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+ set(handles.button_no_recu,'Value',0)
+ val = testsyntaxtype(hObject, eventdata, handles, 'recu');
+
+ if val==0;
+ set(handles.button_recursive, 'Value', 0)
+ set(handles.button_no_recu, 'Value', 1)
+ end
+
+ %%% handles = editorbackup(hObject, eventdata, handles);
+ %%% Update handles structure
+ %%guidata(hObject, handles);
+else
+ set(hObject,'Value',1)
+end
+
+%--------------------------------------------------------------------------
+function button_no_recu_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+ set(handles.button_recursive,'Value',0)
+ val = testsyntaxtype(hObject, eventdata, handles, 'norecu');
+ if val==0
+ set(handles.button_recursive, 'Value', 1)
+ set(handles.button_no_recu, 'Value', 0)
+ end
+ %%% handles = editorbackup(hObject, eventdata, handles);
+ %%% Update handles structure
+ %%%guidata(hObject, handles);
+else
+ set(hObject,'Value',1)
+end
+
+%--------------------------------------------------------------------------
+function val = testsyntaxtype(hObject, eventdata, handles, whocall)
+val = 1;
+formulaArray = get(handles.editor,'String');
+
+if isempty(formulaArray)
+ return
+else
+ formulaArray = strtrim(cellstr(formulaArray));
+end
+nformulas = length(formulaArray);
+
+[expspliter parts] = regexp(formulaArray, '=','match','split');
+ask4fix = 1;
+wantfix = 0;
+newnumchan = 1;
+
+for t=1:nformulas
+ fcomm = formulaArray{t};
+ tokcommentb = regexpi(fcomm, '^#', 'match'); % comment symbol (June 3, 2013)
+
+ if isempty(tokcommentb) % skip comment symbol
+ pleft = regexpi(parts{t}{1}, '(\s*nch[an]*\d+)', 'tokens');
+ plcom = regexpi(parts{t}{1}, '(\s*ch[an]*\d+)', 'tokens');
+
+ if isempty(pleft) && ~isempty(plcom) && strcmpi(whocall,'norecu')
+ if ask4fix
+ BackERPLABcolor = [1 0.9 0.3]; % yellow
+ question = ['For non recursive mode, left side of equation\nmust be define as a new channel.\n'...
+ 'For instance, nchan1 = ...\n\n'...
+ 'Do you want that ERPLAB corrects the syntax for you?'];
+ title = 'WARNING: Syntax is not proper for non recursive mode';
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor)
+ button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes');
+ set(0,'DefaultUicontrolBackgroundColor',oldcolor)
+
+ if strcmpi(button,'Yes')
+ ask4fix = 0;
+ wantfix = 1;
+ elseif strcmpi(button,'Cancel')
+ val = 0; % cancel
+ break
+ else
+ ask4fix = 0;
+ wantfix = 0;
+ end
+ %else
+ % wantfix =1;
+ end
+ elseif ~isempty(pleft) && strcmpi(whocall,'recu')
+ if ask4fix
+ BackERPLABcolor = [1 0.9 0.3]; % yellow
+ question = ['For recursive mode, left side of equation cannot\nbe define as a new channel.\n'...
+ 'For instance, you must write chan1 = ...\n\n'...
+ 'Do you want that ERPLAB corrects the syntax for you?'];
+ title = 'WARNING: Syntax is not proper for recursive mode';
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor)
+ button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes');
+ set(0,'DefaultUicontrolBackgroundColor',oldcolor)
+
+ if strcmpi(button,'Yes')
+ ask4fix = 0;
+ wantfix =1;
+ elseif strcmpi(button,'Cancel')
+ val = 0; % cancel
+ break
+ else
+ ask4fix = 0;
+ wantfix = 0;
+ end
+ %else
+ % wantfix =1;
+ end
+ %else
+ % wantfix = 0;
+ end
+ if wantfix && (~isempty(pleft) || ~isempty(plcom))% fixed (June 3, 2013): JLC
+ fprintf('WARNING: equation %s ', formulaArray{t})
+ if strcmpi(whocall,'recu') % for recursive mode delete the n in nch
+ formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*','','ignorecase')), strtrim(parts{t}{2}));
+ else
+ formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*ch(\D*)(\d*)',['nch$1' num2str(newnumchan)],'ignorecase')), strtrim(parts{t}{2}));
+ newnumchan = newnumchan+1;
+ end
+ fprintf('was changed to equation %s \n', formulaArray{t})
+ end
+ end
+end
+if val==1
+ set(handles.editor,'String', char(formulaArray));
+end
+
+%--------------------------------------------------------------------------
+function chwarning_Callback(hObject, eventdata, handles)
+%
+% if get(hObject,'Value')
+% %
+% % Gui memory
+% %
+% erpworkingmemory('wchmsgon', 1);
+% else
+% %
+% % Gui memory
+% %
+% erpworkingmemory('wchmsgon', 0);
+% end
+
+%--------------------------------------------------------------------------
+function pushbutton_export_chan_list_Callback(hObject, eventdata, handles)
+list_of_chans = get(handles.listboxchan1,'String');
+nloch = length(list_of_chans);
+
+for i=1:nloch
+ fprintf('%s\n',list_of_chans{i});
+end
+
+fprintf('\n\nEnd of list.\n\n')
+
+%--------------------------------------------------------------------------
+function pushbutton_removechan_Callback(hObject, eventdata, handles)
+typedata = handles.typedata;
+chan2del = deletechanGUI(typedata);
+nchan = handles.nchan;
+keeplocs = get(handles.chkeeplocs,'Value');
+
+if ~isempty(chan2del)
+ chan2del = unique_bc2(cell2mat(chan2del));
+ if max(chan2del)>nchan && nnz(isinf(chan2del))==0
+ msgboxText = 'You are specifying non-existing channels!';
+ title = 'ERPLAB: chanoperGUI remove channels';
+ errorfound(sprintf(msgboxText), title);
+ return
+ end
+ if min(chan2del)<1 && nnz(isinf(chan2del))==0
+ msgboxText = 'You are specifying freaky non-existing channels!';
+ title = 'ERPLAB: chanoperGUI remove channels';
+ errorfound(sprintf(msgboxText), title);
+ return
+ end
+ if nnz(isnan(chan2del))>0 || nnz(isinf(chan2del))>0
+ msgboxText = ['Channel problem\n'...
+ 'You are specifying freaky non-existing channels!'];
+ title = 'ERPLAB: chanoperGUI remove channels';
+ errorfound(sprintf(msgboxText), title);
+ return
+ end
+ if strcmpi(typedata, 'EEG')
+ eqtn = sprintf('deletechan(%s)', vect2colon(chan2del, 'Delimiter','off'));
+ else
+ eqtn = sprintf('delerpchan(%s)', vect2colon(chan2del, 'Delimiter','off'));
+ end
+
+ wchmsgon = get(handles.chwarning,'Value');
+ handles.output = {{eqtn}, wchmsgon}; % sent like a cell string (with formulas)
+ try
+ handles.output{3} = keeplocs;
+ catch
+ disp('Problem setting location preference')
+ end
+ % Update handles structure
+ guidata(hObject, handles);
+ uiresume(handles.gui_chassis);
+else
+ return
+end
+
+%--------------------------------------------------------------------------
+function pushbutton_rerefwizard_Callback(hObject, eventdata, handles)
+% set to non-recursive mode
+set(handles.button_recursive, 'Value', 0)
+set(handles.button_no_recu, 'Value', 1)
+
+% open reference wizard
+formulalist = rerefassistantGUI(handles.nchan, handles.listch);
+if isempty(formulalist)
+ return
+end
+
+compacteditor(hObject, eventdata, handles);
+formulas = get(handles.editor, 'String');
+
+if get(handles.button_no_recu,'Value')
+ formulalist = cellstr([formulalist{:}]);
+ for t=1:length(formulalist)
+ [expspliter parts] = regexp(formulalist, '=','match','split');
+ formulalist{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '[^n]*ch','nch','ignorecase')), strtrim(parts{t}{2}));
+ end
+ formulalist = char(formulalist);
+end
+
+if isempty(formulas)
+ set(handles.editor,'String',formulalist);
+else
+ formulalist = cellstr(formulalist);
+ formulas = cellstr(formulas);
+ formt = [formulas ;formulalist];
+ formt = char(formt);
+ set(handles.editor,'String',formt);
+end
+
+% %--------------------------------------------------------------------------
+% function pushbutton_undo_Callback(hObject, eventdata, handles)
+%
+% undocount = handles.undocount;
+% if undocount>1
+% undocount = undocount - 1;
+% formulas = handles.formulas{undocount};
+% handles.undocount = undocount;
+% set(handles.editor, 'String',char(formulas));
+% set(handles.pushbutton_redo,'Enable','on')
+%
+% % formulas = get(handles.edit_filelist, 'String');
+% % Update handles structure
+% guidata(hObject, handles);
+% end
+% if undocount==1
+% set(handles.pushbutton_undo,'Enable','off')
+% set(handles.pushbutton_redo,'Enable','on')
+% end
+
+%--------------------------------------------------------------------------
+% function pushbutton_redo_Callback(hObject, eventdata, handles)
+%
+% nformu = length(handles.formulas);
+% undocount = handles.undocount;
+% if undocount .
+
+function varargout = f_erp2ascGUI(varargin)
+
+% Begin initialization code - DO NOT EDIT
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @f_erp2ascGUI_OpeningFcn, ...
+ 'gui_OutputFcn', @f_erp2ascGUI_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+% End initialization code - DO NOT EDIT
+
+%--------------------------------------------------------------------------
+function f_erp2ascGUI_OpeningFcn(hObject, eventdata, handles, varargin)
+
+% Choose default command line output for f_erp2ascGUI
+handles.output = [];
+try
+ ERP = varargin{1};
+catch
+ ERP.erpname = 'No erp was imported';
+ ERP.filename = 'No erp was imported';
+ ERP.nbin =1;
+ ERP.nchan = 1;
+ ERP.chanlocs(1).labels = 'None';
+ ERP.bindescr{1} = 'None';
+ ERP.bindata = zeros(1,10,1);
+end
+
+try
+ binArray = varargin{2};
+ chanArray = varargin{3};
+catch
+ binArray = 1;
+ chanArray = 1;
+end
+
+%
+% Name & version
+%
+erplab_studio_default_values;
+version = erplabstudiover;
+set(handles.gui_chassis,'Name', strcat('EStudio',version,' - Save "',ERP.erpname, '" as ERPSS'))
+[pathx, erpfilename, ext] = fileparts(ERP.filename);
+ERPFileName = char(strcat(erpfilename,'.txt'));
+
+set(handles.edit_saveas, 'String',fullfile(pathx,ERPFileName) );
+
+
+%%----------------------Setting for bin and channels-----------------------
+listb = {''};
+nbin = ERP.nbin; % Total number of bins
+try
+ for b=1:nbin
+ listb{b}= ['BIN' num2str(b) ' = ' ERP.bindescr{b} ];
+ end
+catch
+ listb = '';
+end
+handles.listb = listb;
+handles.indxlistb = binArray;
+
+nchan = ERP.nchan; % Total number of channels
+if ~isfield(ERP.chanlocs,'labels')
+ for e=1:nchan
+ ERP.chanlocs(e).labels = ['Ch' num2str(e)];
+ end
+end
+listch = {''};
+try
+ for ch =1:nchan
+ listch{ch} = [num2str(ch) ' = ' ERP.chanlocs(ch).labels ];
+ end
+catch
+ listch = '';
+end
+handles.listch = listch;
+handles.indxlistch = chanArray;
+
+set(handles.edit3_custom_bin,'String', vect2colon(binArray, 'Delimiter', 'off'));
+set(handles.edit_custom_chan,'String', vect2colon(chanArray, 'Delimiter', 'off'));
+handles.ERP = ERP;
+
+
+% helpbutton
+
+%
+% Color GUI
+%
+handles = painterplabstudio(handles);
+%
+% %
+% % Set font size
+% %
+handles = setfonterplabestudio(handles);
+
+% Update handles structure
+guidata(hObject, handles);
+
+% help
+% helpbutton
+
+% UIWAIT makes f_erp2ascGUI wait for user response (see UIRESUME)
+uiwait(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+function varargout = f_erp2ascGUI_OutputFcn(hObject, eventdata, handles)
+
+% Get default command line output from handles structure
+varargout{1} = handles.output;
+
+% The figure can be deleted now
+delete(handles.gui_chassis);
+
+
+function edit3_custom_bin_Callback(hObject, eventdata, handles)
+
+BinString = str2num(handles.edit3_custom_bin.String);
+ERP = handles.ERP;
+% [chk, msgboxText] = chckbinandchan(ERP, BinString, []);
+[chk, msgboxText] = f_ERP_chckbinandchan(ERP, BinString, [],1);
+
+if chk(1)
+ title = 'EStudio: f_export2text GUI for bin input!';
+ errorfound(msgboxText, title);
+ return;
+end
+% --- Executes during object creation, after setting all properties.
+function edit3_custom_bin_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+% --- Executes on button press in pushbutton7_browse_bin.
+function pushbutton7_browse_bin_Callback(hObject, eventdata, handles)
+listb = handles.listb;
+indxlistb = handles.indxlistb;
+indxlistb = indxlistb(indxlistb<=length(listb));
+titlename = 'Select Bin(s)';
+
+if get(hObject, 'Value')
+ %set(handles.pushbutton_browsechan, 'Enable', 'off')
+ if ~isempty(listb)
+ bin = browsechanbinGUI(listb, indxlistb, titlename);
+ if ~isempty(bin)
+ set(handles.edit3_custom_bin, 'String', vect2colon(bin, 'Delimiter', 'off'));
+ handles.indxlistb = bin;
+ % Update handles structure
+ guidata(hObject, handles);
+ else
+ disp('User selected Cancel')
+ return
+ end
+ else
+ msgboxText = 'No bin information was found';
+ title = 'EStudio: f_export2text GUI for bin input';
+ errorfound(msgboxText, title);
+ return
+ end
+
+end
+
+
+function edit_custom_chan_Callback(hObject, eventdata, handles)
+chanString = str2num(handles.edit_custom_chan.String);
+ERP = handles.ERP;
+
+[chk, msgboxText] = f_ERP_chckbinandchan(ERP, [],chanString, 2);
+
+if chk(2)
+ title = 'EStudio: f_export2text GUI for channel input!';
+ errorfound(msgboxText, title);
+ return;
+end
+
+
+% --- Executes during object creation, after setting all properties.
+function edit_custom_chan_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+% --- Executes on button press in pushbutton8_browse_chan.
+function pushbutton8_browse_chan_Callback(hObject, eventdata, handles)
+
+listch = handles.listch;
+indxlistch = handles.indxlistch;
+indxlistch = indxlistch(indxlistch<=length(listch));
+titlename = 'Select Channel(s)';
+
+if get(hObject, 'Value')
+ if ~isempty(listch)
+ ch = browsechanbinGUI(listch, indxlistch, titlename);
+ if ~isempty(ch)
+ set(handles.edit_custom_chan, 'String', vect2colon(ch, 'Delimiter', 'off'));
+ handles.indxlistch = ch;
+ % Update handles structure
+ guidata(hObject, handles);
+ else
+ disp('User selected Cancel')
+ return
+ end
+ else
+ msgboxText = 'No channel information was found';
+ title = 'EStudio: f_export2text GUI for channel input';
+ errorfound(msgboxText, title);
+ return
+ end
+end
+
+%--------------------------------------------------------------------------
+function pushbutton_cancel_Callback(hObject, eventdata, handles)
+disp('User selected cancel');
+handles.output = [];
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+% function pushbutton_help_Callback(hObject, eventdata, handles)
+% % doc pop_export2text
+% web 'https://github.com/lucklab/erplab/wiki/Exporting,-Editing,-and-Importing-EVENTLISTS' -browser
+%--------------------------------------------------------------------------
+function pushbutton_export_Callback(hObject, eventdata, handles)
+
+filename = get(handles.edit_saveas, 'string');
+% bins = str2num(get(handles.edit_bins, 'string'));
+
+if isempty(filename)
+ msgboxText = 'You must enter a filename!';
+ title = 'EStudio: f_erp2asc GUI empty filename';
+ errorfound(msgboxText, title);
+ return
+end
+
+
+BinArray = str2num(handles.edit3_custom_bin.String);
+ERP = handles.ERP;
+[chk, msgboxText] = f_ERP_chckbinandchan(ERP, BinArray, [],1);
+
+if chk(1)
+ title = 'EStudio: f_erp2asc GUI for bin input!';
+ errorfound(msgboxText, title);
+ return;
+end
+
+
+ChanArray = str2num(handles.edit_custom_chan.String);
+[chk, msgboxText] = f_ERP_chckbinandchan(ERP, [],ChanArray, 2);
+
+if chk(2)
+ title = 'EStudio: f_erp2asc GUI for channel input!';
+ errorfound(msgboxText, title);
+ return;
+end
+
+ERP.bindata = ERP.bindata(ChanArray,:,BinArray);
+ERP.nbin = numel(BinArray);
+ERP.nchan = numel(ChanArray);
+ERP.chanlocs = ERP.chanlocs(ChanArray);
+for Numofbin = 1:numel(BinArray)
+ ERP.bindescr{Numofbin} = ERP.bindescr{BinArray(Numofbin)};
+end
+
+answer = {ERP,filename};
+handles.output = answer;
+
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+% -------------------------------------------------------------------------
+function edit_saveas_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function edit_saveas_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function pushbutton_browse_Callback(hObject, eventdata, handles)
+
+%
+% Save OUTPUT file
+%
+ERP = handles.ERP;
+prename = get(handles.edit_saveas,'String');
+[fname, pathname, filterindex] = uiputfile({'*.txt';'*.*'},['Save "',ERP.erpname,'"as'], prename);
+
+if isequal(fname,0)
+ disp('User selected Cancel')
+ return
+else
+
+ [px, fname2, ext] = fileparts(fname);
+
+ if strcmp(ext,'')
+
+ if filterindex==1 || filterindex==2
+ ext = '.txt';
+ else
+ ext = '.txt';
+ end
+
+ fname = [ fname2 ext];
+ end
+
+ set(handles.edit_saveas,'String', fullfile(pathname, fname));
+% disp(['To save ERP, user selected ', fullfile(pathname, fname)])
+end
+
+
+
+%--------------------------------------------------------------------------
+function gui_chassis_CloseRequestFcn(hObject, eventdata, handles)
+if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting')
+ handles.output = [];
+ %Update handles structure
+ guidata(hObject, handles);
+ uiresume(handles.gui_chassis);
+else
+ % The GUI is no longer waiting, just close it
+ delete(handles.gui_chassis);
+end
diff --git a/studio_functions/GUIs/ERP Tab/f_erp_dataquality_SME_GUI.m b/studio_functions/GUIs/ERP Tab/f_erp_dataquality_SME_GUI.m
new file mode 100755
index 00000000..d755cf36
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_erp_dataquality_SME_GUI.m
@@ -0,0 +1,342 @@
+
+%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com
+%Center for Mind and Brain
+%University of California, Davis
+%Davis, CA, USA
+%Feb. 2022
+
+
+
+
+function varargout = f_erp_dataquality_SME_GUI(varargin)
+
+global observe_ERPDAT;
+addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged);
+
+
+if nargin < 1
+ beep;
+ help f_erp_dataquality_SME_GUI;
+ return;
+end
+
+
+try
+ ERP = evalin('base','ERP');
+catch
+ beep;
+ disp('f_erp_dataquality_SME_GUI: No ERP was found in workspace');
+ return;
+end
+
+if isempty(ERP)
+ msgboxText = 'No ERPset was found!';
+ title_msg = 'ERPLAB: f_erp_dataquality_SME_GUI() error:';
+ errorfound(msgboxText, title_msg);
+ return
+end
+if ~isfield(ERP, 'bindata')
+ msgboxText = 'f_erp_dataquality_SME_GUI cannot handle an empty ERP dataset';
+ title = 'ERPLAB: f_erp_dataquality_SME_GUI() error:';
+ errorfound(msgboxText, title);
+ return
+end
+if isempty(ERP.bindata)
+ msgboxText = 'f_erp_dataquality_SME_GUI cannot handle an empty ERP dataset';
+ title = 'ERPLAB: f_erp_dataquality_SME_GUI() error:';
+ errorfound(msgboxText, title);
+ return
+end
+
+try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+catch
+ ColorB_def = [0.95 0.95 0.95];
+end
+
+if nargin == 0
+ fig = figure(); % Parent figure
+ Erp_information = uiextras.BoxPanel('Parent', fig, 'Title', 'Data Quality (aSME)', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel
+elseif nargin == 1
+ Erp_information = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Data Quality (aSME)', 'Padding', 5,'BackgroundColor',ColorB_def);
+else
+ Erp_information = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Data Quality (aSME)', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def);
+end
+
+varargout{1} = Erp_information;
+gui_erp_DQSME = struct;
+try
+ FonsizeDefault = varargin{2};
+catch
+ FonsizeDefault = [];
+end
+if isempty(FonsizeDefault)
+ FonsizeDefault = f_get_default_fontsize();
+end
+drawui_erp_information(FonsizeDefault);
+
+
+ function drawui_erp_information(FonsizeDefault)
+
+
+ try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+ catch
+ ColorB_def = [0.95 0.95 0.95];
+ end
+ SelectedERP= estudioworkingmemory('selectederpstudio');
+ if isempty(SelectedERP)
+ SelectedERP = observe_ERPDAT.CURRENTERP;
+
+ if isempty(SelectedERP)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ SelectedERP_current_index = S_binchan.Select_index;
+
+
+
+ if ~isempty(SelectedERP)&& SelectedERP_current_index> numel(SelectedERP)
+ SelectedERP(1) = observe_ERPDAT.CURRENTERP;
+ SelectedERP_current_index = 1;
+ end
+
+ if strcmp(observe_ERPDAT.ALLERP(SelectedERP(SelectedERP_current_index)).erpname,'No ERPset loaded')
+ Enable_label = 'off';
+ else
+ Enable_label = 'on';
+ end
+
+ ERP_SME_summary = f_dq_summary(observe_ERPDAT.ALLERP(SelectedERP(SelectedERP_current_index)));
+
+ gui_erp_DQSME.DataSelBox = uiextras.VBox('Parent', Erp_information, 'Spacing',1,'BackgroundColor',ColorB_def);
+
+ %%----------------------------Setting midian SME---------------------
+ gui_erp_DQSME.Median_sme = uiextras.HBox('Parent',gui_erp_DQSME.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_DQSME.Median_sme_title = uicontrol('Style','text','Parent', gui_erp_DQSME.Median_sme,'String','Median:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ set(gui_erp_DQSME.Median_sme_title,'HorizontalAlignment','left');
+ Median_tw =ERP_SME_summary{3,1};
+ Median_name = strcat(num2str(roundn(ERP_SME_summary{1,1},-2)),', chan.',num2str(ERP_SME_summary{2,1}),',',32,num2str(Median_tw(1)),'-',num2str(Median_tw(2)),'ms, bin:',32,num2str(ERP_SME_summary{4,1}));
+ gui_erp_DQSME.Median_sme_name = uicontrol('Style','text','Parent', gui_erp_DQSME.Median_sme,'String',Median_name,'FontSize',FonsizeDefault);
+ set(gui_erp_DQSME.Median_sme_name,'HorizontalAlignment','left','BackgroundColor',ColorB_def);
+ set(gui_erp_DQSME.Median_sme,'Sizes',[60 400]);
+
+ %%----------------------------Setting min. SME---------------------
+ gui_erp_DQSME.min_sme = uiextras.HBox('Parent',gui_erp_DQSME.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_DQSME.min_sme_title = uicontrol('Style','text','Parent', gui_erp_DQSME.min_sme,'String','Min:','FontSize',FonsizeDefault);
+ set(gui_erp_DQSME.min_sme_title,'HorizontalAlignment','left','BackgroundColor',ColorB_def);
+ Min_tw =ERP_SME_summary{3,2};
+ Min_name = strcat(num2str(roundn(ERP_SME_summary{1,2},-2)),', chan.',num2str(ERP_SME_summary{2,2}),',',32,num2str(Min_tw(1)),'-',num2str(Min_tw(2)),'ms, bin:',32,num2str(ERP_SME_summary{4,2}));
+ gui_erp_DQSME.min_sme_name = uicontrol('Style','text','Parent', gui_erp_DQSME.min_sme,'String',Min_name,'FontSize',FonsizeDefault);
+ set(gui_erp_DQSME.min_sme_name,'HorizontalAlignment','left','BackgroundColor',ColorB_def);
+ set(gui_erp_DQSME.min_sme,'Sizes',[40 400]);
+
+ %%----------------------------Setting max. SME---------------------
+ gui_erp_DQSME.max_sme = uiextras.HBox('Parent',gui_erp_DQSME.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_DQSME.max_sme_title = uicontrol('Style','text','Parent', gui_erp_DQSME.max_sme,'String','Max:','FontSize',FonsizeDefault);
+ set(gui_erp_DQSME.max_sme_title,'HorizontalAlignment','left','BackgroundColor',ColorB_def);
+ Max_tw =ERP_SME_summary{3,3};
+ Max_name = strcat(num2str(roundn(ERP_SME_summary{1,3},-2)),', chan.',num2str(ERP_SME_summary{2,3}),',',32,num2str(Max_tw(1)),'-',num2str(Max_tw(2)),'ms, bin:',32,num2str(ERP_SME_summary{4,3}));
+ gui_erp_DQSME.max_sme_name = uicontrol('Style','text','Parent', gui_erp_DQSME.max_sme,'String',Max_name,'FontSize',FonsizeDefault);
+ set(gui_erp_DQSME.max_sme_name,'HorizontalAlignment','left','BackgroundColor',ColorB_def);
+ set(gui_erp_DQSME.max_sme,'Sizes',[40 400]);
+
+ gui_erp_DQSME.DQSME_option = uiextras.HBox('Parent',gui_erp_DQSME.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_DQSME.DQSME_option_table = uicontrol('Style','pushbutton','Parent', gui_erp_DQSME.DQSME_option,'String','Show in a table',...
+ 'callback',@DQSME_table,'Enable',Enable_label,'FontSize',FonsizeDefault);
+
+ gui_erp_DQSME.DQSME_option_file = uicontrol('Style','pushbutton','Parent', gui_erp_DQSME.DQSME_option,'String','Save to file',...
+ 'callback',@DQSME_file,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ set(gui_erp_DQSME.DQSME_option,'Sizes',[120 120]);
+ try
+ ERP_data_quality = observe_ERPDAT.ALLERP(SelectedERP(SelectedERP_current_index)).dataquality.data;
+ catch
+ ERP_data_quality =[];
+ end
+ if isempty(ERP_data_quality)
+ set(gui_erp_DQSME.DQSME_option_table,'Enable','off');
+ set(gui_erp_DQSME.DQSME_option_file,'Enable','off');
+ end
+ gui_erp_DQSME.DQSME_option1 = uiextras.HBox('Parent',gui_erp_DQSME.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_DQSME.DQSME_option_measure = uicontrol('Style','pushbutton','Parent', gui_erp_DQSME.DQSME_option1,'String','Show measures on Command Window',...
+ 'callback',@DQSME_measures,'Enable',Enable_label,'FontSize',FonsizeDefault);
+ uiextras.Empty('Parent', gui_erp_DQSME.DQSME_option1);
+ set(gui_erp_DQSME.DQSME_option1,'Sizes',[240 10]);
+ set(gui_erp_DQSME.DataSelBox,'Sizes',[20 20 20 30 30]);
+ end
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%-----------------------------Subfunction----------------------------------
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+%%--------Settting will be modified if the selected was changed------------
+ function Count_currentERPChanged(~,~)
+ SelectedERP= estudioworkingmemory('selectederpstudio');
+ if isempty(SelectedERP)
+ SelectedERP = observe_ERPDAT.CURRENTERP;
+ if isempty(SelectedERP)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ SelectedERP_current_index = S_binchan.Select_index;
+ if ~isempty(SelectedERP)&& SelectedERP_current_index> numel(SelectedERP)
+ SelectedERP(1) = observe_ERPDAT.CURRENTERP;
+ SelectedERP_current_index = 1;
+ end
+
+ if strcmp(observe_ERPDAT.ALLERP(SelectedERP(SelectedERP_current_index)).erpname,'No ERPset loaded')
+ Enable_label = 'off';
+ else
+ Enable_label = 'on';
+ end
+
+ ERP_SME_summary = f_dq_summary(observe_ERPDAT.ALLERP(SelectedERP(SelectedERP_current_index)));
+ Median_tw =ERP_SME_summary{3,1};
+ Median_name = strcat(num2str(roundn(ERP_SME_summary{1,1},-2)),', chan.',num2str(ERP_SME_summary{2,1}),',',32,num2str(Median_tw(1)),'-',num2str(Median_tw(2)),'ms, bin',32,num2str(ERP_SME_summary{4,1}));
+ gui_erp_DQSME.Median_sme_name.String = Median_name;
+ Min_tw =ERP_SME_summary{3,2};
+ Min_name = strcat(num2str(roundn(ERP_SME_summary{1,2},-2)),', chan.',num2str(ERP_SME_summary{2,2}),',',32,num2str(Min_tw(1)),'-',num2str(Min_tw(2)),'ms, bin',32,num2str(ERP_SME_summary{4,2}));
+ gui_erp_DQSME.min_sme_name.String = Min_name;
+ Max_tw =ERP_SME_summary{3,3};
+ Max_name = strcat(num2str(roundn(ERP_SME_summary{1,3},-2)),', chan.',num2str(ERP_SME_summary{2,3}),',',32,num2str(Max_tw(1)),'-',num2str(Max_tw(2)),'ms, bin',32,num2str(ERP_SME_summary{4,3}));
+ gui_erp_DQSME.max_sme_name.String=Max_name;
+ gui_erp_DQSME.DQSME_option_measure.Enable = Enable_label;
+
+ try% check if the data for SMEs exsists or not
+ data_quality = observe_ERPDAT.ERP.dataquality.data;
+ if isempty(data_quality)
+ Enable_label = 'off';
+ end
+ catch
+ Enable_label = 'off';
+ beep;
+ disp('There no SME exist in current ERPset');
+ end
+ gui_erp_DQSME.DQSME_option_table.Enable = Enable_label;
+ gui_erp_DQSME.DQSME_option_file.Enable = Enable_label;
+
+
+ end
+
+
+
+%%---------------------Save SME to a table---------------------------------
+ function DQSME_table(~,~)
+
+ SelectedERP= estudioworkingmemory('selectederpstudio');
+ if isempty(SelectedERP)
+ SelectedERP = observe_ERPDAT.CURRENTERP;
+
+ if isempty(SelectedERP)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ SelectedERP_current_index = S_binchan.Select_index;
+
+ if ~isempty(SelectedERP)&& SelectedERP_current_index> numel(SelectedERP)
+ SelectedERP_current_index = 1;
+ end
+ DQ_Table_GUI(observe_ERPDAT.ALLERP(SelectedERP(SelectedERP_current_index)),observe_ERPDAT.ALLERP,SelectedERP(SelectedERP_current_index),1);
+ end
+
+
+
+%-----------------Save the SME to a file-----------------------------------
+ function DQSME_file(~,~)
+
+ SelectedERP= estudioworkingmemory('selectederpstudio');
+ if isempty(SelectedERP)
+ SelectedERP = observe_ERPDAT.CURRENTERP;
+
+ if isempty(SelectedERP)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ SelectedERP_current_index = S_binchan.Select_index;
+
+
+ if ~isempty(SelectedERP)&& SelectedERP_current_index> numel(SelectedERP)
+ SelectedERP_current_index = 1;
+ end
+
+ %-----------Setting for import-------------------------------------
+ try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+ catch
+ ColorB_def = [0.7020 0.77 0.85];
+ end
+
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',ColorB_def);
+
+ for Numoferp = 1:numel(SelectedERP)
+ ERP =observe_ERPDAT.ALLERP(SelectedERP(Numoferp));
+ try
+ Datquality = ERP.dataquality;
+ if isempty(Datquality(1).data)&& isempty(Datquality(2).data) && isempty(Datquality(3).data)
+ msgboxText = ['No information for data quality is found!'];
+ question = [ 'No information for data quality is found!'];
+ title = 'ERPLAB Studio: ERPsets';
+ button = questdlg(sprintf(question, msgboxText), title,'OK','OK');
+ else
+ save_data_quality(observe_ERPDAT.ALLERP(SelectedERP(Numoferp)));
+ end
+ catch
+ msgboxText = ['No information for data quality is found!'];
+ question = [ 'No information for data quality is found!'];
+ title = 'ERPLAB Studio: "Save to file" on "Data quality (aSME)".';
+ button = questdlg(sprintf(question, msgboxText), title,'OK','OK');
+ end
+
+ end
+ set(0,'DefaultUicontrolBackgroundColor',[1 1 1]);
+ end
+
+
+
+%-------------------Show which Data Quality measures are in each loaded ERPSET---------------------------
+ function DQSME_measures(~,~)
+ if isempty(observe_ERPDAT.ALLERP)
+ beep;
+ disp('f_erp_dataquality_SME_GUI: No ERP was found!!!');
+ return;
+ end
+ erpset_summary(observe_ERPDAT.ALLERP);
+
+ end
+
+end
\ No newline at end of file
diff --git a/studio_functions/GUIs/ERP Tab/f_erp_informtion_GUI.m b/studio_functions/GUIs/ERP Tab/f_erp_informtion_GUI.m
new file mode 100755
index 00000000..03a9f2ae
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_erp_informtion_GUI.m
@@ -0,0 +1,344 @@
+
+%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com
+%Center for Mind and Brain
+%University of California, Davis
+%Davis, CA, USA
+%Feb. 2022
+
+
+
+
+function varargout = f_erp_informtion_GUI(varargin)
+
+global observe_ERPDAT;
+addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged);
+
+
+if nargin < 1
+ beep;
+ help f_erp_informtion_GUI;
+ return;
+end
+
+
+try
+ ERP = evalin('base','ERP');
+catch
+ beep;
+ disp('f_erp_informtion_GUI: No ERP was found in workspace');
+ return;
+
+end
+
+if isempty(ERP)
+ msgboxText = 'No ERPset was found!';
+ title_msg = 'EStudio: f_erp_informtion_GUI() error:';
+ errorfound(msgboxText, title_msg);
+ return
+end
+if ~isfield(ERP, 'bindata')
+ msgboxText = 'f_erp_informtion_GUI cannot handle an empty ERP dataset';
+ title = 'EStudio: f_erp_informtion_GUI() error:';
+ errorfound(msgboxText, title);
+ return
+end
+if isempty(ERP.bindata)
+ msgboxText = 'f_erp_informtion_GUI cannot handle an empty ERP dataset';
+ title = 'EStudio: f_erp_informtion_GUI() error:';
+ errorfound(msgboxText, title);
+ return
+end
+
+
+try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+catch
+ ColorB_def = [0.95 0.95 0.95];
+end
+if nargin == 0
+ fig = figure(); % Parent figure
+ Erp_information = uiextras.BoxPanel('Parent', fig, 'Title', 'ERP Information', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel
+elseif nargin == 1
+ Erp_information = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERP Information', 'Padding', 5,'BackgroundColor',ColorB_def);
+else
+ Erp_information = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERP Information', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def);
+end
+
+varargout{1} = Erp_information;
+gui_erp_information = struct;
+try
+ FonsizeDefault = varargin{2};
+catch
+ FonsizeDefault = [];
+end
+if isempty(FonsizeDefault)
+ FonsizeDefault = f_get_default_fontsize();
+end
+drawui_erp_information(FonsizeDefault);
+
+
+ function drawui_erp_information(FonsizeDefault)
+ try
+ [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;
+ catch
+ ColorB_def = [0.95 0.95 0.95];
+ end
+ gui_erp_information.DataSelBox = uiextras.VBox('Parent', Erp_information, 'Spacing',1,'BackgroundColor',ColorB_def);
+
+ %%----------------------------Setting sampling rate---------------------
+ gui_erp_information.samplingrate = uiextras.HBox('Parent',gui_erp_information.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_information.samplingrate_title = uicontrol('Style','text','Parent', gui_erp_information.samplingrate,'String','Sampling:','FontSize',FonsizeDefault);
+ if ERP.srate> 0
+ ERP_time_resolution = strcat(32,num2str(roundn(1000/ERP.srate,-2)),32,'ms (resolution);',32,num2str(ERP.srate),32,'Hz','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ else
+ ERP_time_resolution = strcat(32,num2str(0),32,'ms (time resolution);',32,num2str(ERP.srate),32,'Hz (rate)','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ end
+ set(gui_erp_information.samplingrate_title,'HorizontalAlignment','left','BackgroundColor',ColorB_def);
+
+ gui_erp_information.samplingrate_resolution = uicontrol('Style','text','Parent', gui_erp_information.samplingrate,'String',ERP_time_resolution,'FontSize',FonsizeDefault);
+ set(gui_erp_information.samplingrate_resolution,'HorizontalAlignment','left','BackgroundColor',ColorB_def);
+ set(gui_erp_information.samplingrate ,'Sizes',[70 430]);
+
+ %%----------------------------Setting epoch---------------------
+ gui_erp_information.epoch = uiextras.HBox('Parent',gui_erp_information.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_information.epoch_title = uicontrol('Style','text','Parent', gui_erp_information.epoch,'String','Epoch:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ set(gui_erp_information.epoch_title,'HorizontalAlignment','left');
+ gui_erp_information.epoch_name = uicontrol('Style','text','Parent', gui_erp_information.epoch,'String',[32,num2str(roundn(ERP.times(1),-2)),32,'to',32,num2str(roundn(ERP.times(end),-2)),32,'ms (',num2str(numel(ERP.times)),32,'pts)'],'FontSize',FonsizeDefault);
+ set(gui_erp_information.epoch_name,'HorizontalAlignment','left','BackgroundColor',ColorB_def);
+ set(gui_erp_information.epoch ,'Sizes',[50 450]);
+
+ %%----------------------------Number of Channels---------------------
+ gui_erp_information.chan_num = uiextras.HBox('Parent',gui_erp_information.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_information.numofchan_title = uicontrol('Style','text','Parent', gui_erp_information.chan_num,'String','Number of channels:','FontSize',FonsizeDefault);
+ set(gui_erp_information.numofchan_title,'HorizontalAlignment','left','BackgroundColor',ColorB_def);
+ gui_erp_information.numofchan = uicontrol('Style','text','Parent', gui_erp_information.chan_num,'String',[32,num2str(ERP.nchan)],'FontSize',FonsizeDefault);
+ set(gui_erp_information.numofchan,'HorizontalAlignment','left','BackgroundColor',ColorB_def);
+ set(gui_erp_information.chan_num ,'Sizes',[125 375]);
+ % set(gui_erp_information.filename_gui,'Sizes',[100 -1]);
+
+
+ %%----------------------------Number of bins---------------------
+ gui_erp_information.bin_num = uiextras.HBox('Parent',gui_erp_information.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_information.bin_num_title = uicontrol('Style','text','Parent', gui_erp_information.bin_num,'String','Number of bins:','FontSize',FonsizeDefault);
+ set(gui_erp_information.bin_num_title,'HorizontalAlignment','left','BackgroundColor',ColorB_def);
+ gui_erp_information.numofbin = uicontrol('Style','text','Parent', gui_erp_information.bin_num,'String',[num2str(ERP.nbin)],'FontSize',FonsizeDefault);
+ % set(gui_erp_information.filename_gui,'Sizes',[100 -1]);
+ set(gui_erp_information.numofbin,'HorizontalAlignment','left','BackgroundColor',ColorB_def);
+ set(gui_erp_information.bin_num ,'Sizes',[110 390]);
+
+
+ %%----------------------------Total accepted---------------------
+ N_trials = ERP.ntrials;
+ N_trial_total = sum(N_trials.accepted(:))+sum(N_trials.rejected(:))+sum(N_trials.invalid(:));
+ N_trial_rejected = sum(N_trials.rejected(:));
+
+ if N_trial_total ==0
+ Total_rejected_trials = strcat('0');
+ else
+ Total_rejected_trials = strcat(num2str(roundn(N_trial_rejected/N_trial_total,-3)*100),'%');
+ end
+
+ gui_erp_information.total_rejected = uiextras.HBox('Parent',gui_erp_information.DataSelBox);
+ gui_erp_information.total_rejected_title = uicontrol('Style','text','Parent', gui_erp_information.total_rejected,'String','Total rejected trials:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ set(gui_erp_information.total_rejected_title,'HorizontalAlignment','left');
+
+ gui_erp_information.total_rejected_percentage = uicontrol('Style','text','Parent', gui_erp_information.total_rejected,'String',Total_rejected_trials,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);
+ set(gui_erp_information.total_rejected_percentage,'HorizontalAlignment','left');
+ set(gui_erp_information.total_rejected,'Sizes',[125 375]);
+
+ %%------------totla rejected----------
+ gui_erp_information.total_rejected_show = uiextras.HBox('Parent',gui_erp_information.DataSelBox,'BackgroundColor',ColorB_def);
+ gui_erp_information.total_rejected_option = uicontrol('Style','pushbutton','Parent', gui_erp_information.total_rejected_show,'String','Artifact rejection details',...
+ 'callback',@total_reject_ops,'FontSize',FonsizeDefault);
+
+ if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded')
+ gui_erp_information.total_rejected_option.Enable = 'off';
+ end
+ uiextras.Empty('Parent', gui_erp_information.total_rejected_show);
+ set(gui_erp_information.total_rejected_show,'Sizes',[150 250]);
+
+ set(gui_erp_information.DataSelBox,'Sizes',[20 20 20 20 20 30])
+ end
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%-----------------------------Subfunction----------------------------------
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+%%--------Settting will be modified if the selected was changed------------
+ function Count_currentERPChanged(~,~)
+% try
+% ERPloadIndex = estudioworkingmemory('ERPloadIndex');
+% catch
+% ERPloadIndex =0;
+% end
+% if ERPloadIndex==1
+% ALLERPIN = evalin('base','ALLERP');
+% CURRENTERPIN = evalin('base','CURRENTERP');
+% observe_ERPDAT.ALLERP = ALLERPIN;
+% observe_ERPDAT.CURRENTERP =CURRENTERPIN;
+% try
+% observe_ERPDAT.ERP = ALLERPIN(CURRENTERPIN);
+% catch
+% observe_ERPDAT.ERP = ALLERPIN(end);
+% observe_ERPDAT.CURRENTERP =length(ALLERPIN);
+% end
+% end
+
+
+ SelectedERP= estudioworkingmemory('selectederpstudio');
+ if isempty(SelectedERP)
+ SelectedERP = observe_ERPDAT.CURRENTERP;
+
+ if isempty(SelectedERP)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+
+ S_binchan = estudioworkingmemory('geterpbinchan');
+ SelectedERP_current_index = S_binchan.Select_index;
+
+ if ~isempty(SelectedERP)&& SelectedERP_current_index> numel(SelectedERP)
+ SelectedERP(1) = observe_ERPDAT.CURRENTERP;
+ SelectedERP_current_index = 1;
+ end
+
+ if strcmp(observe_ERPDAT.ALLERP(SelectedERP(SelectedERP_current_index)).erpname,'No ERPset loaded')
+ Enable_label = 'off';
+ else
+ Enable_label = 'on';
+ end
+
+ ERP_current_index = observe_ERPDAT.ALLERP(SelectedERP(SelectedERP_current_index));
+ if numel(SelectedERP)==1
+ if ERP_current_index.srate> 0
+ ERP_time_resolution = strcat(32,num2str(roundn(1000/ERP_current_index.srate,-2)),32,'ms(resolution);',32,num2str(ERP_current_index.srate),32,'Hz');
+ else
+ ERP_time_resolution = strcat(32,num2str(0),32,'ms(time resolution);',32,num2str(ERP_current_index.srate),32,'Hz (rate)');
+ end
+ gui_erp_information.samplingrate_resolution.String = ERP_time_resolution;
+ try
+ gui_erp_information.epoch_name.String=char(strcat(num2str(roundn(ERP_current_index.times(1),-2)),32,'to',32,num2str(roundn(ERP_current_index.times(end),-2)),32,...
+ 'ms(',num2str(numel(ERP_current_index.times)),32,'pts)'));
+ catch
+ gui_erp_information.epoch_name.String=char(strcat('0 to 0ms(0 pts)'));
+ end
+
+ gui_erp_information.numofchan.String=num2str(ERP_current_index.nchan);
+ gui_erp_information.numofbin.String=num2str(ERP_current_index.nbin);
+ N_trials = ERP_current_index.ntrials;
+ N_trial_total = sum(N_trials.accepted(:))+sum(N_trials.rejected(:))+sum(N_trials.invalid(:));
+ N_trial_rejected = sum(N_trials.rejected(:));
+ if N_trial_total ==0
+ Total_rejected_trials = strcat('0');
+ else
+ Total_rejected_trials = strcat(num2str(roundn(N_trial_rejected/N_trial_total,-3)*100),'%');
+ end
+ gui_erp_information.total_rejected_percentage.Enable = Enable_label;
+ gui_erp_information.total_rejected_percentage.String = Total_rejected_trials;
+ gui_erp_information.total_rejected_option.Enable = Enable_label;
+ end
+
+ if numel(SelectedERP)>1
+ Check_Selected_erpset = [0 0 0 0 0 0 0];
+ if numel(SelectedERP)>1
+
+ Check_Selected_erpset = S_binchan.checked_ERPset_Index;
+
+ end
+ %%bin
+ if Check_Selected_erpset(1) ==1
+ gui_erp_information.numofbin.String = 'Varied across ERPsets';
+ else
+ try
+ BinNum = observe_ERPDAT.ERP.nbin;
+ catch
+ BinNum = 0;
+ end
+ gui_erp_information.numofbin.String = num2str(BinNum);
+ end
+
+ %%chan
+ if Check_Selected_erpset(2) ==2
+ gui_erp_information.numofchan.String = 'Varied across ERPsets';
+ else
+ try
+ chanNum = observe_ERPDAT.ERP.nchan;
+ catch
+ chanNum = 0;
+ end
+ gui_erp_information.numofchan.String = num2str(chanNum);
+ end
+ %%Total rejected artifacts
+ gui_erp_information.total_rejected_percentage.String = 'Varied across ERPsets';
+
+ %%sampling rate
+ if Check_Selected_erpset(7) ==7
+ gui_erp_information.samplingrate_resolution.String = 'Varied across ERPsets';
+ else
+ try
+ if observe_ERPDAT.ERP.srate
+ ERP_time_resolution = strcat(32,num2str(roundn(1000/ERP_current_index.srate,-2)),32,'ms(resolution);',32,num2str(ERP_current_index.srate),32,'Hz');
+ end
+ catch
+ ERP_time_resolution = strcat(32,num2str(0),32,'ms(time resolution);',32,num2str(ERP_current_index.srate),32,'Hz (rate)');
+ end
+ gui_erp_information.samplingrate_resolution.String = ERP_time_resolution;
+ end
+
+ if any(Check_Selected_erpset(4:6))
+ gui_erp_information.epoch_name.String=char(strcat('Varied across ERPsets'));
+ else
+ try
+ gui_erp_information.epoch_name.String=char(strcat(num2str(roundn(ERP_current_index.times(1),-2)),32,'to',32,num2str(roundn(ERP_current_index.times(end),-2)),32,...
+ 'ms(',num2str(numel(ERP_current_index.times)),32,'pts)'));
+ catch
+ gui_erp_information.epoch_name.String=char(strcat('0 to 0ms(0 pts)'));
+ end
+ end
+
+
+ end
+
+
+ end
+
+
+
+%%----------------Rejection option----------------------------------------
+ function total_reject_ops(~,~)
+
+ SelectedERP= estudioworkingmemory('selectederpstudio');
+ if isempty(SelectedERP)
+ SelectedERP = observe_ERPDAT.CURRENTERP;
+
+ if isempty(SelectedERP)
+ msgboxText = 'No ERPset was selected!!!';
+ title = 'EStudio: ERPsets';
+ errorfound(msgboxText, title);
+ return;
+ end
+ S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP);
+ estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan);
+ estudioworkingmemory('geterpplot',S_erpplot.geterpplot);
+ end
+
+ try
+ for Numoferp = 1:numel(SelectedERP)
+ ERP = observe_ERPDAT.ALLERP(SelectedERP(Numoferp));
+ [ERP, acce, rej, histoflags, erpcom] = pop_summary_AR_erp_detection(ERP);
+ end
+ catch
+ return;
+ end
+ end
+
+end
\ No newline at end of file
diff --git a/studio_functions/GUIs/ERP Tab/f_export2csvGUI.fig b/studio_functions/GUIs/ERP Tab/f_export2csvGUI.fig
new file mode 100755
index 00000000..47afcceb
Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_export2csvGUI.fig differ
diff --git a/studio_functions/GUIs/ERP Tab/f_export2csvGUI.m b/studio_functions/GUIs/ERP Tab/f_export2csvGUI.m
new file mode 100755
index 00000000..48438e6d
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_export2csvGUI.m
@@ -0,0 +1,352 @@
+%
+% Author: Javier Lopez-Calderon & Steven Luck & Guanghui ZHANG
+% Center for Mind and Brain
+% University of California, Davis,
+% Davis, CA
+% 2009 & 2022
+
+%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b
+%
+% Copyright (C) 2008 Javier Lopez-Calderon & Steven Luck,
+% Center for Mind and Brain, University of California, Davis,
+% javlopez@ucdavis.edu, sjluck@ucdavis.edu
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see .
+
+function varargout = f_export2csvGUI(varargin)
+
+% Begin initialization code - DO NOT EDIT
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @f_export2csvGUI_OpeningFcn, ...
+ 'gui_OutputFcn', @f_export2csvGUI_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+% End initialization code - DO NOT EDIT
+
+%--------------------------------------------------------------------------
+function f_export2csvGUI_OpeningFcn(hObject, eventdata, handles, varargin)
+
+% Choose default command line output for f_export2csvGUI
+handles.output = [];
+try
+ ERP = varargin{1};
+catch
+ ERP.nbin =1;
+ ERP.nchan = 1;
+ ERP.chanlocs(1).labels = 'None';
+ ERP.bindescr{1} = 'None';
+ ERP.bindata = zeros(1,10,1);
+end
+handles.ERP = ERP;
+
+try
+ def = varargin{2};
+catch
+ def = {1, 1, 1, 3, ''};
+end
+
+
+% try
+% binArray = varargin{3};
+% chanArray = varargin{4};
+%
+% catch
+% binArray = 1;
+% chanArray = 1;
+% end
+
+istime = def{1};
+islabeled = def{2};
+transpa = def{3};
+prec = def{4};
+filename = def{5};
+
+% version = geterplabversion;
+set(handles.gui_chassis,'Name', ['EStudio ' '2022.1' ' - Export spectrum for selected ERPset as ".csv"'])
+
+[pathx, erpfilename, ext] = fileparts(filename);
+ERPFileName = char(strcat(erpfilename,'.csv'));
+set(handles.edit_saveas, 'String', fullfile(pathx,ERPFileName) )
+% set(handles.edit_bins, 'String', vect2colon(binArray, 'Delimiter', 'off'))
+% set(handles.popupmenu_tunits,'String',{'seconds';'milliseconds'})
+% set(handles.popupmenu_tunits,'Value', tunitx)
+set(handles.popupmenu_precision,'String', num2str([1:10]'))
+set(handles.popupmenu_precision,'Value', prec)
+set(handles.checkbox_time,'Value', istime)
+set(handles.checkbox_elabels,'Value', islabeled)
+set(handles.radiobutton_pr_ec,'Value', prec)
+
+if transpa==0
+ set(handles.radiobutton_pr_ec,'Value', 1)
+ set(handles.radiobutton_er_pc,'Value', 0)
+else
+ set(handles.radiobutton_pr_ec,'Value', 0)
+ set(handles.radiobutton_er_pc,'Value', 1)
+end
+
+
+% listb = {''};
+% nbin = ERP.nbin; % Total number of bins
+% try
+% for b=1:nbin
+% listb{b}= ['BIN' num2str(b) ' = ' ERP.bindescr{b} ];
+% end
+% catch
+% listb = '';
+% end
+%
+% handles.listb = listb;
+% handles.indxlistb = binArray;
+
+
+
+
+% nchan = ERP.nchan; % Total number of channels
+% if ~isfield(ERP.chanlocs,'labels')
+% for e=1:nchan
+% ERP.chanlocs(e).labels = ['Ch' num2str(e)];
+% end
+% end
+% listch = {''};
+% try
+% for ch =1:nchan
+% listch{ch} = [num2str(ch) ' = ' ERP.chanlocs(ch).labels ];
+% end
+% catch
+% listch = '';
+% end
+% handles.listch = listch;
+% handles.indxlistch = chanArray;
+%
+% set(handles.edit_custom_bin,'String', vect2colon(binArray, 'Delimiter', 'off'));
+% set(handles.edit_custom_chan,'String', vect2colon(chanArray, 'Delimiter', 'off'));
+
+
+% helpbutton
+
+%
+% Color GUI
+%
+% handles = painterplab(handles);
+
+%
+% Set font size
+%
+% handles = setfonterplab(handles);
+
+handles = painterplabstudio(handles);
+handles = setfonterplabestudio(handles);
+
+% Update handles structure
+guidata(hObject, handles);
+
+% help
+% helpbutton
+
+% UIWAIT makes f_export2csvGUI wait for user response (see UIRESUME)
+uiwait(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+function varargout = f_export2csvGUI_OutputFcn(hObject, eventdata, handles)
+
+% Get default command line output from handles structure
+varargout{1} = handles.output;
+
+% The figure can be deleted now
+delete(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+function checkbox_time_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function checkbox_elabels_Callback(hObject, eventdata, handles)
+values = handles.checkbox_elabels.Value;
+
+if values==1
+ handles.checkbox_elabels.Value=values;
+else
+ handles.checkbox_elabels.Value=values;
+end
+
+
+%--------------------------------------------------------------------------
+% function popupmenu_tunits_Callback(hObject, eventdata, handles)
+%
+% %--------------------------------------------------------------------------
+% function popupmenu_tunits_CreateFcn(hObject, eventdata, handles)
+%
+% if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+% set(hObject,'BackgroundColor','white');
+% end
+
+%--------------------------------------------------------------------------
+function popupmenu_precision_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function popupmenu_precision_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function pushbutton_cancel_Callback(hObject, eventdata, handles)
+
+handles.output = [];
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+% function pushbutton_help_Callback(hObject, eventdata, handles)
+% % doc pop_export2text
+% web 'https://github.com/lucklab/erplab/wiki/Exporting,-Editing,-and-Importing-EVENTLISTS' -browser
+
+
+%--------------------------------------------------------------------------
+function pushbutton_export_Callback(hObject, eventdata, handles)
+
+istime = get(handles.checkbox_time, 'Value');
+% timeu = get(handles.popupmenu_tunits, 'value');
+
+islabeled = get(handles.checkbox_elabels, 'Value');
+transpa = get(handles.radiobutton_er_pc, 'Value');
+precision = get(handles.popupmenu_precision, 'Value');
+filename = get(handles.edit_saveas, 'String');
+% bins = str2num(get(handles.edit_bins, 'string'));
+
+if isempty(filename)
+ msgboxText = 'You must enter a filename!';
+ title = 'EStudio: export2csv empty filename';
+ errorfound(msgboxText, title);
+ return
+end
+
+answer = {istime, islabeled, transpa, precision,filename};
+handles.output = answer;
+
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+% -------------------------------------------------------------------------
+function edit_saveas_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function edit_saveas_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function pushbutton_browse_Callback(hObject, eventdata, handles)
+
+%
+% Save OUTPUT file
+%
+prename = get(handles.edit_saveas,'String');
+[fname, pathname, filterindex] = uiputfile({'*.csv';'*.*'},'Save Output file as', prename);
+
+if isequal(fname,0)
+ disp('User selected Cancel')
+ return
+else
+
+ [px, fname2, ext] = fileparts(fname);
+
+ if strcmp(ext,'')
+
+ if filterindex==1 || filterindex==2
+ ext = '.csv';
+ else
+ ext = '.csv';
+ end
+
+ fname = [ fname2 ext];
+ end
+
+ set(handles.edit_saveas,'String', fullfile(pathname, fname));
+ % disp(['To save ERP, user selected ', fullfile(pathname, fname)])
+end
+
+
+
+%--------------------------------------------------------------------------
+function gui_chassis_CloseRequestFcn(hObject, eventdata, handles)
+if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting')
+ handles.output = [];
+ %Update handles structure
+ guidata(hObject, handles);
+ uiresume(handles.gui_chassis);
+else
+ % The GUI is no longer waiting, just close it
+ delete(handles.gui_chassis);
+end
+
+
+% --- Executes when uipanel1 is resized.
+function uipanel1_SizeChangedFcn(hObject, eventdata, handles)
+% hObject handle to uipanel1 (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+
+
+% function edit_custom_bin_Callback(hObject, eventdata, handles)
+%
+%
+%
+% % --- Executes during object creation, after setting all properties.
+% function edit_custom_bin_CreateFcn(hObject, eventdata, handles)
+% if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+% set(hObject,'BackgroundColor','white');
+% end
+
+
+% % --- Executes on button press in pushbutton_browse_bin.
+% function pushbutton_browse_bin_Callback(hObject, eventdata, handles)
+% % hObject handle to pushbutton_browse_bin (see GCBO)
+% % eventdata reserved - to be defined in a future version of MATLAB
+% % handles structure with handles and user data (see GUIDATA)
+%
+%
+%
+% function edit_custom_chan_Callback(hObject, eventdata, handles)
+%
+%
+%
+% % --- Executes during object creation, after setting all properties.
+% function edit_custom_chan_CreateFcn(hObject, eventdata, handles)
+% if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+% set(hObject,'BackgroundColor','white');
+% end
+%
+%
+% % --- Executes on button press in pushbutton_browse_chan.
+% function pushbutton_browse_chan_Callback(hObject, eventdata, handles)
+% % hObject handle to pushbutton_browse_chan (see GCBO)
+% % eventdata reserved - to be defined in a future version of MATLAB
+% % handles structure with handles and user data (see GUIDATA)
diff --git a/studio_functions/GUIs/ERP Tab/f_export2textGUI.fig b/studio_functions/GUIs/ERP Tab/f_export2textGUI.fig
new file mode 100755
index 00000000..41604a53
Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_export2textGUI.fig differ
diff --git a/studio_functions/GUIs/ERP Tab/f_export2textGUI.m b/studio_functions/GUIs/ERP Tab/f_export2textGUI.m
new file mode 100755
index 00000000..9b87e99e
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_export2textGUI.m
@@ -0,0 +1,438 @@
+%
+% Author: Javier Lopez-Calderon & Steven Luck & Guanghui ZHANG
+% Center for Mind and Brain
+% University of California, Davis,
+% Davis, CA
+% 2009 & 2022
+
+%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b
+%
+% Copyright (C) 2008 Javier Lopez-Calderon & Steven Luck,
+% Center for Mind and Brain, University of California, Davis,
+% javlopez@ucdavis.edu, sjluck@ucdavis.edu
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see .
+
+function varargout = f_export2textGUI(varargin)
+
+% Begin initialization code - DO NOT EDIT
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @f_export2textGUI_OpeningFcn, ...
+ 'gui_OutputFcn', @f_export2textGUI_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+% End initialization code - DO NOT EDIT
+
+%--------------------------------------------------------------------------
+function f_export2textGUI_OpeningFcn(hObject, eventdata, handles, varargin)
+
+% Choose default command line output for f_export2textGUI
+handles.output = [];
+try
+ ERP = varargin{1};
+catch
+ ERP.erpname = 'No erp was imported';
+ ERP.nbin =1;
+ ERP.nchan = 1;
+ ERP.chanlocs(1).labels = 'None';
+ ERP.bindescr{1} = 'None';
+ ERP.bindata = zeros(1,10,1);
+end
+
+try
+
+ binArray = varargin{3};
+ chanArray = varargin{4};
+catch
+ binArray = 1;
+ chanArray = 1;
+end
+
+try
+ def = varargin{2};
+catch
+ def = {1,1000, 1, 1, 4, 1, ''};
+end
+
+istime = def{1};
+tunit = def{2};
+islabeled = def{3};
+transpa = def{4};
+prec = def{5};
+filename = def{6};
+
+if tunit == 1
+ tunitx = 1;
+else
+ tunitx = 2;
+end
+
+%
+% Name & version
+%
+erplab_studio_default_values;
+version = erplabstudiover;
+
+set(handles.gui_chassis,'Name', ['EStudio ', version, ' - Export ERP GUI'])
+
+[pathx, erpfilename, ext] = fileparts(filename);
+ERPFileName = char(strcat(erpfilename,'.txt'));
+
+
+set(handles.edit_saveas, 'String', fullfile(pathx,ERPFileName))
+% set(handles.edit_bins, 'String', vect2colon(binArray, 'Delimiter', 'off'))
+set(handles.popupmenu_tunits,'String',{'seconds';'milliseconds'})
+set(handles.popupmenu_tunits,'Value', tunitx)
+set(handles.popupmenu_precision,'String', num2str([1:10]'))
+set(handles.popupmenu_precision,'Value', prec)
+set(handles.checkbox_time,'Value', istime)
+set(handles.checkbox_elabels,'Value', islabeled)
+set(handles.radiobutton_pr_ec,'Value', prec)
+
+if transpa==0
+ set(handles.radiobutton_pr_ec,'Value', 1)
+ set(handles.radiobutton_er_pc,'Value', 0)
+else
+ set(handles.radiobutton_pr_ec,'Value', 0)
+ set(handles.radiobutton_er_pc,'Value', 1)
+end
+
+%%----------------------Setting for bin and channels-----------------------
+listb = {''};
+nbin = ERP.nbin; % Total number of bins
+try
+ for b=1:nbin
+ listb{b}= ['BIN' num2str(b) ' = ' ERP.bindescr{b} ];
+ end
+catch
+ listb = '';
+end
+handles.listb = listb;
+handles.indxlistb = binArray;
+
+nchan = ERP.nchan; % Total number of channels
+if ~isfield(ERP.chanlocs,'labels')
+ for e=1:nchan
+ ERP.chanlocs(e).labels = ['Ch' num2str(e)];
+ end
+end
+listch = {''};
+try
+ for ch =1:nchan
+ listch{ch} = [num2str(ch) ' = ' ERP.chanlocs(ch).labels ];
+ end
+catch
+ listch = '';
+end
+handles.listch = listch;
+handles.indxlistch = chanArray;
+
+set(handles.edit3_custom_bin,'String', vect2colon(binArray, 'Delimiter', 'off'));
+set(handles.edit_custom_chan,'String', vect2colon(chanArray, 'Delimiter', 'off'));
+handles.ERP = ERP;
+
+
+% helpbutton
+
+%
+% Color GUI
+%
+handles = painterplabstudio(handles);
+%
+% %
+% % Set font size
+% %
+handles = setfonterplabestudio(handles);
+
+% Update handles structure
+guidata(hObject, handles);
+
+% help
+% helpbutton
+
+% UIWAIT makes f_export2textGUI wait for user response (see UIRESUME)
+uiwait(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+function varargout = f_export2textGUI_OutputFcn(hObject, eventdata, handles)
+
+% Get default command line output from handles structure
+varargout{1} = handles.output;
+
+% The figure can be deleted now
+delete(handles.gui_chassis);
+
+
+function edit3_custom_bin_Callback(hObject, eventdata, handles)
+
+BinString = str2num(handles.edit3_custom_bin.String);
+ERP = handles.ERP;
+% [chk, msgboxText] = chckbinandchan(ERP, BinString, []);
+[chk, msgboxText] = f_ERP_chckbinandchan(ERP, BinString, [],1);
+
+if chk(1)
+ title = 'EStudio: f_export2text GUI for bin input!';
+ errorfound(msgboxText, title);
+ return;
+end
+% --- Executes during object creation, after setting all properties.
+function edit3_custom_bin_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+% --- Executes on button press in pushbutton7_browse_bin.
+function pushbutton7_browse_bin_Callback(hObject, eventdata, handles)
+listb = handles.listb;
+indxlistb = handles.indxlistb;
+indxlistb = indxlistb(indxlistb<=length(listb));
+titlename = 'Select Bin(s)';
+
+if get(hObject, 'Value')
+ %set(handles.pushbutton_browsechan, 'Enable', 'off')
+ if ~isempty(listb)
+ bin = browsechanbinGUI(listb, indxlistb, titlename);
+ if ~isempty(bin)
+ set(handles.edit3_custom_bin, 'String', vect2colon(bin, 'Delimiter', 'off'));
+ handles.indxlistb = bin;
+ % Update handles structure
+ guidata(hObject, handles);
+ else
+ disp('User selected Cancel')
+ return
+ end
+ else
+ msgboxText = 'No bin information was found';
+ title = 'EStudio: f_export2text GUI for bin input';
+ errorfound(msgboxText, title);
+ return
+ end
+
+end
+
+
+function edit_custom_chan_Callback(hObject, eventdata, handles)
+chanString = str2num(handles.edit_custom_chan.String);
+ERP = handles.ERP;
+
+[chk, msgboxText] = f_ERP_chckbinandchan(ERP, [],chanString, 2);
+
+if chk(2)
+ title = 'EStudio: f_export2text GUI for channel input!';
+ errorfound(msgboxText, title);
+ return;
+end
+
+
+% --- Executes during object creation, after setting all properties.
+function edit_custom_chan_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+% --- Executes on button press in pushbutton8_browse_chan.
+function pushbutton8_browse_chan_Callback(hObject, eventdata, handles)
+
+listch = handles.listch;
+indxlistch = handles.indxlistch;
+indxlistch = indxlistch(indxlistch<=length(listch));
+titlename = 'Select Channel(s)';
+
+if get(hObject, 'Value')
+ if ~isempty(listch)
+ ch = browsechanbinGUI(listch, indxlistch, titlename);
+ if ~isempty(ch)
+ set(handles.edit_custom_chan, 'String', vect2colon(ch, 'Delimiter', 'off'));
+ handles.indxlistch = ch;
+ % Update handles structure
+ guidata(hObject, handles);
+ else
+ disp('User selected Cancel')
+ return
+ end
+ else
+ msgboxText = 'No channel information was found';
+ title = 'EStudio: f_export2text GUI for channel input';
+ errorfound(msgboxText, title);
+ return
+ end
+end
+%--------------------------------------------------------------------------
+function checkbox_time_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function checkbox_elabels_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function popupmenu_tunits_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function popupmenu_tunits_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function popupmenu_precision_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function popupmenu_precision_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function pushbutton_cancel_Callback(hObject, eventdata, handles)
+
+handles.output = [];
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+% function pushbutton_help_Callback(hObject, eventdata, handles)
+% % doc pop_export2text
+% web 'https://github.com/lucklab/erplab/wiki/Exporting,-Editing,-and-Importing-EVENTLISTS' -browser
+%--------------------------------------------------------------------------
+function pushbutton_export_Callback(hObject, eventdata, handles)
+
+istime = get(handles.checkbox_time, 'value');
+timeu = get(handles.popupmenu_tunits, 'value');
+
+if timeu == 1
+ timeunit = 1E0;
+else
+ timeunit = 1E-3;
+end
+
+islabeled = get(handles.checkbox_elabels, 'value');
+transpa = get(handles.radiobutton_er_pc, 'value');
+precision = get(handles.popupmenu_precision, 'value');
+filename = get(handles.edit_saveas, 'string');
+% bins = str2num(get(handles.edit_bins, 'string'));
+
+if isempty(filename)
+ msgboxText = 'You must enter a filename!';
+ title = 'EStudio: f_export2text GUI empty filename';
+ errorfound(msgboxText, title);
+ return
+end
+
+
+BinArray = str2num(handles.edit3_custom_bin.String);
+ERP = handles.ERP;
+[chk, msgboxText] = f_ERP_chckbinandchan(ERP, BinArray, [],1);
+
+if chk(1)
+ title = 'EStudio: f_export2text GUI for bin input!';
+ errorfound(msgboxText, title);
+ return;
+end
+
+
+ChanArray = str2num(handles.edit_custom_chan.String);
+[chk, msgboxText] = f_ERP_chckbinandchan(ERP, [],ChanArray, 2);
+
+if chk(2)
+ title = 'EStudio: f_export2text GUI for channel input!';
+ errorfound(msgboxText, title);
+ return;
+end
+
+ERP.bindata = ERP.bindata(ChanArray,:,BinArray);
+ERP.nbin = numel(BinArray);
+ERP.nchan = numel(ChanArray);
+ERP.chanlocs = ERP.chanlocs(ChanArray);
+for Numofbin = 1:numel(BinArray)
+ ERP.bindescr{Numofbin} = ERP.bindescr{BinArray(Numofbin)};
+end
+
+answer = {istime, timeunit, islabeled, transpa, precision,filename,ERP};
+handles.output = answer;
+
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+% -------------------------------------------------------------------------
+function edit_saveas_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function edit_saveas_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function pushbutton_browse_Callback(hObject, eventdata, handles)
+
+%
+% Save OUTPUT file
+%
+ERP = handles.ERP;
+prename = get(handles.edit_saveas,'String');
+[fname, pathname, filterindex] = uiputfile({'*.txt';'*.dat';'*.*'},['Save "', ERP.erpname,'" as'], prename);
+
+if isequal(fname,0)
+ disp('User selected Cancel')
+ return
+else
+
+ [px, fname2, ext] = fileparts(fname);
+
+ if strcmp(ext,'')
+
+ if filterindex==1 || filterindex==3
+ ext = '.txt';
+ else
+ ext = '.dat';
+ end
+
+ fname = [ fname2 ext];
+ end
+
+ set(handles.edit_saveas,'String', fullfile(pathname, fname));
+ disp(['To save ERP, user selected ', fullfile(pathname, fname)])
+end
+
+
+
+%--------------------------------------------------------------------------
+function gui_chassis_CloseRequestFcn(hObject, eventdata, handles)
+if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting')
+ handles.output = [];
+ %Update handles structure
+ guidata(hObject, handles);
+ uiresume(handles.gui_chassis);
+else
+ % The GUI is no longer waiting, just close it
+ delete(handles.gui_chassis);
+end
diff --git a/studio_functions/GUIs/ERP Tab/f_rerefassistantGUI.fig b/studio_functions/GUIs/ERP Tab/f_rerefassistantGUI.fig
new file mode 100755
index 00000000..88ebabfb
Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_rerefassistantGUI.fig differ
diff --git a/studio_functions/GUIs/ERP Tab/f_rerefassistantGUI.m b/studio_functions/GUIs/ERP Tab/f_rerefassistantGUI.m
new file mode 100755
index 00000000..ea236564
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_rerefassistantGUI.m
@@ -0,0 +1,383 @@
+function varargout = f_rerefassistantGUI(varargin)
+
+% Begin initialization code - DO NOT EDIT
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @f_rerefassistantGUI_OpeningFcn, ...
+ 'gui_OutputFcn', @f_rerefassistantGUI_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+% End initialization code - DO NOT EDIT
+
+
+%--------------------------------------------------------------------------
+function f_rerefassistantGUI_OpeningFcn(hObject, eventdata, handles, varargin)
+% Choose default command line output for f_rerefassistantGUI
+handles.output = hObject;
+try
+ handles.norichan = varargin{1};
+ listch = varargin{2};
+ listch = regexprep(listch, '.*=','','ignorecase');
+ listch = strtrim(listch);
+ handles.listch = listch;
+catch
+ handles.norichan = 1;
+ handles.listch = {};
+end
+
+%
+% Gui memory
+%
+rerefwizardGUI = erpworkingmemory('rerefwizardGUI');
+
+if isempty(rerefwizardGUI)
+ set(handles.edit_includechan,'String','');
+ set(handles.radiobutton_allchan,'Value',1)
+ set(handles.radiobutton_chan2inclu,'Value',0)
+ set(handles.radiobutton_chan2exclu,'Value',0)
+ set(handles.edit_excludechan,'String','');
+ set(handles.checkbox_addrefchan2mydata,'Value', 0); % 1 means yes
+ set(handles.checkbox_copynewlabel,'Value', 1);
+ set(handles.edit_equation,'String', '');
+ set(handles.checkbox_addunrefequ,'Value', 0);
+ set(handles.edit_includechan,'Enable','off')
+ set(handles.edit_excludechan,'Enable','off')
+ chArray = 1:handles.norichan;
+else
+ incexc = rerefwizardGUI.incexc ;
+ chArray = rerefwizardGUI.chArray;
+ addref = rerefwizardGUI.addref;
+ addlab = rerefwizardGUI.addlab;
+ equation = rerefwizardGUI.equation;
+ addunrefequ = rerefwizardGUI.addunrefequ;
+
+ if incexc
+ set(handles.radiobutton_chan2inclu,'Value',1)
+ set(handles.radiobutton_chan2exclu,'Value',0)
+ set(handles.edit_includechan,'String',vect2colon(chArray,'Delimiter','off'));
+ set(handles.edit_excludechan,'String','');
+ %set(handles.edit_includechan,'Enable','off')
+ set(handles.edit_excludechan,'Enable','off')
+ else
+ set(handles.radiobutton_chan2inclu,'Value',0)
+ set(handles.radiobutton_chan2exclu,'Value',1)
+ set(handles.edit_includechan,'String', '');
+ set(handles.edit_excludechan,'String', vect2colon(chArray,'Delimiter','off'));
+ set(handles.edit_includechan,'Enable','off')
+ %set(handles.edit_excludechan,'Enable','off')
+ end
+ set(handles.checkbox_addrefchan2mydata,'Value', addref); % 1 means yes
+ set(handles.checkbox_copynewlabel,'Value', addlab);
+ set(handles.edit_equation,'String', equation);
+ set(handles.checkbox_addunrefequ,'Value', addunrefequ);
+end
+
+handles.chArray = chArray;
+
+%
+% Name & version
+%
+erplab_studio_default_values;
+version = erplabstudiover;
+set(handles.gui_chassis,'Name', ['EStudio ' version ' - Rereference GUI'])
+
+%
+% Color GUI
+%
+handles = painterplabstudio(handles);
+
+%
+% Set font size
+%
+handles = setfonterplabestudio(handles);
+
+% Update handles structure
+guidata(hObject, handles);
+
+% help
+% helpbutton
+
+drawnow
+uiwait(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+function varargout = f_rerefassistantGUI_OutputFcn(hObject, eventdata, handles)
+
+varargout{1} = handles.output;
+
+% The figure can be deleted now
+delete(handles.gui_chassis);
+pause(0.1)
+
+%--------------------------------------------------------------------------
+function edit_equation_Callback(hObject, eventdata, handles)
+
+%
+% In case user writes "Ch_REF =", this will be erased.
+%
+formula = get(hObject,'String');
+formula = regexprep(formula, '.*s*=','','ignorecase');
+formula = lower(formula);
+set(hObject,'String', formula);
+
+%--------------------------------------------------------------------------
+function edit_equation_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function radiobutton_allchan_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+ set(handles.radiobutton_chan2inclu,'Value',0)
+ set(handles.radiobutton_chan2exclu,'Value',0)
+ set(handles.edit_includechan,'Enable','off')
+ set(handles.edit_excludechan,'Enable','off')
+else
+ set(handles.radiobutton_allchan,'Value',1)
+end
+
+%--------------------------------------------------------------------------
+function radiobutton_chan2inclu_Callback(hObject, eventdata, handles)
+
+if get(hObject,'Value')
+ set(handles.radiobutton_allchan,'Value',0)
+ set(handles.radiobutton_chan2exclu,'Value',0)
+ set(handles.edit_includechan,'Enable','on')
+ set(handles.edit_excludechan,'Enable','off')
+else
+ set(handles.radiobutton_chan2inclu,'Value',1)
+end
+
+%--------------------------------------------------------------------------
+function radiobutton_chan2exclu_Callback(hObject, eventdata, handles)
+
+if get(hObject,'Value')
+ set(handles.radiobutton_allchan,'Value',0)
+ set(handles.radiobutton_chan2inclu,'Value',0)
+ set(handles.edit_includechan,'Enable','off')
+ set(handles.edit_excludechan,'Enable','on')
+else
+ set(handles.radiobutton_chan2exclu,'Value',1)
+end
+
+%--------------------------------------------------------------------------
+function edit_includechan_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function edit_includechan_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function edit_excludechan_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function edit_excludechan_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function pushbutton_cancel_Callback(hObject, eventdata, handles)
+handles.output = [];
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+function pushbutton2_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function pushbutton_OK_Callback(hObject, eventdata, handles)
+
+addref = get(handles.checkbox_addrefchan2mydata,'Value'); % 1 means yes
+addlabel = get(handles.checkbox_copynewlabel,'Value');
+equation = get(handles.edit_equation,'String');
+addunrefequ = get(handles.checkbox_addunrefequ,'Value'); % 1 means yes
+
+if isempty(equation)
+ msgboxText = 'You have not written any expression yet!';
+ title = 'ERPLAB: rerefwizardGUI empty input';
+ errorfound(msgboxText, title);
+ return
+end
+
+abut = get(handles.radiobutton_allchan,'Value'); % all
+bbut = get(handles.radiobutton_chan2inclu,'Value'); % include
+cbut = get(handles.radiobutton_chan2exclu,'Value'); % exclude
+norichan = handles.norichan;
+
+if abut && ~bbut && ~cbut
+ incexc = 1; % include
+ chArray = 1:norichan;
+elseif ~abut && bbut && ~cbut
+ incexc = 1; % include
+ chArray = str2num(get(handles.edit_includechan,'String'));
+ if isempty(chArray)
+ msgboxText = 'You have not specified any channel yet!';
+ title = 'ERPLAB: rerefwizardGUI empty input';
+ errorfound(msgboxText, title);
+ return
+ end
+elseif ~abut && ~bbut && cbut
+ incexc = 0; % exclude
+ chArray = str2num(get(handles.edit_excludechan,'String'));
+else
+ fprintf('\nOops! something went wrong with this gui.\n')
+ return
+end
+% if get(handles.radiobutton_chan2inclu,'Value') && ~get(handles.radiobutton_chan2exclu,'Value')
+% incexc = 1; % include
+% chArray = str2num(get(handles.edit_includechan,'String'));
+% elseif ~get(handles.radiobutton_chan2inclu,'Value') && get(handles.radiobutton_chan2exclu,'Value')
+% incexc = 0; % exclude
+% chArray = str2num(get(handles.edit_excludechan,'String'));
+% else
+% return
+% end
+
+formulalist = createformulas(handles, incexc, chArray, addref, equation, addunrefequ);
+handles.output = {formulalist};
+
+%
+% memory for Gui
+%
+rerefwizardGUI.incexc = incexc;
+rerefwizardGUI.chArray = chArray;
+rerefwizardGUI.addref = addref;
+rerefwizardGUI.addlab = addlabel;
+rerefwizardGUI.equation = equation;
+rerefwizardGUI.addunrefequ = addunrefequ;
+
+erpworkingmemory('rerefwizardGUI', rerefwizardGUI);
+
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+function checkbox_addrefchan2mydata_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function formulalist = createformulas(handles, incexc, chArray, addref, equation, addunrefequ)
+
+%
+% Creates list of formulas for referencing
+%
+norichan = handles.norichan; % number of original channels
+listch = handles.listch;
+
+if incexc
+ chanArray = chArray;
+else
+ orichanArray = 1:norichan;
+ chanArray = orichanArray(~ismember_bc2(orichanArray, chArray));
+end
+% nchan = length(chanArray); % number of chs to reref
+
+unrefchanArray = 1:norichan;
+unrefchanArray = unrefchanArray(~ismember_bc2(unrefchanArray, chanArray));
+
+for i=1:norichan
+ if get(handles.checkbox_copynewlabel,'Value')
+ try
+ newlabel = listch{i};
+ catch
+ newlabel = 'undefined';
+ end
+ if ismember_bc2(i, unrefchanArray) && addunrefequ
+ flist{i} = sprintf('ch%g = ch%g Label %s', i, i, newlabel);
+ elseif ismember_bc2(i, chanArray)
+ flist{i} = sprintf('ch%g = ch%g - ( %s ) Label %s', i, i, equation, newlabel) ;
+ end
+ else
+ if ismember_bc2(i, unrefchanArray) && addunrefequ
+ flist{i} = sprintf('ch%g = ch%g', i, i) ;
+ elseif ismember_bc2(i, chanArray)
+ flist{i} = sprintf('ch%g = ch%g - ( %s )', i, i, equation) ;
+ end
+ end
+end
+flist = flist(~cellfun(@isempty, flist));
+
+% for i=1:nchan
+% if get(handles.checkbox_copynewlabel,'Value')
+% try
+% newlabel = listch{chanArray(i)};
+% catch
+% newlabel = 'undefined';
+% end
+% flist{i} = sprintf('ch%g = ch%g - ( %s ) Label %s', chanArray(i), chanArray(i), equation, newlabel) ;
+% else
+% flist{i} = sprintf('ch%g = ch%g - ( %s )', chanArray(i), chanArray(i), equation) ;
+% end
+% end
+%
+%
+%
+%
+% if addunrefequ
+% unrefchanArray = 1:norichan;
+% unrefchanArray = unrefchanArray(~ismember_bc2(unrefchanArray, chanArray));
+% unchan = length(unrefchanArray);
+% for i=1:unchan
+% if get(handles.checkbox_copynewlabel,'Value')
+% try
+% newlabel = listch{unrefchanArray(i)};
+% catch
+% newlabel = 'undefined';
+% end
+% flist{i+nchan} = sprintf('ch%g = ch%g Label %s', unrefchanArray(i), unrefchanArray(i), newlabel) ;
+% else
+% flist{i+nchan} = sprintf('ch%g = ch%g', unrefchanArray(i), unrefchanArray(i)) ;
+% end
+% end
+% end
+
+if addref
+ flist{end+1} = sprintf('ch%g = %s Label New Ref', norichan+1, equation) ;
+end
+formulalist = char(flist);
+return
+
+%--------------------------------------------------------------------------
+function pushbutton_avgref_Callback(hObject, eventdata, handles)
+chArray = handles.chArray;
+set(handles.edit_equation, 'String','')
+avgformula = sprintf('avgchan(%s)', vect2colon(chArray, 'Delimiter', 'off'));
+set(handles.edit_equation, 'String', avgformula)
+
+%--------------------------------------------------------------------------
+function checkbox_copynewlabel_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function checkbox_addunrefequ_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function gui_chassis_CloseRequestFcn(hObject, eventdata, handles)
+
+if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting')
+ %The GUI is still in UIWAIT, us UIRESUME
+ handles.output = '';
+ %Update handles structure
+ guidata(hObject, handles);
+ uiresume(handles.gui_chassis);
+else
+ % The GUI is no longer waiting, just close it
+ delete(handles.gui_chassis);
+end
diff --git a/studio_functions/GUIs/ERP Tab/f_scalplotadvanceGUI.fig b/studio_functions/GUIs/ERP Tab/f_scalplotadvanceGUI.fig
new file mode 100755
index 00000000..035469a4
Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_scalplotadvanceGUI.fig differ
diff --git a/studio_functions/GUIs/ERP Tab/f_scalplotadvanceGUI.m b/studio_functions/GUIs/ERP Tab/f_scalplotadvanceGUI.m
new file mode 100755
index 00000000..ce7a4c5f
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/f_scalplotadvanceGUI.m
@@ -0,0 +1,738 @@
+% Author: Javier Lopez-Calderon % Sam London
+% Center for Mind and Brain
+% University of California, Davis,
+% Davis, CA
+% 2009
+
+%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b
+%
+% EStudio Toolbox
+% Copyright © 2007 The Regents of the University of California
+% Created by Javier Lopez-Calderon and Steven Luck
+% Center for Mind and Brain, University of California, Davis,
+% javlopez@ucdavis.edu, sjluck@ucdavis.edu
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see .
+
+function varargout = f_scalplotadvanceGUI(varargin)
+
+% Begin initialization code - DO NOT EDIT
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @f_scalplotadvanceGUI_OpeningFcn, ...
+ 'gui_OutputFcn', @f_scalplotadvanceGUI_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+% End initialization code - DO NOT EDIT
+
+%--------------------------------------------------------------------------
+function f_scalplotadvanceGUI_OpeningFcn(hObject, eventdata, handles, varargin)
+
+% Choose default command line output for f_scalplotadvanceGU
+try
+ pscale_legend = varargin{1};
+catch
+ %%{binnum, bindesc, type, latency, electrodes, elestyle, elec3D, ismaxim, 2Dvalue}
+ pscale_legend = {1,1,1,1,0,'on','off',0,1};
+end
+
+binnum = pscale_legend{1};
+bindesc = pscale_legend{2};
+type = pscale_legend{3};
+latency = pscale_legend{4};
+electrodes = pscale_legend{5};
+elestyle = pscale_legend{6};
+elec3D = pscale_legend{7};
+% colorbar = val(6);
+ismaxim = pscale_legend{8};
+is2Dmap = pscale_legend{9};
+
+handles.is2Dmap = is2Dmap;
+% Name & version
+%
+erplab_studio_default_values;
+version = erplabstudiover;
+set(handles.gui_chassis,'Name', ['EStudio ' version ' - SCALP MAPPING ADVANCED GUI'])
+
+
+
+set(handles.checkbox_binnumber,'Value', binnum)
+set(handles.checkbox_bindescription,'Value', bindesc)
+set(handles.checkbox_tvalue,'Value', type)
+set(handles.checkbox_latency,'Value', latency)
+
+if electrodes && ~strcmpi(elec3D, 'on')
+ switch elestyle
+ case 'on'
+ set(handles.checkbox_electrodes,'Value', 1)
+ set(handles.radiobutton_excludepoints,'Value', 0)
+ set(handles.radiobutton_showenumber,'Value', 0)
+ set(handles.radiobutton_showelabel,'Value', 0)
+ set(handles.radiobutton_excludepoints,'Enable', 'off')
+ case 'off'
+ set(handles.checkbox_electrodes,'Value', 0)
+ set(handles.radiobutton_excludepoints,'Value', 0)
+ set(handles.radiobutton_showenumber,'Value', 0)
+ set(handles.radiobutton_showelabel,'Value', 0)
+
+ set(handles.radiobutton_excludepoints,'Enable', 'off')
+ set(handles.radiobutton_showenumber,'Enable', 'off')
+ set(handles.radiobutton_showelabel,'Enable', 'off')
+ case 'numbers'
+ set(handles.checkbox_electrodes,'Value', 1)
+ set(handles.radiobutton_excludepoints,'Value', 1)
+ set(handles.radiobutton_showenumber,'Value', 1)
+ set(handles.radiobutton_showelabel,'Value', 0)
+ case 'labels'
+ set(handles.checkbox_electrodes,'Value', 1)
+ set(handles.radiobutton_excludepoints,'Value', 1)
+ set(handles.radiobutton_showenumber,'Value', 0)
+ set(handles.radiobutton_showelabel,'Value', 1)
+ case 'ptsnumbers'
+ set(handles.checkbox_electrodes,'Value', 1)
+ set(handles.radiobutton_excludepoints,'Value', 0)
+ set(handles.radiobutton_showenumber,'Value', 1)
+ set(handles.radiobutton_showelabel,'Value', 0)
+ case 'ptslabels'
+ set(handles.checkbox_electrodes,'Value', 1)
+ set(handles.radiobutton_excludepoints,'Value', 0)
+ set(handles.radiobutton_showenumber,'Value', 0)
+ set(handles.radiobutton_showelabel,'Value', 1)
+ otherwise
+ set(handles.checkbox_electrodes,'Value', 0)
+ set(handles.radiobutton_excludepoints,'Value', 0)
+ set(handles.radiobutton_showenumber,'Value', 0)
+ set(handles.radiobutton_showelabel,'Value', 0)
+
+ set(handles.radiobutton_excludepoints,'Enable', 'off')
+ set(handles.radiobutton_showenumber,'Enable', 'off')
+ set(handles.radiobutton_showelabel,'Enable', 'off')
+ end
+
+ % if ~elecexcpnts && ~elecshownum && ~elecshowlab
+ % %'on','off','labels','numbers','ptslabels','ptsnumbers'
+ % elestyle = 'on';
+ % elseif ~elecexcpnts && elecshownum && ~elecshowlab
+ % %'on','off','labels','numbers','ptslabels','ptsnumbers'
+ % elestyle = 'numbers';
+ % elseif ~elecexcpnts && ~elecshownum && elecshowlab
+ % %'on','off','labels','numbers','ptslabels','ptsnumbers'
+ % elestyle = 'labels';
+ % elseif elecexcpnts && elecshownum && ~elecshowlab
+ % %'on','off','labels','numbers','ptslabels','ptsnumbers'
+ % elestyle = 'ptsnumbers';
+ % elseif elecexcpnts && ~elecshownum && elecshowlab
+ % %'on','off','labels','numbers','ptslabels','ptsnumbers'
+ % elestyle = 'ptslabels';
+ % else
+ % return
+ % end
+else
+ %elestyle = 'off';
+ set(handles.checkbox_electrodes,'Value', 0);
+ set(handles.radiobutton_excludepoints,'Enable', 'off','Value',0)
+ set(handles.radiobutton_showenumber,'Enable', 'off','Value',0);
+ set(handles.radiobutton_showelabel,'Enable', 'off','Value',0);
+ set(handles.checkbox_3Delec,'Value', 0,'Enable', 'off');
+end
+if is2Dmap
+ set(handles.checkbox_3Delec,'Value', 0)
+ set(handles.checkbox_3Delec,'Enable', 'off')
+else
+ if strcmpi(elec3D, 'on')
+ set(handles.checkbox_3Delec,'Value', 1)
+ set(handles.checkbox_electrodes,'Value', 1)
+
+ set(handles.radiobutton_excludepoints,'Value', 0)
+ set(handles.radiobutton_showenumber,'Value', 0)
+ set(handles.radiobutton_showelabel,'Value', 0)
+
+ %set(handles.checkbox_electrodes,'Enable', 'off')
+ set(handles.radiobutton_excludepoints,'Enable', 'off')
+ set(handles.radiobutton_showenumber,'Enable', 'off')
+ set(handles.radiobutton_showelabel,'Enable', 'off')
+ end
+end
+
+set(handles.checkbox_maximize,'Value', ismaxim)
+%
+
+try
+ pagif_legend = varargin{2};
+catch
+ %%{binnum, bindesc, type, latency, electrodes, elestyle, elec3D, ismaxim, 2Dvalue}
+ pagif_legend = {0,[],'',[]};
+end
+
+agif = pagif_legend{1};
+FPS = pagif_legend{2};
+fnameagif = pagif_legend{3};
+latency =pagif_legend{4};
+handles.latency = latency;
+
+
+if agif>0
+ set(handles.checkbox_animation,'Value', 1)
+ set(handles.checkbox_adjust1frame,'Enable', 'on')
+ set(handles.edit_fps,'Enable', 'on')
+ set(handles.edit_fps,'String', num2str(FPS))
+ set(handles.edit_fname_animation,'Enable', 'on')
+ set(handles.edit_fname_animation,'String', fnameagif)
+ set(handles.pushbutton_browse_animation,'Enable', 'on')
+
+ if agif==2
+ set(handles.checkbox_adjust1frame,'Value', 1)
+ else
+ set(handles.checkbox_adjust1frame,'Value', 0)
+ end
+ set(handles.checkbox_adjust1frame,'Enable', 'on')
+else
+ set(handles.checkbox_animation,'Value', 0)
+ set(handles.checkbox_animation,'Value', 0)
+ set(handles.checkbox_adjust1frame,'Value', 0)
+ set(handles.checkbox_adjust1frame,'Enable', 'off')
+ set(handles.edit_fps,'Enable', 'off')
+ set(handles.edit_fname_animation,'Enable', 'off')
+ set(handles.pushbutton_browse_animation,'Enable', 'off')
+ set(handles.checkbox_adjust1frame,'Value', 0)
+ set(handles.checkbox_adjust1frame,'Enable', 'off')
+end
+
+
+% Color GUI
+%
+handles = painterplabstudio(handles);
+%
+% %
+% % Set font size
+% %
+handles = setfonterplabestudio(handles);
+
+% Update handles structure
+guidata(hObject, handles);
+
+% help
+% helpbutton
+
+% PDF button
+% pdfbutton
+
+% set all objects
+% setall(hObject, eventdata, handles)
+
+% UIWAIT makes geterpvaluesGUI wait for user response (see UIRESUME)
+uiwait(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+function varargout = f_scalplotadvanceGUI_OutputFcn(hObject, eventdata, handles)
+varargout{1} = handles.output;
+% varargout{2} = handles.ERP;
+
+% The figure can be deleted now
+delete(handles.gui_chassis);
+pause(0.1)
+
+
+%--------------------------------------------------------------------------
+function pushbutton_OK_Callback(hObject, eventdata, handles)
+% Animation
+%
+if get(handles.checkbox_animation, 'Value')
+ if get(handles.checkbox_adjust1frame, 'Value')
+ isagif = 2; % adjust first frame
+ else
+ isagif = 1;
+ end
+
+ FPS = str2num(get(handles.edit_fps, 'String'));
+ fnameagif = get(handles.edit_fname_animation, 'String');
+
+ if isempty(FPS) || FPS<1 || FPS>1000
+ msgboxText = 'Error: You must specify a scalar value between 1 and 1000 inclusive';
+ title = 'EStudio: f_scalplotadvanceGUI() error:';
+ errorfound(msgboxText, title);
+ return
+ end
+ if isempty(strtrim(fnameagif))
+ msgboxText = 'Error: You must specify a valid file name for your animated GIF';
+ title = 'EStudio: f_scalplotadvanceGUI() error:';
+ errorfound(msgboxText, title);
+ return
+ else
+ [pthxz, fnamez, ext] = fileparts(fnameagif);
+ if strcmp(ext,'')
+ ext = '.gif';
+ end
+ fnameagif = fullfile(pthxz,[ fnamez ext]);
+ end
+else
+ isagif = 0;
+ FPS = [];
+ fnameagif = '';
+end
+
+
+
+binnum = get(handles.checkbox_binnumber,'Value');
+bindesc = get(handles.checkbox_bindescription,'Value');
+type = get(handles.checkbox_tvalue,'Value');
+latency = get(handles.checkbox_latency,'Value');
+electrodes = get(handles.checkbox_electrodes,'Value');
+
+elecexcpnts = get(handles.radiobutton_excludepoints,'Value');
+elecshownum = get(handles.radiobutton_showenumber,'Value');
+elecshowlab = get(handles.radiobutton_showelabel,'Value');
+
+if electrodes
+ if ~elecexcpnts && ~elecshownum && ~elecshowlab
+ %'on','off','labels','numbers','ptslabels','ptsnumbers'
+ elestyle = 'on';
+ elseif ~elecexcpnts && elecshownum && ~elecshowlab
+ %'on','off','labels','numbers','ptslabels','ptsnumbers'
+ elestyle = 'ptsnumbers';
+ elseif ~elecexcpnts && ~elecshownum && elecshowlab
+ %'on','off','labels','numbers','ptslabels','ptsnumbers'
+ elestyle = 'ptslabels';
+ elseif elecexcpnts && elecshownum && ~elecshowlab
+ %'on','off','labels','numbers','ptslabels','ptsnumbers'
+ elestyle = 'numbers';
+ elseif elecexcpnts && ~elecshownum && elecshowlab
+ %'on','off','labels','numbers','ptslabels','ptsnumbers'
+ elestyle = 'labels';
+ else
+ return
+ end
+else
+ elestyle = 'off';
+end
+
+el3D = get(handles.checkbox_3Delec,'Value');
+if el3D
+ elec3D = 'on';
+else
+ elec3D = 'off';
+end
+
+% colorbar = get(handles.checkbox_cbar,'Value');
+ismaxim = get(handles.checkbox_maximize,'Value');
+
+is2Dmap=handles.is2Dmap;
+%%{binnum, bindesc, type, latency, electrodes, elestyle, elec3D, ismaxim, 2Dvalue}
+pscale_legend = {binnum, bindesc, type, latency, electrodes, elestyle, elec3D, ismaxim,is2Dmap};
+
+%%isagif; FPS;fnameagif
+pagif_legend = {isagif,FPS,'',fnameagif};
+
+
+handles.output = {pscale_legend,pagif_legend};
+
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+% end
+% end
+
+
+
+
+
+
+%--------------------------------------------------------------------------
+function edit_customblc_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+
+
+
+
+
+%--------------------------------------------------------------------------
+function edit_exchan_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function edit_exchan_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function popupmenu_exchan_Callback(hObject, eventdata, handles)
+numch = get(hObject, 'Value');
+nums = get(handles.edit_exchan, 'String');
+nums = [nums ' ' num2str(numch)];
+set(handles.edit_exchan, 'String', nums);
+
+%--------------------------------------------------------------------------
+function popupmenu_exchan_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function checkbox_animation_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+ set(handles.edit_fps,'Enable', 'on')
+ set(handles.edit_fname_animation,'Enable', 'on')
+ set(handles.pushbutton_browse_animation,'Enable', 'on')
+ set(handles.checkbox_adjust1frame,'Enable', 'on')
+else
+ set(handles.edit_fps,'Enable', 'off')
+ set(handles.edit_fname_animation,'Enable', 'off')
+ set(handles.pushbutton_browse_animation,'Enable', 'off')
+ set(handles.checkbox_adjust1frame,'Enable', 'off')
+end
+
+%--------------------------------------------------------------------------
+function edit_fname_animation_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function edit_fname_animation_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function pushbutton_browse_animation_Callback(hObject, eventdata, handles)
+
+%
+% Save GIF, mov, or mpg
+%
+prename = get(handles.edit_fname_animation,'String');
+%[blfilename, blpathname, filterindex] = uiputfile({'*.gif';'*.*'},'Save animation as',prename);
+
+[blfilename, blpathname, filterindex] = uiputfile( ...
+ {'*.gif','Animated GIF (*.gif)';
+ '*.mat', 'Matlab movie (*.mat)';...
+ '*.avi','AVI file (*.avi)'},...
+ 'Save animation as', prename);
+
+if isequal(blfilename,0)
+ disp('User selected Cancel')
+ return
+else
+ [px, fname, ext] = fileparts(blfilename);
+ if filterindex==1
+ ext = '.gif';
+ elseif filterindex==2
+ ext = '.mat';
+ elseif filterindex==3
+ ext = '.avi';
+ else
+ ext = '.gif';
+ end
+
+ fname = [ fname ext];
+
+ fullgifname = fullfile(blpathname, fname);
+ set(handles.edit_fname_animation,'String', fullgifname);
+ disp(['Animatation will be saved at ' fullgifname])
+end
+
+%--------------------------------------------------------------------------
+function edit_fps_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function edit_fps_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+% function checkbox_colorbar_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function pushbutton_ploterp_Callback(hObject, eventdata, handles)
+plotset = getplotset(hObject, eventdata, handles);
+if isempty(plotset.ptime)
+ return
+else
+ plotset.ptime.binArray = plotset.pscalp.binArray ;
+ plotset.ptime.blcorr = plotset.pscalp.baseline;
+ assignin('base','plotset', plotset);
+ handles.eplot = 1;
+
+ %Update handles structure
+ guidata(hObject, handles);
+ uiresume(handles.figure1);
+end
+
+
+
+
+%--------------------------------------------------------------------------
+function checkbox_adjust1frame_Callback(hObject, eventdata, handles)
+
+
+
+%--------------------------------------------------------------------------
+function popupmenu_orientation_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+
+%--------------------------------------------------------------------------
+function edit_customview_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+
+%--------------------------------------------------------------------------
+function popupmenu_measurement_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+
+
+%--------------------------------------------------------------------------
+function popupmenu_mapstyle_CreateFcn(hObject, eventdata, handles)
+
+% Hint: popupmenu controls usually have a white background on Windows.
+% See ISPC and COMPUTER.
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+
+%--------------------------------------------------------------------------
+function checkbox_realtime_Callback(hObject, eventdata, handles)
+if get(hObject, 'Value')
+ lat = handles.latency;
+ if isempty(lat)
+ msgboxText = 'You must specify a latency vector first.';
+ title = 'EStudio: f_scalplotadvancedGUI input';
+ errorfound(msgboxText, title);
+ return
+ end
+% lat = str2num(lat);
+ T = unique_bc2(diff(lat));
+ if isempty(T)
+ msgboxText = 'You must specify a latency vector first.';
+ title = 'EStudio: f_scalplotadvancedGUI input';
+ errorfound(msgboxText, title);
+ return
+ end
+ if length(T)>1
+ msgboxText = ['The latency vector does not have a fixed step to determine its periodicity.\n\n'...
+ 'You may use colon notation, e.g. start:step:end, to specify your latency vector.\n'...
+ 'This may work better to generate the time of each frame.'];
+ title = 'EStudio: f_scalplotadvancedGUI input';
+ errorfound(sprintf(msgboxText), title);
+ return
+ end
+ f = round(1/(T/1000));
+ set(handles.edit_fps, 'String', num2str(f));
+ set(handles.edit_fps,'Enable', 'off')
+else
+ set(handles.edit_fps,'Enable', 'on')
+end
+
+
+
+
+%--------------------------------------------------------------------------
+function pushbutton_cancel_Callback(hObject, eventdata, handles)
+% plotset = evalin('base', 'plotset');
+% plotset.pscalp = [];
+handles.output = {};
+
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+function gui_chassis_CloseRequestFcn(hObject, eventdata, handles)
+if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting')
+ %The GUI is still in UIWAIT, us UIRESUME
+% plotset = evalin('base', 'plotset');
+% plotset.pscalp = [];
+ handles.output = {};
+ %Update handles structure
+ guidata(hObject, handles);
+ uiresume(handles.gui_chassis);
+else
+ % The GUI is no longer waiting, just close it
+ delete(handles.gui_chassis);
+end
+
+
+% --- Executes on button press in checkbox_binnumber.
+function checkbox_binnumber_Callback(hObject, eventdata, handles)
+% hObject handle to checkbox_binnumber (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Hint: get(hObject,'Value') returns toggle state of checkbox_binnumber
+
+
+% --- Executes on button press in checkbox_bindescription.
+function checkbox_bindescription_Callback(hObject, eventdata, handles)
+% hObject handle to checkbox_bindescription (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Hint: get(hObject,'Value') returns toggle state of checkbox_bindescription
+
+
+% --- Executes on button press in checkbox_latency.
+function checkbox_latency_Callback(hObject, eventdata, handles)
+% hObject handle to checkbox_latency (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Hint: get(hObject,'Value') returns toggle state of checkbox_latency
+
+
+% --- Executes on button press in checkbox_tvalue.
+function checkbox_tvalue_Callback(hObject, eventdata, handles)
+% hObject handle to checkbox_tvalue (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Hint: get(hObject,'Value') returns toggle state of checkbox_tvalue
+
+
+% --- Executes on button press in checkbox_maximize.
+function checkbox_maximize_Callback(hObject, eventdata, handles)
+% hObject handle to checkbox_maximize (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Hint: get(hObject,'Value') returns toggle state of checkbox_maximize
+
+
+% --- Executes on button press in checkbox_electrodes.
+function checkbox_electrodes_Callback(hObject, eventdata, handles)
+
+is2Dmap = handles.is2Dmap;
+
+if get(hObject, 'value')
+ set(handles.radiobutton_excludepoints,'Enable', 'off')
+ set(handles.radiobutton_showenumber,'Enable', 'on')
+ set(handles.radiobutton_showelabel,'Enable', 'on')
+
+ set(handles.checkbox_3Delec,'Enable', 'on')
+else
+ set(handles.radiobutton_excludepoints,'Value', 0)
+ set(handles.radiobutton_showenumber,'Value', 0)
+ set(handles.radiobutton_showelabel,'Value', 0)
+ set(handles.checkbox_3Delec,'Value', 0)
+
+ set(handles.radiobutton_excludepoints,'Enable', 'off')
+ set(handles.radiobutton_showenumber,'Enable', 'off')
+ set(handles.radiobutton_showelabel,'Enable', 'off')
+ set(handles.checkbox_3Delec,'Enable', 'off')
+end
+
+
+
+
+% --- Executes on button press in radiobutton_excludepoints.
+function radiobutton_excludepoints_Callback(hObject, eventdata, handles)
+% if get(hObject, 'value')
+%
+% else
+%
+% end
+
+
+% --- Executes on button press in checkbox_3Delec.
+function checkbox_3Delec_Callback(hObject, eventdata, handles)
+if get(hObject, 'Value')
+ %set(handles.checkbox_electrodes,'Value', 0)
+ set(handles.radiobutton_excludepoints,'Value', 0)
+ set(handles.radiobutton_showenumber,'Value', 0)
+ set(handles.radiobutton_showelabel,'Value', 0)
+
+ %set(handles.checkbox_electrodes,'Enable', 'off')
+ set(handles.radiobutton_excludepoints,'Enable', 'off')
+ set(handles.radiobutton_showenumber,'Enable', 'off')
+ set(handles.radiobutton_showelabel,'Enable', 'off')
+else
+ %set(handles.radiobutton_excludepoints,'Value', 0)
+ %set(handles.radiobutton_showenumber,'Value', 0)
+ %set(handles.radiobutton_showelabel,'Value', 0)
+
+ %set(handles.checkbox_electrodes,'Enable', 'off')
+ set(handles.radiobutton_excludepoints,'Enable', 'off')
+ set(handles.radiobutton_showenumber,'Enable', 'on')
+ set(handles.radiobutton_showelabel,'Enable', 'on')
+end
+
+
+% --- Executes on button press in radiobutton_showelabel.
+function radiobutton_showelabel_Callback(hObject, eventdata, handles)
+
+if get(hObject, 'value')
+ set(handles.radiobutton_showenumber,'Value', 0)
+ set(handles.radiobutton_excludepoints,'Enable', 'on')
+else
+ %set(handles.radiobutton_showelabel,'Value', 1)
+ if ~get(handles.radiobutton_showelabel,'Value')
+ set(handles.radiobutton_excludepoints,'Value', 0)
+ set(handles.radiobutton_excludepoints,'Enable', 'off')
+ end
+end
+
+
+% --- Executes on button press in radiobutton_showenumber.
+function radiobutton_showenumber_Callback(hObject, eventdata, handles)
+if get(hObject, 'value')
+ set(handles.radiobutton_showelabel,'Value', 0)
+ set(handles.radiobutton_excludepoints,'Enable', 'on')
+else
+ %set(handles.radiobutton_showenumber,'Value', 1
+ if ~get(handles.radiobutton_showenumber,'Value')
+ set(handles.radiobutton_excludepoints,'Value', 0)
+ set(handles.radiobutton_excludepoints,'Enable', 'off')
+ end
+end
+
+
+
+% --- Executes during object creation, after setting all properties.
+function checkbox_maximize_CreateFcn(hObject, eventdata, handles)
+% hObject handle to checkbox_maximize (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+
+
+% --- Executes during object creation, after setting all properties.
+function checkbox_electrodes_CreateFcn(hObject, eventdata, handles)
+% hObject handle to checkbox_maximize (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
diff --git a/studio_functions/GUIs/ERP Tab/geterpvaluesparasGUI2.fig b/studio_functions/GUIs/ERP Tab/geterpvaluesparasGUI2.fig
new file mode 100755
index 00000000..cde446d6
Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/geterpvaluesparasGUI2.fig differ
diff --git a/studio_functions/GUIs/ERP Tab/geterpvaluesparasGUI2.m b/studio_functions/GUIs/ERP Tab/geterpvaluesparasGUI2.m
new file mode 100755
index 00000000..894b172c
--- /dev/null
+++ b/studio_functions/GUIs/ERP Tab/geterpvaluesparasGUI2.m
@@ -0,0 +1,1212 @@
+%
+% Author: Javier Lopez-Calderon & Steven Luck
+% Center for Mind and Brain
+% University of California, Davis,
+% Davis, CA
+% 2009
+
+%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b
+%
+% ERPLAB Toolbox
+% Copyright © 2007 The Regents of the University of California
+% Created by Javier Lopez-Calderon and Steven Luck
+% Center for Mind and Brain, University of California, Davis,
+% javlopez@ucdavis.edu, sjluck@ucdavis.edu
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see .
+
+function varargout = geterpvaluesparasGUI2(varargin)
+
+% Begin initialization code - DO NOT EDIT
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @geterpvaluesparasGUI2_OpeningFcn, ...
+ 'gui_OutputFcn', @geterpvaluesparasGUI2_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+% End initialization code - DO NOT EDIT
+
+%--------------------------------------------------------------------------
+function geterpvaluesparasGUI2_OpeningFcn(hObject, eventdata, handles, varargin)
+% Choose default command line output for geterpvaluesparasGUI2
+handles.output = [];
+handles.indxline = 1;
+handles.listname = [];
+handles.listb = '';
+handles.indxlistb = [];
+handles.listch = '';
+handles.indxlistch = [];
+handles.owfp = 0; % over write file permission. 1:allowed; 0:do not overwrite w/o asking.
+handles.rise = 1;
+
+try
+ def = varargin{1};
+ handles.def = def;
+catch
+ def = {'fpeaklat', 3, 0, 1, 3, 0, 0.5, 0, 0, 1, 1, 1};
+ handles.def = def;
+end
+
+
+try
+ ERP = varargin{2};
+ if isstruct(ERP)
+ handles.xmin = ERP.xmin;
+ handles.xmax = ERP.xmax;
+ handles.srate = ERP.srate;
+
+ else
+ handles.xmin = [];
+ handles.xmax = [];
+ handles.srate = [];
+
+ end
+ datatype =ERP.datatype;
+catch
+ ERP = [];
+ handles.xmin = [];
+ handles.xmax = [];
+ handles.srate = [];
+ handles.nsets = [];
+ datatype = 'ERP';
+end
+
+handles.datatype = datatype;
+if strcmpi(datatype, 'ERP')
+ kktime = 1000;
+else
+ return;
+end
+handles.kktime = kktime;
+
+
+handles.frac = [];
+handles.intfactor = [];
+
+%
+% Color GUI
+handles = painterplabstudio(handles);
+%
+% %
+% % Set font size
+% %
+handles = setfonterplabestudio(handles);
+
+% Update handles structure
+guidata(hObject, handles);
+
+setall(hObject, eventdata, handles)
+
+% help
+% helpbutton
+
+% viewer
+% viewerbutton
+
+%
+% Set Measurement menu
+%
+% set(handles.listbox_erpnames, 'Value',1)
+% set(handles.popupmenu_measurement, 'Backgroundcolor',[1 1 0.8])
+% set(handles.popupmenu_pol_amp, 'Backgroundcolor',[1 1 0.8])
+% set(handles.popupmenu_samp_amp, 'Backgroundcolor',[1 1 0.8])
+% set(handles.popupmenu_locpeakreplacement, 'Backgroundcolor',[1 1 0.8])
+% set(handles.popupmenu_fracreplacement, 'Backgroundcolor',[1 1 0.8])
+% set(handles.popupmenu_precision, 'Backgroundcolor',[1 1 0.8])
+%set(handles.text_fraca,'String', {''});
+%set(handles.text_fa3,'String',{''});
+drawnow
+
+% UIWAIT makes geterpvaluesparasGUI2 wait for user response (see UIRESUME)
+uiwait(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+function varargout = geterpvaluesparasGUI2_OutputFcn(hObject, eventdata, handles)
+varargout{1} = handles.output;
+% The figure can be deleted now
+delete(handles.gui_chassis);
+pause(0.1)
+
+%--------------------------------------------------------------------------
+function menupeakoff(hObject, eventdata, handles)
+set(handles.popupmenu_pol_amp, 'Enable', 'off')
+set(handles.text_fa1, 'Enable', 'off')
+set(handles.popupmenu_samp_amp, 'Enable', 'off')
+set(handles.text_samp, 'Enable', 'off')
+set(handles.text12, 'Enable', 'off')
+set(handles.popupmenu_locpeakreplacement, 'Enable', 'off')
+set(handles.text_fa1, 'Enable', 'off')
+set(handles.text_fa2, 'Enable', 'off')
+set(handles.text_fa3, 'Enable', 'off')
+set(handles.text_fa4, 'Enable', 'off')
+
+%--------------------------------------------------------------------------
+function menupeakon(hObject, eventdata, handles)
+set(handles.popupmenu_pol_amp, 'Enable', 'off')
+set(handles.text_fa1, 'Enable', 'on')
+set(handles.popupmenu_samp_amp, 'Enable', 'on')
+set(handles.text_samp, 'Enable', 'on')
+set(handles.text12, 'Enable', 'on')
+set(handles.popupmenu_locpeakreplacement, 'Enable', 'on')
+set(handles.text_fa1, 'Enable', 'on')
+set(handles.text_fa2, 'Enable', 'on')
+
+
+
+%--------------------------------------------------------------------------
+function menufareaoff(hObject, eventdata, handles)
+set(handles.text_fraca,'Enable','off')
+set(handles.popupmenu_fraca,'String', {''})
+set(handles.popupmenu_fraca,'Enable','off')
+set(handles.text_punit,'Enable','off')
+set(handles.popupmenu_fracreplacement,'Enable','off')
+set(handles.text19, 'Enable', 'off')
+set(handles.text_fa3, 'Enable', 'off')
+set(handles.text_fa3,'String',{''});
+set(handles.text_fa4, 'Enable', 'off')
+set(handles.popupmenu_fraca, 'Enable', 'off')
+set(handles.popupmenu_rise, 'Enable', 'off')
+set(handles.text_fraca,'String', {''});
+
+%--------------------------------------------------------------------------
+function menufareaon(hObject, eventdata, handles)
+set(handles.text_fraca,'Enable','on')
+set(handles.text_punit,'Enable','on')
+set(handles.popupmenu_fraca,'Enable','on')
+set(handles.popupmenu_fracreplacement,'Enable','on')
+set(handles.text19, 'Enable', 'on')
+set(handles.text_fa3, 'Enable', 'on')
+set(handles.text_fa3,'String',{'Measure'});
+set(handles.text_fa4, 'Enable', 'on')
+set(handles.popupmenu_fraca, 'Enable', 'on')
+set(handles.popupmenu_rise, 'Enable', 'on')
+
+fracarray = 0:100;
+set(handles.popupmenu_fraca,'String', cellstr(num2str(fracarray')))
+frac = handles.frac;
+if isempty(frac)
+ frac = 0.50;
+end
+fracpos = round(frac*100)+1;
+set(handles.popupmenu_fraca,'Value', fracpos)
+
+set(handles.text19, 'Enable', 'on')
+
+%--------------------------------------------------------------------------
+function pushbutton_cancel_Callback(hObject, eventdata, handles)
+handles.output = [];
+% Update handles structure
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+%--------------------------------------------------------------------------
+function pushbutton_run_Callback(hObject, eventdata, handles)
+datatype = handles.datatype;
+kktime = handles.kktime;
+if kktime==1 % sec or Hz
+ TimeOp = 0;
+else % ms
+ TimeOp = 1;
+end
+
+xmin = handles.xmin;
+xmax = handles.xmax;
+
+srate = handles.srate;
+
+
+% Send to workspace
+%
+send2ws = get(handles.checkbox_send2ws, 'Value'); % 0:no; 1:yes
+owfp = handles.owfp; % over write file permission
+appendfile = 0;
+
+
+% if ~strcmp(chanArraystr, '') && ~isempty(chanArraystr) && ~strcmp(latestr, '') && ~isempty(latestr) && ~strcmp(binArraystr, '') && ~isempty(binArraystr)
+% binArray = str2num(binArraystr);
+% chanArray = str2num(chanArraystr);
+% late = str2num(latestr);
+% nlate = length(late);
+%
+
+
+polpeak = [];
+sampeak = [];
+% coi = 0; % ignore overlapped components
+locpeakrep = 0;
+frac = [];
+fracmearep = 0;
+measure_option = get(handles.popupmenu_measurement, 'Value');
+areatype = get(handles.popupmenu_areatype,'Value'); % 1=total ; 2=pos; 3=neg
+
+
+
+switch measure_option
+ case 1 % instabl
+ % if nlate~=1
+ % if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz
+ % msgboxText = 'You must define only one frequency';
+ % else
+ % msgboxText = 'You must define only one latency';
+ % end
+ % title = 'ERPLAB: measurement window';
+ % errorfound(sprintf(msgboxText), title);
+ % return
+ % end
+ moption = 'instabl';
+ fprintf('\nInstantaneous amplitude measurement in progress...\n');
+ case 2 % meanbl
+ % if nlate~=2
+ % if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz
+ % msgboxText = 'You must define two frequencies';
+ % else
+ % msgboxText = 'You must define two latencies';
+ % end
+ % title = 'ERPLAB: measurement window';
+ % errorfound(sprintf(msgboxText), title);
+ % return
+ % end
+ moption = 'meanbl';
+ fprintf('\nMean amplitude measurement in progress...\n');
+ case 3 % peakampbl
+ % if nlate~=2
+ % if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz
+ % msgboxText = 'You must define two frequencies';
+ % else
+ % msgboxText = 'You must define two latencies';
+ % end
+ % title = 'ERPLAB: measurement window';
+ % errorfound(sprintf(msgboxText), title);
+ % return
+ % end
+ moption = 'peakampbl';
+ polpeak = 2-get(handles.popupmenu_pol_amp,'Value');
+ sampeak = get(handles.popupmenu_samp_amp,'Value') - 1;
+ locpeakrep = 2-get(handles.popupmenu_locpeakreplacement,'Value');
+
+ % cc1 = late(1)-sample2time(TimeOp, sampeak, srate) < xmin*kktime;
+ % ccdiff = abs((late(1)-sample2time(TimeOp, sampeak, srate)) - xmin*kktime);
+ % cc2 = time2sample(TimeOp, ccdiff, srate)>2;
+ % cc3 = late(2)+sample2time(TimeOp, sampeak, srate)>xmax*kktime;
+ % ccdiff = abs((late(2)+sample2time(TimeOp, sampeak, srate)) - xmax*kktime);
+ % cc4 = time2sample(TimeOp, ccdiff, srate)>2;
+
+ % if (cc1 && cc2) || (cc3 && cc4)
+ % msgboxText = msgboxText4peak;
+ % title = 'ERPLAB: measurement window';
+ % errorfound(sprintf(msgboxText,sampeak, sampeak, sampeak, xmin*kktime, xmax*kktime, xmin*kktime+sample2time(TimeOp, sampeak,srate), xmax*kktime-sample2time(TimeOp, sampeak,srate)), title);
+ % return
+ % end
+ fprintf('\nLocal peak measurement in progress...\n');
+ case 4 % peaklatbl
+ % if nlate~=2
+ % if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz
+ % msgboxText = 'You must define two frequencies';
+ % else
+ % msgboxText = 'You must define two latencies';
+ % end
+ % title = 'ERPLAB: measurement window';
+ % errorfound(sprintf(msgboxText), title);
+ % return
+ % end
+ moption = 'peaklatbl';
+ polpeak = 2-get(handles.popupmenu_pol_amp,'Value');
+ sampeak = get(handles.popupmenu_samp_amp,'Value') - 1;
+ locpeakrep = 2-get(handles.popupmenu_locpeakreplacement,'Value');
+
+ % cc1 = late(1)-sample2time(TimeOp, sampeak, srate) < xmin*kktime;
+ % ccdiff = abs((late(1)-sample2time(TimeOp, sampeak, srate)) - xmin*kktime);
+ % cc2 = time2sample(TimeOp, ccdiff, srate)>2;
+ % cc3 = late(2)+sample2time(TimeOp, sampeak, srate)>xmax*kktime;
+ % ccdiff = abs((late(2)+sample2time(TimeOp, sampeak, srate)) - xmax*kktime);
+ % cc4 = time2sample(TimeOp, ccdiff, srate)>2;
+
+ % if (cc1 && cc2) || (cc3 && cc4)
+ % msgboxText = msgboxText4peak;
+ % title = 'ERPLAB: measurement window';
+ % errorfound(sprintf(msgboxText,sampeak, sampeak, sampeak, xmin*kktime, xmax*kktime, xmin*kktime+sample2time(TimeOp, sampeak,srate), xmax*kktime-sample2time(TimeOp, sampeak,srate)), kktime);
+ % return
+ % end
+ if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz
+ fprintf('\nLocal peak frequency measurement in progress...\n');
+ else
+ fprintf('\nLocal peak latency measurement in progress...\n');
+ end
+ case 5 % fpeaklat
+ % if nlate~=2
+ % if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz
+ % msgboxText = 'You must define two frequencies';
+ % else
+ % msgboxText = 'You must define two latencies';
+ % end
+ % title = 'ERPLAB: measurement window';
+ % errorfound(sprintf(msgboxText), title);
+ % return
+ % end
+ set(handles.text_fraca,'String', 'Fractional Peak')
+ moption = 'fpeaklat';
+ frac = (get(handles.popupmenu_fraca,'Value') - 1)/100; % 0 to 1
+ polpeak = 2-get(handles.popupmenu_pol_amp,'Value');
+ sampeak = get(handles.popupmenu_samp_amp,'Value') - 1;
+ locpeakrep = 2-get(handles.popupmenu_locpeakreplacement,'Value');
+ fracmearep = 2-get(handles.popupmenu_fracreplacement,'Value');
+
+ % cc1 = late(1)-sample2time(TimeOp, sampeak, srate) < xmin*kktime;
+ % ccdiff = abs((late(1)-sample2time(TimeOp, sampeak, srate)) - xmin*kktime);
+ % cc2 = time2sample(TimeOp, ccdiff, srate)>2;
+ % cc3 = late(2)+sample2time(TimeOp, sampeak, srate)>xmax*kktime;
+ % ccdiff = abs((late(2)+sample2time(TimeOp, sampeak, srate)) - xmax*kktime);
+ % cc4 = time2sample(TimeOp, ccdiff, srate)>2;
+
+ % if (cc1 && cc2) || (cc3 && cc4)
+ % msgboxText = msgboxText4peak;
+ % title = 'ERPLAB: measurement window';
+ % errorfound(sprintf(msgboxText,sampeak, sampeak, sampeak, xmin*kktime, xmax*kktime, xmin*kktime+sample2time(TimeOp, sampeak,srate), xmax*kktime-sample2time(TimeOp, sampeak,srate)), title);
+ % return
+ % end
+ if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz
+ fprintf('\nFractional Peak Frequency measurement in progress...\n');
+ else
+ fprintf('\nFractional Peak Latency measurement in progress...\n');
+ end
+ case 6 % inte/area value (fixed latencies)
+ % if nlate~=2
+ % if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz
+ % msgboxText = 'You must define two frequencies';
+ % else
+ % msgboxText = 'You must define two latencies';
+ % end
+ % title = 'ERPLAB: measurement window';
+ % errorfound(sprintf(msgboxText), title);
+ % return
+ % end
+ switch areatype
+ case 1
+ moption = 'areat';
+ fprintf('\nTotal area measurement in progress...\n');
+ case 2
+ moption = 'ninteg';
+ fprintf('\nNumerical integration in progress...\n');
+ case 3
+ moption = 'areap';
+ fprintf('\nPositive area measurement in progress...\n');
+ case 4
+ moption = 'arean';
+ fprintf('\nNegative area measurement in progress...\n');
+ end
+
+ case 7 % inte/area value (auto latencies)
+ if ~strcmpi(datatype, 'ERP')
+ msgboxText = 'Sorry. This type of measurement is not allowed for Power Spectrum data';
+ title = 'ERPLAB: geterpvaluesGUI() -> invalid input';
+ errorfound(sprintf(msgboxText), title);
+ return
+ end
+ % if nlate~=1
+ % %if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz
+ % % msgboxText = 'You must define only one frequency';
+ % %else
+ % msgboxText = 'You must define only one latency';
+ % %end
+ % title = 'ERPLAB: measurement window';
+ % errorfound(sprintf(msgboxText), title);
+ % return
+ % end
+ switch areatype
+ case 1
+ moption = 'areazt';
+ fprintf('\nTotal area measurement in progress...\n');
+ case 2
+ moption = 'nintegz';
+ fprintf('\nNumerical integration (automatic limits) in progress...\n');
+ case 3
+ moption = 'areazp';
+ fprintf('\nPositive area measurement (automatic limits) in progress...\n');
+ case 4
+ moption = 'areazn';
+ fprintf('\nNegative area measurement (automatic limits) in progress...\n');
+ end
+
+ case 8 % fractional inte/area latency
+ % if nlate~=2
+ % if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz
+ % msgboxText = 'You must define two frequencies';
+ % else
+ % msgboxText = 'You must define two latencies';
+ % end
+ % title = 'ERPLAB: measurement window';
+ % errorfound(sprintf(msgboxText), title);
+ % return
+ % end
+
+ set(handles.text_fraca,'String', 'Fractional Area')
+ frac = (get(handles.popupmenu_fraca,'Value') - 1)/100; % 0 to 1
+ if strcmpi(datatype, 'ERP')
+ meawordx = 'Latency';
+ else
+ meawordx = 'Frequency';
+ end
+ switch areatype
+ case 1
+ moption = 'fareatlat';
+ fprintf('\nFractional Total Area %s measurement in progress...\n', meawordx);
+ case 2
+ moption = 'fninteglat';
+ fprintf('\nFractional Total Area %s measurement in progress...\n', meawordx);
+ case 3
+ moption = 'fareaplat';
+ fprintf('\nFractional Positive Area %s measurement in progress...\n', meawordx);
+
+ case 4
+ moption = 'fareanlat';
+ fprintf('\nFractional Negative Area %s measurement in progress...\n', meawordx);
+ otherwise
+ error('wrong area type.')
+ end
+ fracmearep = 1+ (-1)^(get(handles.popupmenu_fracreplacement,'Value')); % when 1 means 0, when 2 means 2
+end
+
+%
+
+
+dig = get(handles.popupmenu_precision, 'Value');
+binlabop = get(handles.checkbox_binlabel,'Value'); % bin label option for table
+inclate = get(handles.checkbox_include_used_latencies, 'Value');
+intfactor = get(handles.popupmenu_interpofactor, 'Value');
+
+peakonset = get(handles.popupmenu_rise, 'Value'); % axs - get onset from menu value
+
+%
+% Output
+%
+outstr = {moption, dig, binlabop, polpeak, sampeak, locpeakrep, frac, fracmearep,...
+ send2ws, inclate, intfactor, peakonset};
+handles.output = outstr;
+
+guidata(hObject, handles);
+uiresume(handles.gui_chassis);
+
+
+%--------------------------------------------------------------------------
+function popupmenu_precision_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function popupmenu_precision_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+%--------------------------------------------------------------------------
+%--------------------------------------------------------------------------
+%--------------------------------------------------------------------------
+%--------------------------------------------------------------------------
+%--------------------------------------------------------------------------
+% -------------------------------------------------------------------------
+function pushbutton_run_CreateFcn(hObject, eventdata, handles)
+
+
+
+%--------------------------------------------------------------------------
+function popupmenu_pol_amp_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function popupmenu_pol_amp_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function popupmenu_samp_amp_Callback(hObject, eventdata, handles)
+kktime = handles.kktime;
+srate = handles.srate;
+pnts = get(handles.popupmenu_samp_amp,'Value')-1;
+intfactor = get(handles.popupmenu_interpofactor,'Value');
+if isempty(srate)
+ msecstr = sprintf('pnts ( ? ms)');
+else
+ msecstr = sprintf('pnts (%4.1f ms)', (pnts/srate*intfactor)*kktime);
+end
+set(handles.text_samp,'String',msecstr)
+
+%--------------------------------------------------------------------------
+function popupmenu_samp_amp_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function popupmenu_measurement_Callback(hObject, eventdata, handles)
+meamenu = get(handles.popupmenu_measurement, 'String');
+currentm = get(handles.popupmenu_measurement, 'Value');
+if currentm==7
+ mnamex = 'Numerical integration/Area between two (automatically detected) zero-crossing latencies';
+ question = [ '%s\n\nThis tool is still in alpha phase.\n'...
+ 'Use it under your responsibility.'];
+ title = 'ERPLAB: Overwriting Confirmation';
+ BackERPLABcolor = [1 0.9 0.3]; % yellow
+ oldcolor = get(0,'DefaultUicontrolBackgroundColor');
+ set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor)
+ button = questdlg(sprintf(question, mnamex), title,'OK','OK');
+ set(0,'DefaultUicontrolBackgroundColor',oldcolor)
+end
+
+areatype = get(handles.popupmenu_areatype,'Value');
+% formatout = get(handles.popupmenu_formatout,'Value');
+version = geterplabversion;
+set(handles.gui_chassis,'Name', ['ERPLAB ' version ' - ERP Measurements GUI - ' meamenu{currentm}])
+
+datatype = handles.datatype;
+if strcmpi(datatype, 'ERP')
+ meawordx = 'latenc';
+else
+ meawordx = 'frequenc';
+end
+
+%
+% NEW MENU
+%
+
+% 1 = 'Instantaneous amplitude',
+% 2 = 'Mean amplitude between two fixed latencies',...
+% 3 = 'Peak amplitude'
+% 4 = 'Peak latency'
+% 5 = 'Fractional Peak latency',...
+% 6 = 'Numerical integration/Area between two fixed latencies'
+% 7 = 'Numerical integration/Area between two (automatically detected) zero-crossing latencies'...
+% 8 = 'Fractional Area latency'
+
+switch currentm
+ case 1 % 'Instantaneous amplitude'
+ menupeakoff(hObject, eventdata, handles)
+ menufareaoff(hObject, eventdata, handles)
+ set(handles.popupmenu_rise, 'String', {'(pre-peak) onset','(post-peak) offset'})
+ set(handles.popupmenu_rise, 'Value', 1)
+ set(handles.text_punit,'String','% of peak')
+ set(handles.text_tip_inputlat, 'String',['(use one ' meawordx 'y)']);
+ set(handles.popupmenu_areatype,'Enable','off')
+ case {2,6} % mean, area, integral between fixed latencies
+ menupeakoff(hObject, eventdata, handles)
+ menufareaoff(hObject, eventdata, handles)
+ set(handles.popupmenu_rise, 'String', {'(pre-peak) onset','(post-peak) offset'})
+ set(handles.popupmenu_rise, 'Value', 1)
+ set(handles.text_punit,'String','% of peak')
+ set(handles.text_tip_inputlat, 'String',['(use two ' meawordx 'ies)']);
+ if currentm==6
+ set(handles.popupmenu_areatype,'Enable','on')
+ else
+ set(handles.popupmenu_areatype,'Enable','off')
+ end
+ case {3,4} % 'Peak amplitude', 'Peak latency'
+ menupeakon(hObject, eventdata, handles)
+ menufareaoff(hObject, eventdata, handles)
+ set(handles.popupmenu_rise, 'String', {'(pre-peak) onset','(post-peak) offset'})
+ set(handles.popupmenu_rise, 'Value', 1)
+ set(handles.text_punit,'String','% of peak')
+ % set(handles.text_tip_inputlat, 'String',['(use two ' meawordx 'ies)']);
+ set(handles.popupmenu_areatype,'Enable','off')
+ set(handles.popupmenu_fracreplacement, 'String', {'fractional absolute peak','"not a number" (NaN)'});
+ case 5 % 'Fractional Peak latency'
+ menupeakon(hObject, eventdata, handles)
+ menufareaon(hObject, eventdata, handles)
+ set(handles.popupmenu_rise, 'String', {'(pre-peak) onset','(post-peak) offset'})
+ set(handles.popupmenu_rise, 'Value', 1)
+ fracpos = round(frac*100)+1;
+ set(handles.popupmenu_fraca,'Value', fracpos)
+ set(handles.text_punit,'String','% of peak')
+ % set(handles.text_tip_inputlat, 'String',['(use two ' meawordx 'ies)']);
+ set(handles.text_fraca,'String', 'Fractional Peak');
+ set(handles.popupmenu_areatype,'Enable','off');
+ set(handles.popupmenu_fracreplacement, 'String', {'"not a number" (NaN)','show error message'});
+ case {7} % area, integral automatic limits
+ menupeakoff(hObject, eventdata, handles)
+ menufareaoff(hObject, eventdata, handles)
+ set(handles.popupmenu_rise, 'String', '--------')
+ set(handles.popupmenu_rise, 'Value', 1)
+ set(handles.popupmenu_rise, 'Enable', 'off')
+ set(handles.text_punit,'String','% of area')
+ % set(handles.text_tip_inputlat, 'String',['(use one "seed" ' meawordx 'y)']);
+ if currentm==7
+ set(handles.popupmenu_areatype,'Enable','on')
+ else
+ set(handles.popupmenu_areatype,'Enable','off')
+ end
+ case 8 % 'Fractional Area latency'
+ menupeakoff(hObject, eventdata, handles)
+ menufareaon(hObject, eventdata, handles)
+ %punit_str = get(handles.text_punit, 'String');
+ set(handles.popupmenu_rise, 'String', '--------')
+ set(handles.popupmenu_rise, 'Value', 1)
+ set(handles.popupmenu_rise, 'Enable', 'off')
+ set(handles.text_punit,'String','% of area')
+ set(handles.text_tip_inputlat, 'String',['(use two ' meawordx 'ies)']);
+ set(handles.text_fraca,'String', 'Fractional Area')
+ set(handles.popupmenu_areatype,'Enable','on')
+ set(handles.popupmenu_fracreplacement, 'String', {'show error message','"not a number" (NaN)'});
+ otherwise % 'test'
+ menupeakoff(hObject, eventdata, handles)
+ menufareaoff(hObject, eventdata, handles)
+ set(handles.text_tip_inputlat, 'String',['(use two ' meawordx 'ies)']);
+end
+
+%--------------------------------------------------------------------------
+function popupmenu_measurement_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function popupmenu_locpeakreplacement_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function popupmenu_locpeakreplacement_CreateFcn(hObject, eventdata, handles)
+
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function uipanel9_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function uipanel1_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function uipanel2_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function pushbutton_cancel_CreateFcn(hObject, eventdata, handles)
+
+% %--------------------------------------------------------------------------
+function text_tip_inputlat_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function uipanel4_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function uipanel6_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function uipanel8_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function uipanel12_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function uipanel13_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+% function radiobutton_erpset_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+% function radiobutton_folders_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function setall(hObject, eventdata, handles)
+
+% ALLERP = handles.ALLERP;
+% if isstruct(ALLERP)
+% nsets = length(ALLERP);
+% nbin = ALLERP(1).nbin;
+% nchan = ALLERP(1).nchan;
+% else
+% nsets = 0;
+% nbin = 1;
+% nchan = 1;
+% end
+datatype = handles.datatype;
+set(handles.popupmenu_samp_amp,'String',cellstr(num2str([0:40]')))
+set(handles.popupmenu_precision,'String', num2str([1:6]'))
+kktime = handles.kktime;
+
+
+
+set(handles.popupmenu_rise,'BackgroundColor',[1 1 1])
+set(handles.popupmenu_fraca,'BackgroundColor',[1 1 1])
+set(handles.popupmenu_fracreplacement,'BackgroundColor',[1 1 1])
+set(handles.popupmenu_locpeakreplacement,'BackgroundColor',[1 1 1])
+set(handles.popupmenu_areatype,'BackgroundColor',[1 1 1])
+
+set(handles.popupmenu_interpofactor,'BackgroundColor',[1 1 1])
+set(handles.popupmenu_precision,'BackgroundColor',[1 1 1])
+
+
+%
+% NEW MENU
+%
+
+% 1 = 'Instantaneous amplitude',
+% 2 = 'Mean amplitude between two fixed latencies',...
+% 3 = 'Peak amplitude'
+% 4 = 'Peak latency'
+% 5 = 'Fractional Peak latency',...
+% 6 = 'Numerical integration/Area between two fixed latencies'
+% 7 = 'Numerical integration/Area between two (automatically detected) zero-crossing latencies'...
+% 8 = 'Fractional Area latency'
+
+%
+% New Are type menu
+%
+% 1 = 'Rectified area (negative values become positive)'
+% 2 = 'Numerical integration (negative substracted from positive)'
+% 3 = 'Only positive area'
+% 4 = 'Only negative area'
+%
+
+if strcmpi(datatype, 'ERP')
+ measurearray = {'Instantaneous amplitude',...
+ 'Mean amplitude between two fixed latencies',...
+ 'Peak amplitude',...
+ 'Peak latency',...
+ 'Fractional Peak latency',...
+ 'Numerical integration/Area between two fixed latencies',...
+ 'Numerical integration/Area between two (automatically detected) zero-crossing latencies'...
+ 'Fractional Area latency'};
+else
+ measurearray = {'Instantaneous power',...
+ 'Mean power between two fixed frequencies',...
+ 'Peak power',...
+ 'Peak frequency',...
+ 'Fractional Peak frequency',...
+ 'Numerical integration/Area between two fixed frequencies',...
+ '------------------------------------------------------'...
+ 'Fractional Area frequency'};
+end
+set(handles.popupmenu_measurement, 'String', measurearray,'Enable','off');
+set(handles.popupmenu_locpeakreplacement, 'String', {'absolute peak','"not a number" (NaN)','show error message'});
+set(handles.popupmenu_fracreplacement, 'String', {'closest value','"not a number" (NaN)','show error message'});
+
+
+%
+% Type of Area
+%
+% areatype = {'Total area', 'Only positive area', 'Only negative area'};
+areatype = {'Rectified area (negative values become positive)', 'Numerical integration (area for negatives substracted from area for positives)',...
+ 'Area for positive waveforms (negative values will be zeroed)', 'Area for negative waveforms (positive values will be zeroed)'};
+set(handles.popupmenu_areatype, 'String', areatype);
+
+% Interpolation factor
+set(handles.popupmenu_interpofactor, 'String', cellstr(num2str([1:10]'))')
+
+%
+% GUI's working memory
+%
+def = handles.def;
+% def{:}
+
+if ~isempty(def)
+ op = def{1}; % option: type of measurement ---> instabl, meanbl, peakampbl, peaklatbl, area, areaz, or errorbl.
+ dig = def{2}; %Resolution
+ binlabop = def{3}; % 0: bin# as bin label for table, 1 bin label
+ polpeak = def{4}; % local peak polarity
+ sampeak = def{5}; % number of samples (one-side) for local peak detection criteria
+ locpeakrep = def{6}; % 1 abs peak , 0 Nan
+ frac = def{7};
+ fracmearep = def{8}; % def{19}; NaN
+ send2ws = def{9}; % 1 send to ws, 0 dont do
+ inclate = def{10};
+ intfactor = def{11};
+ if isempty(sampeak)
+ sampeak = 3;
+ end
+
+else
+
+ %%def = {'fareaplat', 3, 0, 1, 3, 0, 0.5, NaN, 0, 0, 1, 1};
+ op = 'meanbl'; % option: type of measurement ---> instabl, meanbl, peakampbl, peaklatbl, area, areaz, or errorbl.
+ dig = 3; %Resolution
+ binlabop = 0; % 0: bin# as bin label for table, 1 bin label
+ polpeak = 1; % local peak polarity
+ sampeak = 3; % number of samples (one-side) for local peak detection criteria
+ locpeakrep = 0; % 1 abs peak , 0 Nan
+ frac = 0.5;
+ fracmearep = 0; % def{19}; NaN
+ send2ws = 0; % 1 send to ws, 0 dont do
+ inclate = 1;
+ intfactor = 1;
+end
+if isempty(frac)
+ frac = 0.50;
+end
+
+%
+% New menu
+%
+[tfm, indxmeaX] = ismember_bc2({op}, {'instabl', 'meanbl', 'peakampbl', 'peaklatbl', 'fpeaklat',...
+ 'areat', 'areap', 'arean','areazt','areazp','areazn','fareatlat', 'fninteglat',...
+ 'fareaplat','fareanlat', 'ninteg','nintegz' } );
+
+%
+% fix index for menu
+%
+areatype=1; % 1=total; 2=integral; 3=pos; 4= neg
+fracmenuindex = 2-fracmearep;
+
+if ismember(indxmeaX,[6 7 8 16])
+ indxmea = 6;
+ areatype = find(indxmeaX==[6 16 7 8]); % 1,2,3,4
+elseif ismember(indxmeaX,[9 10 11 17])
+ areatype = find(indxmeaX==[9 17 10 11]); % 1,2,3,4
+
+ if strcmpi(datatype, 'ERP')
+ indxmea = 7;
+ else
+ indxmea = 1;
+ end
+elseif ismember(indxmeaX,[12 13 14 15])
+ areatype = find(indxmeaX==[12 13 14 15]); % 1,2,3,4
+ indxmea = 8;
+ fracmenuindex = round(2^(fracmearep/2)); % when 0 means 1, when 2 means 2;
+else
+ indxmea = indxmeaX;
+end
+
+%
+% Type of output
+%
+% 1 = one measurement per line; 0 = one erpset per line
+%
+set(handles.checkbox_include_used_latencies, 'Value', inclate);
+
+set(handles.checkbox_send2ws, 'Value', send2ws);
+set(handles.checkbox_binlabel, 'Value', binlabop); %0: use bin number as binlabel; 1:use bin descr as binlabel
+
+% interpolation
+set(handles.popupmenu_interpofactor, 'Value', intfactor);
+
+%
+% Measurements
+%
+set(handles.popupmenu_measurement,'value', indxmea);
+set(handles.popupmenu_fracreplacement,'value', fracmenuindex);
+
+%
+% NEW MENU (indxmea)
+%
+% 1 = 'Instantaneous amplitude',
+% 2 = 'Mean amplitude between two fixed latencies',...
+% 3 = 'Peak amplitude'
+% 4 = 'Peak latency'
+% 5 = 'Fractional Peak latency',...
+% 6 = 'Numerical integration/Area between two fixed latencies'
+% 7 = 'Numerical integration/Area between two (automatically detected) zero-crossing latencies'...
+% 8 = 'Fractional Area latency'
+
+set(handles.popupmenu_samp_amp,'value',sampeak+1);
+
+switch indxmea
+ case 1 % 'Instantaneous amplitude'
+ menupeakoff(hObject, eventdata, handles)
+ menufareaoff(hObject, eventdata, handles)
+ set(handles.popupmenu_rise, 'String', {'(pre-peak) onset','(post-peak) offset'})
+ set(handles.popupmenu_rise, 'Value', 1)
+ set(handles.text_punit,'String','% of peak')
+ set(handles.popupmenu_areatype,'Enable','off')
+ % set(handles.text_tip_inputlat, 'String',['(use one ' mwordx 'y)']);
+ case {2,6} % mean, area, integral between fixed latencies
+ menupeakoff(hObject, eventdata, handles)
+ menufareaoff(hObject, eventdata, handles)
+ set(handles.popupmenu_rise, 'String', {'(pre-peak) onset','(post-peak) offset'})
+ set(handles.popupmenu_rise, 'Value', 1)
+ set(handles.text_punit,'String','% of peak')
+ if indxmea==6
+ set(handles.popupmenu_areatype,'Value',areatype)
+ end
+ set(handles.popupmenu_areatype,'Enable','off')
+
+ case {3,4} % 'Peak amplitude', 'Peak latency'
+ menupeakon(hObject, eventdata, handles)
+ menufareaoff(hObject, eventdata, handles)
+ set(handles.popupmenu_rise, 'String', {'(pre-peak) onset','(post-peak) offset'})
+ set(handles.popupmenu_rise, 'Value', 1)
+ set(handles.text_punit,'String','% of peak')
+ % set(handles.text_tip_inputlat, 'String',['(use two ' mwordx 'ies)']);
+ set(handles.popupmenu_pol_amp,'Value',2-polpeak,'Enable','off')
+ %set(handles.popupmenu_samp_amp,'value',sampeak+1);
+ set(handles.popupmenu_locpeakreplacement,'value',2-locpeakrep);
+ set(handles.popupmenu_areatype,'Enable','off');
+ % set(handles.popupmenu_fracreplacement, 'String', {'fractional absolute peak','"not a number" (NaN)'});
+ case 5 % 'Fractional Peak latency'
+ menupeakon(hObject, eventdata, handles)
+ menufareaon(hObject, eventdata, handles)
+ set(handles.popupmenu_rise, 'String', {'(pre-peak) onset','(post-peak) offset'})
+ set(handles.popupmenu_rise, 'Value', 1)
+ fracpos = round(frac*100)+1;
+ set(handles.popupmenu_fraca,'Value', fracpos)
+ set(handles.text_punit,'String','% of peak')
+ % set(handles.text_tip_inputlat, 'String',['(use two ' mwordx 'ies)']);
+ set(handles.text_fraca,'String', 'Fractional Peak')
+ set(handles.popupmenu_pol_amp,'Value',2-polpeak,'Enable','off')
+ %set(handles.popupmenu_samp_amp,'value',sampeak+1);
+ set(handles.popupmenu_locpeakreplacement,'value',2-locpeakrep);
+ set(handles.popupmenu_fracreplacement,'value',2-fracmearep);
+ set(handles.popupmenu_areatype,'Enable','off');
+ % set(handles.popupmenu_fracreplacement, 'String', {'"not a number" (NaN)','show error message'});
+
+ if strcmpi(fracmearep,'NaN')
+ set(handles.popupmenu_fracreplacement, 'Value', 1);
+ else
+ set(handles.popupmenu_fracreplacement, 'Value', 2);
+ end
+ case 7 % area and integral with auto limits
+ menupeakoff(hObject, eventdata, handles);
+ menufareaoff(hObject, eventdata, handles);
+ set(handles.popupmenu_rise, 'String', '--------');
+ set(handles.popupmenu_rise, 'Value', 1);
+ set(handles.popupmenu_rise, 'Enable', 'off');
+ set(handles.popupmenu_areatype,'Enable','on');
+ set(handles.popupmenu_areatype,'Value',areatype);
+
+ case 8 % fractional area
+ menupeakoff(hObject, eventdata, handles)
+ menufareaon(hObject, eventdata, handles)
+ fracpos = round(frac*100)+1;
+ set(handles.popupmenu_rise, 'String', '--------')
+ set(handles.popupmenu_rise, 'Value', 1)
+ set(handles.popupmenu_rise, 'Enable', 'off')
+ set(handles.text_punit,'String','% of area')
+ set(handles.popupmenu_fraca,'Value', fracpos);
+
+
+ set(handles.text_fa3,'Enable', 'on')
+ set(handles.text_fraca,'String', 'Fractional Area')
+ set(handles.popupmenu_areatype,'Enable','on')
+ set(handles.popupmenu_areatype,'Value',areatype)
+ set(handles.popupmenu_fracreplacement, 'String', {'show error message','"not a number" (NaN)'});
+ if strcmpi(fracmearep,'NaN')
+ set(handles.popupmenu_fracreplacement, 'Value', 2);
+ else
+ set(handles.popupmenu_fracreplacement, 'Value', 1);
+ end
+
+ otherwise
+ menupeakoff(hObject, eventdata, handles)
+ menufareaoff(hObject, eventdata, handles)
+end
+
+set(handles.popupmenu_precision, 'Value', dig)
+set(handles.checkbox_send2ws, 'Value', send2ws);
+
+srate = handles.srate;
+try
+ msecstr = sprintf('pnts (%4.1f ms)', (sampeak/srate*intfactor)*kktime);
+catch
+ msecstr = 'pnts (... ms)';
+end
+
+set(handles.text_samp,'String',msecstr)
+
+%
+% Name & version
+%
+meamenu = get(handles.popupmenu_measurement, 'String');
+currentm = get(handles.popupmenu_measurement, 'Value');
+erplab_studio_default_values;
+version = erplabstudiover;
+set(handles.gui_chassis,'Name', ['EStudio ' version ' - ERP Measurement Tool > Type > Option'])
+handles.frac = frac;
+
+
+% Update handles structure
+guidata(hObject, handles);
+
+%--------------------------------------------------------------------------
+function gui_chassis_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function checkbox_send2ws_Callback(hObject, eventdata, handles)
+
+
+
+%--------------------------------------------------------------------------
+function radiobutton_f0_1erp_per_line_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+ set(handles.radiobutton_f1_1mea_per_line,'Value',0)
+ %set(handles.edit_label_mea,'Enable', 'off')
+else
+ set(hObject,'Value',1)
+end
+
+%--------------------------------------------------------------------------
+function radiobutton_f1_1mea_per_line_Callback(hObject, eventdata, handles)
+if get(hObject,'Value')
+ set(handles.radiobutton_f0_1erp_per_line,'Value',0)
+ % set(handles.edit_label_mea,'Enable', 'on')
+else
+ set(hObject,'Value',1)
+end
+
+
+%--------------------------------------------------------------------------
+function popupmenu_interpofactor_Callback(hObject, eventdata, handles)
+kktime = handles.kktime;
+srate = handles.srate;
+pnts = get(handles.popupmenu_samp_amp,'Value')-1;
+intfactor = get(handles.popupmenu_interpofactor,'Value');
+if isempty(srate)
+ msecstr = sprintf('pnts ( ? ms)');
+else
+ msecstr = sprintf('pnts (%4.1f ms)', (pnts/srate*intfactor)*kktime);
+end
+set(handles.text_samp,'String',msecstr)
+
+%--------------------------------------------------------------------------
+function popupmenu_interpofactor_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function edit10_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function edit10_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function popupmenu_fraca_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function popupmenu_fraca_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function popupmenu_fracreplacement_Callback(hObject, eventdata, handles)
+% if get(hObject,'Value')==1
+% set(handles. popupmenu_fracreplacement,'Value',2)
+% end
+
+%--------------------------------------------------------------------------
+function popupmenu_fracreplacement_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+%--------------------------------------------------------------------------
+function popupmenu_areatype_Callback(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function popupmenu_areatype_CreateFcn(hObject, eventdata, handles)
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+%--------------------------------------------------------------------------
+% function togglebutton_viewer_Callback(hObject, eventdata, handles)
+% if get(hObject, 'Value')
+% pushbutton_run_Callback(hObject, eventdata, handles)
+% end
+
+%--------------------------------------------------------------------------
+function uipanel_inputlat_CreateFcn(hObject, eventdata, handles)
+
+%--------------------------------------------------------------------------
+function gui_chassis_CloseRequestFcn(hObject, eventdata, handles)
+if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting')
+ % The GUI is still in UIWAIT, us UIRESUME
+ uiresume(handles.gui_chassis);
+else
+ % The GUI is no longer waiting, just close it
+ delete(handles.gui_chassis);
+end
+
+
+% --- Executes on selection change in popupmenu_rise.
+function popupmenu_rise_Callback(hObject, eventdata, handles)
+% hObject handle to popupmenu_rise (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Hints: contents = cellstr(get(hObject,'String')) returns popupmenu_rise contents as cell array
+% contents{get(hObject,'Value')} returns selected item from popupmenu_rise
+
+
+% --- Executes during object creation, after setting all properties.
+function popupmenu_rise_CreateFcn(hObject, eventdata, handles)
+% hObject handle to popupmenu_rise (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+% Hint: popupmenu controls usually have a white background on Windows.
+% See ISPC and COMPUTER.
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+% --- Executes during object creation, after setting all properties.
+function text_punit_CreateFcn(hObject, eventdata, handles)
+% hObject handle to text_punit (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+
+% --- Executes during object creation, after setting all properties.
+function text_fa1_CreateFcn(hObject, eventdata, handles)
+% hObject handle to text_fa1 (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+% --- Executes during object creation, after setting all properties.
+function text_fraca_CreateFcn(hObject, eventdata, handles)
+% hObject handle to text_fa1 (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+
+% --- Executes during object creation, after setting all properties.
+function checkbox_include_used_latencies_CreateFcn(hObject, eventdata, handles)
+% hObject handle to checkbox_include_used_latencies (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+
+% --- Executes during object deletion, before destroying properties.
+function checkbox_include_used_latencies_DeleteFcn(hObject, eventdata, handles)
+% hObject handle to checkbox_include_used_latencies (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+
+% --- Executes on button press in checkbox_include_used_latencies.
+function checkbox_include_used_latencies_Callback(hObject, eventdata, handles)
+% hObject handle to checkbox_include_used_latencies (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Hint: get(hObject,'Value') returns toggle state of checkbox_include_used_latencies
+
+
+% --- Executes on button press in checkbox_binlabel.
+function checkbox_binlabel_Callback(hObject, eventdata, handles)
+% hObject handle to checkbox_binlabel (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Hint: get(hObject,'Value') returns toggle state of checkbox_binlabel
diff --git a/studio_functions/displayEquiComERP.m b/studio_functions/displayEquiComERP.m
new file mode 100755
index 00000000..9e7f5dff
--- /dev/null
+++ b/studio_functions/displayEquiComERP.m
@@ -0,0 +1,74 @@
+function displayEquiComERP(xcom, nline2end)
+if nargin<2
+ nline2end = 140; % max line length
+ nd = nline2end; % number of dashed lines
+end
+
+%%changed by Guanghui Mar 2023
+ERPtooltype = erpgettoolversion('tooltype');
+if ~isempty(ERPtooltype)
+ if strcmpi(ERPtooltype,'EStudio')
+ Toolabel = 1;%%Get label from work space to confirm whether EStudio was executed.
+ else
+ Toolabel = 0;
+ end
+else
+ Toolabel = 1;
+end
+
+
+fprintf([repmat('-', 1,nd) '\n']);
+if Toolabel==0
+ try
+ cprintf([0.1333 0.5451 0.1333], '%%Equivalent command:\n');
+ catch
+ fprintf('%%Equivalent command:\n');
+ end
+elseif Toolabel==1
+
+ try
+ cprintf([0.1333 0.5451 0.1333], '%%EStudio:Equivalent command:\n');
+ catch
+ fprintf('%%EStudio:Equivalent command:\n');
+ end
+end
+if length(xcom)nline2end)
+ if isempty(indxcomx)
+ fprintf('%s\n', xcom); % as it is...
+ else
+ N = round((length(xcom)/nline2end));
+ Npos = nline2end:nline2end:N*nline2end;
+ Apos = unique_bc2(closest(indxcomx,Npos));
+ if length(Apos)>1 && (length(xcom)-Apos(end-1))<=nline2end
+ Apos = Apos(1:end-1);
+ elseif length(Apos)==1 && (length(xcom)-Apos)< 0.1*length(xcom)
+ fprintf('%s\n', xcom); % as it is...
+ fprintf([repmat('-', 1,nd) '\n']);
+ return
+ end
+ for kk=1:length(xcom)
+ if ~ismember_bc2(kk, Apos)
+ fprintf('%s', xcom(kk));
+ elseif ismember_bc2(kk, Apos) && kkGo back to ERPLAB menu');
+end
+fprintf('\n');
\ No newline at end of file
diff --git a/studio_functions/erpgettoolversion.m b/studio_functions/erpgettoolversion.m
new file mode 100755
index 00000000..b7734cbe
--- /dev/null
+++ b/studio_functions/erpgettoolversion.m
@@ -0,0 +1,43 @@
+
+
+function output = erpgettoolversion(field)
+output = [];
+if nargin<1
+ help erpgettoolversion;
+ return
+end
+
+if nargin==1 % read
+ try
+ p = which('EStudio');
+ p = p(1:findstr(p,'EStudio.m')-1);
+ v = load(fullfile(p,'erplab_running_version.erpm'), '-mat');
+ catch
+
+ msgboxText = ['EStudio (erpgettoolversion.m) could not find "erplab_running_version.erpm" or does not have permission for reading it.\n'...
+ 'Please, run EStudio once again.\n'];
+ try
+ cprintf([0.45 0.45 0.45], msgboxText');
+ catch
+ fprintf(msgboxText);
+ end
+ output = [];
+ return
+ end
+ if isfield(v, field)
+ output = v.(field);
+ else
+ output = [];
+ end
+ return
+
+else % invalid inputs
+ msgboxText = 'Wrong number of inputs for erpworkingmemory.m\n';
+ try
+ cprintf([0.45 0.45 0.45], msgboxText');
+ catch
+ fprintf(msgboxText);
+ end
+ output = [];
+ return
+end
\ No newline at end of file
diff --git a/studio_functions/erplab_running_version.m b/studio_functions/erplab_running_version.m
new file mode 100755
index 00000000..aca135a2
--- /dev/null
+++ b/studio_functions/erplab_running_version.m
@@ -0,0 +1,108 @@
+% PURPOSE :
+
+
+
+
+function erplab_running_version(varargin)
+erpcom = '';
+if nargin < 1
+ help erplab_running_version
+ return
+end
+
+% if isempty(tooltype)
+%
+%
+% end
+
+
+
+%
+% CHECK EEGLAB Version
+%
+if exist('erplab_running_version.erpm','file')==2
+ iserpmem = 1; % file for memory exists
+else
+ iserpmem = 0; % does not exist file for memory
+end
+
+%
+% Parsing inputs
+%
+p = inputParser;
+p.FunctionName = mfilename;
+p.CaseSensitive = false;
+
+p.addParamValue('version', @isnumeric); % erpset index or input file
+p.addParamValue('tooltype', @ischar); % 'on', 'off'
+
+p.parse(varargin{:});
+
+
+
+
+% if ~iserpmem
+
+p_location = which('EStudio');
+p_location = p_location(1:findstr(p_location,'EStudio.m')-1);
+try
+ tooltype = p.Results.tooltype;
+catch
+ tooltype = 'erplab';
+end
+
+try
+ version = p.Results.version;
+catch
+ version = 1;
+end
+
+save(fullfile(p_location,'erplab_running_version.erpm'),'tooltype','version');
+
+
+
+% end
+% erpcom = char(strcat());
+
+fn = fieldnames(p.Results);
+erpcom = sprintf( '%s erplab_running_version( %s ', inputname(1), inputname(1) );
+
+for q=1:length(fn)
+
+ fn2com = fn{q};
+ fn2res = p.Results.(fn2com);
+ if ~isempty(fn2res)
+ if ischar(fn2res)
+
+ erpcom = sprintf( '%s ''%s'', ''%s''', erpcom, fn2com, fn2res);
+ else
+ if isnumeric(fn2res)
+ fn2resstr = char(num2str(fn2res));
+ fnformat = '%s';
+ erpcom = sprintf( ['%s, ''%s'', ' fnformat], erpcom, fn2com, fn2resstr);
+ end
+
+ end
+ end
+
+end
+
+erpcom = sprintf( '%s );', erpcom);
+ALLERPCOM = [];
+if isempty(ALLERPCOM)
+ ALLERPCOM{1} = erpcom;
+else
+ ALLERPCOM{length(ALLERPCOM)+1} = erpcom;
+end
+
+assignin('base','ALLERPCOM',ALLERPCOM);
+
+assignin('base','ERPCOM',erpcom);%Send the history to Matlab workspace
+% get history from script. ERP
+
+displayEquiComERP(erpcom);
+
+
+
+
+return
diff --git a/studio_functions/erplab_studio_default_values.m b/studio_functions/erplab_studio_default_values.m
new file mode 100755
index 00000000..9c796e1e
--- /dev/null
+++ b/studio_functions/erplab_studio_default_values.m
@@ -0,0 +1,23 @@
+erplabstudiover = '1.00'; % current erplab studio version
+erplabstudiorel = '26-April-2022'; % DOB
+erplabstudiodeveloper = 'Simmons&Zhang';
+% erplabstudiolabel = 1;%0: using ERPLAB; 1:using ERPLAB Studio
+%ColorB = [170 180 195]/255; % old background color (until version 3)
+%ColorB = [0.9216 0.8353 0.6078]; % background color for version 4
+%ColorB = [0.7020 0.7647 0.8392]; % background color since version 4.0.0.3
+%ColorB = [0.9804 0.8118 0.5529]; % background color since version 4.0.0.11
+ColorB = [0.7020 0.77 0.85]; % background color since version 4.0.0.12
+ColorBviewer = [0.8 0.8 0.9];%[0.7765,0.7294,0.8627];
+% ColorB = [0.95 0.95 0.95];
+ColorF = [0.02 0.02 0.02]; % foreground color since version 4.0.2.0
+errorColorF = [0 0 0]; % foreground color for error window
+errorColorB = [0.6824 1 0.6353]; % background color for error window
+fontunitsGUI = 'pixels';
+
+set(0,'Units','pixels')
+thisscreen = get(0, 'ScreenSize');
+if thisscreen(4)>=1440
+ fontsizeGUI = 12; % high resolution display (eg Retina)
+else
+ fontsizeGUI = 11;
+end
diff --git a/studio_functions/erpworkingmemory.m b/studio_functions/erpworkingmemory.m
new file mode 100755
index 00000000..a4d75751
--- /dev/null
+++ b/studio_functions/erpworkingmemory.m
@@ -0,0 +1,189 @@
+% PURPOSE : encodes and retrieves ERPLAB's working memory
+%
+% FORMAT :
+%
+% output = erpworkingmemory(field, input2store)
+%
+% INPUTS :
+%
+% field - function name. e.g. 'pop_appenderp'
+% input2store - values to store (cell array)
+%
+%
+% OUTPUTS :
+%
+% output - stored values (cell array)
+%
+%
+% EXAMPLE 1: encode pop_appenderp's memory (values currently being used)
+%
+% erpworkingmemory('pop_appenderp', { optioni, erpset, prefixlist });
+%
+%
+% EXAMPLE 2: retrieve pop_appenderp's memory (values last used)
+%
+% def = erpworkingmemory('pop_appenderp');
+%
+%
+% *** This function is part of ERPLAB Toolbox ***
+% Author: Javier Lopez-Calderon &Guanghui Zhang
+% Center for Mind and Brain
+% University of California, Davis,
+% Davis, CA
+% 2009 & 2022
+
+%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b
+%
+% ERPLAB Toolbox
+% Copyright © 2007 The Regents of the University of California
+% Created by Javier Lopez-Calderon and Steven Luck
+% Center for Mind and Brain, University of California, Davis,
+% javlopez@ucdavis.edu, sjluck@ucdavis.edu
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see .
+
+function output = erpworkingmemory(field, input2store)
+output = [];
+if nargin<1
+ help erpworkingmemory
+ return
+end
+try
+ vmemoryerp = evalin('base', 'vmemoryerp');
+catch
+ vmemoryerp = [];
+end
+
+ERPtooltype = erpgettoolversion('tooltype');
+if ~isempty(ERPtooltype)
+ if strcmpi(ERPtooltype,'EStudio')
+ Toolabel = 1;%%Get label from work space to confirm whether EStudio was executed.
+
+ else
+ Toolabel = 0;
+ end
+else
+ Toolabel = 1;
+end
+
+
+if nargin==1 % read
+ if ~isempty(vmemoryerp) % variable at the workspace for storing/reading memory
+ % try
+ % v = memoryerp;
+ % catch
+ % msgboxText = 'ERPLAB could not load the variable, at workspace, called "memoryerp"';
+ % try
+ % cprintf([0.45 0.45 0.45], sprintf(msgboxText', erplabmemoryfile));
+ % catch
+ % fprintf(msgboxText);
+ % end
+ % output = [];
+ % return
+ % end
+ if isfield(vmemoryerp, field)
+ output = vmemoryerp.(field);
+ else
+ output = [];
+ end
+ else % file for storing/reading memory
+ try
+ if Toolabel==1%%When using EStudio
+ p = which('EStudio');
+ p = p(1:findstr(p,'EStudio.m')-1);
+ v = load(fullfile(p,'memoryerpstudio.erpm'), '-mat');
+ else%%When using ERPLAB
+ p = which('eegplugin_erplab');
+ p = p(1:findstr(p,'eegplugin_erplab.m')-1);
+ v = load(fullfile(p,'memoryerp.erpm'), '-mat');
+ end
+ catch
+ if Toolabel==1%%When using EStudio
+ msgboxText = ['ERPLAB Studio (erpworkingmemory.m) could not find "memoryerpstudio.erpm" or does not have permission for reading it.\n'...
+ 'Please, run EEGLAB once again or go to ERPLAB''s Setting menu and specify/create a new memory file.\n'];
+ else
+ msgboxText = ['ERPLAB Studio (erpworkingmemory.m) could not find "memoryerpstudio.erpm" or does not have permission for reading it.\n'...
+ 'Please, run EEGLAB Studio once again or go to EStudio''s Setting menu and specify/create a new memory file.\n'];
+
+ end
+
+ try
+ cprintf([0.45 0.45 0.45], msgboxText');
+ catch
+ fprintf(msgboxText);
+ end
+ output = [];
+ return
+ end
+ if isfield(v, field)
+ output = v.(field);
+ else
+ output = [];
+ end
+ end
+ return
+elseif nargin==2 % write
+ if ~isempty(vmemoryerp) % variable at the workspace for storing/reading memory
+ try
+ vmemoryerp.(field) = input2store;
+ assignin('base','vmemoryerp', vmemoryerp);
+ catch
+ msgboxText = 'ERPLAB (erpworkingmemory.m) could not write to the variable called vmemoryerp, at workspace.';
+ try
+ cprintf([0.45 0.45 0.45], sprintf(msgboxText', erplabmemoryfile));
+ catch
+ fprintf(msgboxText);
+ end
+ return
+ end
+ else % file for storing/reading memory
+ try
+ if Toolabel==1%%When using EStudio
+ eval([field '=input2store;'])
+ p = which('EStudio');
+ p = p(1:findstr(p,'EStudio.m')-1);
+ save(fullfile(p,'memoryerpstudio.erpm'), field,'-append');
+
+ else%%When using ERPLAB
+ eval([field '=input2store;'])
+ p = which('eegplugin_erplab');
+ p = p(1:findstr(p,'eegplugin_erplab.m')-1);
+ save(fullfile(p,'memoryerp.erpm'), field,'-append');
+ end
+ catch
+ if Toolabel==1%%When using EStudio
+ msgboxText = ['ERPLAB Studio could not find "memoryerpstudio.erpm" or does not have permission for writting on it.\n'...
+ 'Please, run EEGLAB Studio once again or go to EStudio''s Setting menu and specify/create a new memory file.\n'];
+ else
+ msgboxText = ['ERPLAB could not find "memoryerp.erpm" or does not have permission for writting on it.\n'...
+ 'Please, run EEGLAB once again or go to ERPLAB''s Setting menu and specify/create a new memory file.\n'];
+ end
+ try
+ cprintf([0.45 0.45 0.45], msgboxText');
+ catch
+ fprintf(msgboxText);
+ end
+ return
+ end
+ end
+else % invalid inputs
+ msgboxText = 'Wrong number of inputs for erpworkingmemory.m\n';
+ try
+ cprintf([0.45 0.45 0.45], msgboxText');
+ catch
+ fprintf(msgboxText);
+ end
+ output = [];
+ return
+end
\ No newline at end of file
diff --git a/studio_functions/estudioworkingmemory.m b/studio_functions/estudioworkingmemory.m
new file mode 100755
index 00000000..270aec06
--- /dev/null
+++ b/studio_functions/estudioworkingmemory.m
@@ -0,0 +1,144 @@
+% PURPOSE : encodes and retrieves ERPLAB's working memory
+%
+% FORMAT :
+%
+% output = erpworkingmemory(field, input2store)
+%
+% INPUTS :
+%
+% field - function name. e.g. 'pop_appenderp'
+% input2store - values to store (cell array)
+%
+%
+% OUTPUTS :
+%
+% output - stored values (cell array)
+%
+%
+% EXAMPLE 1: encode pop_appenderp's memory (values currently being used)
+%
+% erpworkingmemory('pop_appenderp', { optioni, erpset, prefixlist });
+%
+%
+% EXAMPLE 2: retrieve pop_appenderp's memory (values last used)
+%
+% def = erpworkingmemory('pop_appenderp');
+%
+%
+% *** This function is part of ERPLAB Toolbox ***
+% Author: Javier Lopez-Calderon &Guanghui Zhang
+% Center for Mind and Brain
+% University of California, Davis,
+% Davis, CA
+% 2009 & 2022
+
+%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b
+%
+% ERPLAB Toolbox
+% Copyright © 2007 The Regents of the University of California
+% Created by Javier Lopez-Calderon and Steven Luck
+% Center for Mind and Brain, University of California, Davis,
+% javlopez@ucdavis.edu, sjluck@ucdavis.edu
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see .
+
+function output = estudioworkingmemory(field, input2store);
+output = [];
+if nargin<1
+ help estudioworkingmemory
+ return
+end
+try
+ vmemoryestudio = evalin('base', 'vmemoryestudio');
+catch
+ vmemoryestudio = [];
+end
+
+
+
+if nargin==1 % read
+ if ~isempty(vmemoryestudio) % variable at the workspace for storing/reading memory
+ if isfield(vmemoryestudio, field)
+ output = vmemoryestudio.(field);
+ else
+ output = [];
+ end
+ else % file for storing/reading memory
+ try
+ p = which('EStudio');
+ p = p(1:findstr(p,'EStudio.m')-1);
+ v = load(fullfile(p,'memoryerpstudiopanels.erpm'), '-mat');
+
+ catch
+
+ msgboxText = ['EStudio (memoryerpstudiopanels.m) could not find "memoryerpstudiopanels.erpm" or does not have permission for reading it.\n'...
+ 'Please, run EStudio again or go to EStudio''s Setting menu and specify/create a new memory file.\n'];
+
+ try
+ cprintf([0.45 0.45 0.45], msgboxText');
+ catch
+ fprintf(msgboxText);
+ end
+ output = [];
+ return
+ end
+ if isfield(v, field)
+ output = v.(field);
+ else
+ output = [];
+ end
+ end
+ return
+elseif nargin==2 % write
+ if ~isempty(vmemoryestudio) % variable at the workspace for storing/reading memory
+ try
+ vmemoryestudio.(field) = input2store;
+ assignin('base','vmemoryestudio', vmemoryestudio);
+ catch
+ msgboxText = 'EStudio (estudioworkingmemory.m) could not write to the variable called vmemoryestudio, at workspace.';
+ try
+ cprintf([0.45 0.45 0.45], sprintf(msgboxText', erplabmemoryfile));
+ catch
+ fprintf(msgboxText);
+ end
+ return
+ end
+ else % file for storing/reading memory
+ try
+ eval([field '=input2store;'])
+ p = which('EStudio');
+ p = p(1:findstr(p,'EStudio.m')-1);
+ save(fullfile(p,'memoryerpstudiopanels.erpm'), field,'-append');
+ catch
+ msgboxText = ['EStudio could not find "memoryerpstudiopanels.erpm" or does not have permission for writting on it.\n'...
+ 'Please, run EStudio again or go to EStudio''s Setting menu and specify/create a new memory file.\n'];
+
+ try
+ cprintf([0.45 0.45 0.45], msgboxText');
+ catch
+ fprintf(msgboxText);
+ end
+ return
+ end
+ end
+else % invalid inputs
+ msgboxText = 'Wrong number of inputs for estudioworkingmemory.m\n';
+ try
+ cprintf([0.45 0.45 0.45], msgboxText');
+ catch
+ fprintf(msgboxText);
+ end
+ output = [];
+ return
+end
\ No newline at end of file
diff --git a/studio_functions/geterplabstudioversion.m b/studio_functions/geterplabstudioversion.m
new file mode 100755
index 00000000..40fff9a4
--- /dev/null
+++ b/studio_functions/geterplabstudioversion.m
@@ -0,0 +1,45 @@
+% PURPOSE: gets current ERPLAB's version
+%
+% FORMAT:
+%
+% version = geterplabversion;
+%
+% or
+%
+%
+% [version reldate] = geterplabversion; % reldate=release date
+%
+%
+% *** This function is part of ERPLAB Toolbox ***
+% Author: Javier Lopez-Calderon
+% Center for Mind and Brain
+% University of California, Davis,
+% Davis, CA
+% 2009
+
+%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b
+%
+% ERPLAB Toolbox
+% Copyright © 2007 The Regents of the University of California
+% Created by Javier Lopez-Calderon and Steven Luck
+% Center for Mind and Brain, University of California, Davis,
+% javlopez@ucdavis.edu, sjluck@ucdavis.edu
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see .
+
+function [version reldate] = geterplabstudioversion
+
+erplab_studio_default_values
+version = erplabstudiover;
+reldate = erplabstudiorel;
\ No newline at end of file
diff --git a/studio_functions/memoryerpstudio.erpm b/studio_functions/memoryerpstudio.erpm
new file mode 100644
index 00000000..9aaa7a95
Binary files /dev/null and b/studio_functions/memoryerpstudio.erpm differ
diff --git a/studio_functions/memoryerpstudiopanels.erpm b/studio_functions/memoryerpstudiopanels.erpm
new file mode 100644
index 00000000..0068b260
Binary files /dev/null and b/studio_functions/memoryerpstudiopanels.erpm differ
diff --git a/studio_functions/o_ERPDAT.m b/studio_functions/o_ERPDAT.m
new file mode 100755
index 00000000..ea07e70a
--- /dev/null
+++ b/studio_functions/o_ERPDAT.m
@@ -0,0 +1,79 @@
+classdef o_ERPDAT < handle
+ properties
+ ALLERP
+ ERP
+ CURRENTERP
+ Count_ERP
+ ERP_chan
+ ERP_bin
+ Count_currentERP
+ Process_messg
+ Two_GUI
+ end
+
+
+ events
+ erpschange
+ drawui_CB
+ cerpchange
+ Count_ERP_change
+ ERP_chan_change
+ ERP_bin_change
+ Count_currentERP_change
+ Messg_change
+ Two_GUI_change
+ end
+
+
+ methods
+ function set.ALLERP(obj,value)
+ obj.ALLERP = value;
+ notify(obj,'erpschange');
+ end
+ function set.ERP(obj,value)
+ obj.ERP = value;
+ notify(obj,'drawui_CB');
+ end
+ %%Modified CurrentERP
+ function set.CURRENTERP(obj,value)
+ obj.CURRENTERP = value;
+ notify(obj,'cerpchange');
+ end
+ %%ERP Plotting panel
+ function set.Count_ERP(obj,value)
+ obj.Count_ERP = value;
+ notify(obj,'Count_ERP_change');
+ end
+ %Modified channels of the selected ERP
+ function set.ERP_chan(obj,value)
+ obj.ERP_chan = value;
+ notify(obj,'ERP_chan_change');
+ end
+ %Modified bins of the selected ERP
+ function set.ERP_bin(obj,value)
+ obj.ERP_bin = value;
+ notify(obj,'ERP_bin_change');
+ end
+
+ %Modified bins of the selected ERP
+ function set.Count_currentERP(obj,value)
+ obj.Count_currentERP = value;
+ notify(obj,'Count_currentERP_change');
+ end
+
+
+ %Modified bins of the selected ERP
+ function set.Process_messg(obj,value)
+ obj.Process_messg = value;
+ notify(obj,'Messg_change');
+ end
+
+ %capture the change from main EStudio
+ function set.Two_GUI(obj,value)
+ obj.Two_GUI = value;
+ notify(obj,'Two_GUI_change');
+ end
+
+
+ end
+end
\ No newline at end of file
diff --git a/studio_functions/painterplabstudio.m b/studio_functions/painterplabstudio.m
new file mode 100755
index 00000000..bdfbac85
--- /dev/null
+++ b/studio_functions/painterplabstudio.m
@@ -0,0 +1,89 @@
+% PURPOSE : sets background and foreground color of the current ERPLAB's GUI
+%
+% FORMAT :
+%
+% handles = painterplab(handles, type);
+%
+% handles - GUI's handles structure
+%
+%
+% *** This function is part of ERPLAB Toolbox ***
+% Author: Javier Lopez-Calderon
+% Center for Mind and Brain
+% University of California, Davis,
+% Davis, CA
+% 2009
+
+%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b
+%
+% ERPLAB Toolbox
+% Copyright © 2007 The Regents of the University of California
+% Created by Javier Lopez-Calderon and Steven Luck
+% Center for Mind and Brain, University of California, Davis,
+% javlopez@ucdavis.edu, sjluck@ucdavis.edu
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see .
+
+function handles = painterplabstudio(handles, type)
+if nargin<2
+ type = 0;
+end
+if type==0
+ %
+ % Color GUI
+ %
+ ColorB = erpworkingmemory('ColorB');
+ ColorF = erpworkingmemory('ColorF');
+elseif type==1
+ ColorB = [0.95 0.95 0.95];
+ ColorF = [0 0 0];
+end
+if isempty(ColorB)
+ ColorB = [0.95 0.95 0.95];
+ %ColorB = [0.83 0.82 0.79];
+end
+if isempty(ColorF)
+ ColorF = [0 0 0];
+end
+
+filedsn = fieldnames(handles);
+
+% GUI's objects' color background
+for kk=1:length(filedsn)
+ mstr = regexpi(filedsn{kk},'^figure|^axes1|^nbin|^edit|^listbox|^EEG|^ERP|togglebutton_summary|^pushbutton|totline|indxline|ERP_figure|Scalp_figure|counterchanwin|counterbinwin','match');
+ if isempty(mstr)
+ num = handles.(filedsn{kk});
+ if ~iscell(num) && ~isstruct(num)
+ if num~=1
+ try
+ set(num, 'BackgroundColor', ColorB)
+ catch
+ end
+ try
+ set(num, 'ForegroundColor', ColorF)
+ catch
+
+ end
+ end
+ end
+ end
+end
+% GUI's color background
+try
+ set(handles.gui_chassis, 'Color', ColorB)
+ %disp('Mira:')
+ %num
+ %filedsn{kk}
+catch
+end
\ No newline at end of file
diff --git a/studio_functions/setfonterplabestudio.m b/studio_functions/setfonterplabestudio.m
new file mode 100755
index 00000000..961868c7
--- /dev/null
+++ b/studio_functions/setfonterplabestudio.m
@@ -0,0 +1,87 @@
+% PURPOSE: sets ERPLAB's GUIs' font
+%
+% FORMAT:
+%
+% handles = setfonterplab(handles, fontsize, fontunits);
+%
+% INPUT
+%
+% handles - GUI's handles stucture
+% fontsize - font size
+% fontunits - font units ('pixels', 'points')
+%
+%
+% *** This function is part of ERPLAB Toolbox ***
+% Author: Javier Lopez-Calderon & Johanna Kreither
+% Center for Mind and Brain
+% University of California, Davis,
+% Davis, CA
+% 2012
+
+%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b
+%
+% ERPLAB Toolbox
+% Copyright © 2007 The Regents of the University of California
+% Created by Javier Lopez-Calderon and Steven Luck
+% Center for Mind and Brain, University of California, Davis,
+% javlopez@ucdavis.edu, sjluck@ucdavis.edu
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see .
+
+function handles = setfonterplabestudio(handles, fontsize, fontunits)
+
+if nargin<3
+ fontunits = [];
+end
+if nargin<2
+ fontsize = [];
+end
+if isempty(fontsize)
+ %
+ % GUI's fontsize
+ %
+ fontsize = f_get_default_fontsize();
+end
+if isempty(fontsize)
+ fontsize = 10;
+end
+if isempty(fontunits)
+ %
+ % GUI's fontsize
+ %
+ fontunits = erpworkingmemory('fontunitsGUI');
+end
+if isempty(fontunits)
+ fontunits = 'points';
+end
+
+filedsn = fieldnames(handles);
+
+for j=1:length(filedsn)
+ %mstr = regexp(filedsn{j},'^nbin|^edit|^listbox|^EEG|^ERP|togglebutton_summary|^pushbutton|totline|indxline|Plotting_ERP|Scalp|counterchanwin|counterbinwin|text_erpset','match');
+ mstr = regexp(filedsn{j},'^EEG|^ERP|totline|Plotting_ERP|Scalp|text_erpset','match');
+ if isempty(mstr)
+ num = handles.(filedsn{j});
+ if ~iscell(num) && ~isstruct(num)
+ if num~=1
+ try
+ set(num, 'FontUnits', fontunits)
+ set(num, 'FontSize' , fontsize)
+ catch
+
+ end
+ end
+ end
+ end
+end
\ No newline at end of file