function varargout = bm(varargin)
%BM GUI for Brookshear Machine emulator
% BM creates a new emulator and gui if none exists, or if there is an
% existing instance, it raises it.
%
% H = BM returns the handle to a new BM or the handle to
% the existing singleton.
%
% BM('CALLBACK',hObject,eventData,handles,...) calls the local
% function named CALLBACK in BM.M with the given input arguments.
%
% BM('Property','Value',...) creates a new BM or raises the
% existing singleton. Starting from the left, property value pairs are
% applied to the GUI before bm_OpeningFcn gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to bm_OpeningFcn via varargin.
%
% See also: BMACHINE, GUIDE, GUIDATA, GUIHANDLES
% Copyright 2008 University of Sussex and David Young
% Last Modified by GUIDE v2.5 29-Dec-2008 18:08:06
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @bm_OpeningFcn, ...
'gui_OutputFcn', @bm_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 bm is made visible.
function bm_OpeningFcn(hObject, eventdata, handles, varargin) %#ok<*INUSL>
% hObject handle to figure
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to bm
% Choose default command line output for bm
handles.output = hObject;
% Create and store Brookshear machine
handles.machine = newbm;
% For bitmap display
handles.bitmapDisplay = get(handles.bitmappanel, 'UserData');
set(hObject, 'Colormap', handles.bitmapDisplay.colourmap);
% Update handles structure
guidata(hObject, handles);
% --- Outputs from this function are returned to the command line.
function varargout = bm_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;
% --- Executes when user attempts to close figure1.
function figure1_CloseRequestFcn(hObject, eventdata, handles) %#ok<*INUSD,*DEFNU>
% 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)
delete(hObject); % closes the figure
% if not running desktop, assume BM is meant to be standalone, so quit
if ~desktop('-inuse')
quit;
end
%---------------------- Memory panel --------------------------------------
function mempanel_CreateFcn(hObject, eventdata, handles)
% Main memory panel
% Would be nice to use uitable for this, but updating the table data always
% moves the focus to the top left table cell, so hopeless if the edit
% action updates other cells
defaultFontSize(hObject);
% Parameters for edit cell layout - panel size must accommodate
nrows = 32; % rows to display
maxrows = 256; % must agree with machine memory size
textcol = [0.9 0.9 1];
pccol = [1 0.75 0.75];
rows = [1 nrows];
headers = memstrings;
insttype = 'descriptive';
strings = memstrings([], rows, insttype);
ncols = length(headers);
units = 'characters';
width = 13; % cell dimensions in units above
instrwidth = 40;
height = 1.25;
set(hObject, 'Units', units);
panelpos = get(hObject, 'Position');
l1 = 7; % left side x coord of leftmost cell
b = panelpos(4) - 2 - height; % bottom y coord of current cell
lpad = 0; % extra spacing
bpad = 0.2; % extra spacing
% array of data text/edit cells
uimemctls = zeros(nrows, ncols);
% create main text cells - first col and row not editable
for row = 0:nrows
l = l1;
for col = 1:ncols
if row == 0
str = headers{col};
else
str = strings{row, col};
end
if row == 0 || col == 1 || col == ncols
style = 'text';
if (row == 1 || row == 2) && col == 1
bgcolour = pccol;
else
bgcolour = textcol;
end
else
style = 'edit';
bgcolour = 'w';
end
if col == ncols
w = instrwidth;
align = 'left';
else
w = width;
align = 'center';
end
h = uicontrol(hObject, ...
'Style', style, ...
'Units', units, ...
'Position', [l, b, w, height], ...
'String', str, ...
'Callback', @membox_Callback, ...
'KeyPressFcn', @membox_KeyPressFcn, ...
'Interruptible', 'on', ... % must be on for stringready to work
'BusyAction', 'queue', ...
'BackgroundColor', bgcolour, ...
'HorizontalAlignment', align, ...
'UserData', [row col] ...
);
l = l + w + lpad;
if row > 0
uimemctls(row, col) = h;
end
end
b = b - height - bpad;
end
% uicontrol used to force focus change when string in edit
% uicontrol needs to be read
ud.textcontrol = uicontrol(hObject, ...
'Style', 'text', ...
'Units', units, ...
'Position', [0.1 0.1 0.1 0.1], ...
'String', '', ...
'Interruptible', 'off', ...
'BusyAction', 'cancel', ...
'BackgroundColor', get(hObject, 'BackgroundColor'), ...
'Visible', 'on' ... % needs to be "visible"
);
% Data for callbacks
ud.rows = rows;
ud.maxrows = maxrows;
ud.ctls = uimemctls;
ud.textcol = textcol;
ud.pccol = pccol;
ud.pcrow = 1;
ud.insttype = insttype;
set(hObject, 'UserData', ud);
function membox_Callback(hObject, eventdata)
% fish out all the bits and pieces from the gui
panel = get(hObject, 'Parent');
ud = get(panel, 'UserData');
ctls = ud.ctls;
rows = ud.rows;
coords = get(hObject, 'UserData');
row = coords(1);
col = coords(2);
a = rows(1) + row - 2; % machine address
handles = guidata(hObject);
machine = handles.machine;
str = get(hObject, 'String');
% Get new value, update machine if valid
try
machine.memory(a+1) = string2val(col, str);
catch err
if ~bmexception(err)
rethrow(err);
end
end
% update display and gui
strings = memstrings(machine, [a a]+1, ud.insttype);
ncols = length(strings);
for c = 2:ncols
set(ctls(row, c), 'String', strings{1, c});
end;
if oddaddr(machine.pc, a) && row > 1 % show instruction on line above
set(ctls(row-1, ncols), 'String', ...
instr2string(ud.insttype, machine.memory(a), machine.memory(a+1)));
end
handles.machine = machine;
guidata(hObject, handles);
% update bitmap display
if a >= 128 && a <= 255 && handles.bitmapDisplay.on
bitmapDisplay(hObject);
end
function membox_KeyPressFcn(hObject, eventdata, handles)
% eventdata structure with the following fields (see UICONTROL)
% Key: name of the key that was pressed, in lower case
% Character: character interpretation of the key(s) that was pressed
% Modifier: name(s) of the modifier key(s) (i.e., control, shift) pressed
%
% Used to move focus to next location and maybe scroll when enter or arrow
% keys pressed. Biggest problem is getting the string on an arbitrary key
% press - stringready is the nasty solution to this.
% Needs to lock itself to avoid acting on interrupts from repeating keys.
persistent running;
if ~isempty(running)
return
end
running = true; %#ok<NASGU>
panel = get(hObject, 'Parent');
ud = get(panel, 'UserData');
ctls = ud.ctls;
rows = ud.rows;
maxrows = ud.maxrows;
coords = get(hObject, 'UserData');
row = coords(1);
col = coords(2);
switch eventdata.Key
case {'return' 'downarrow'}
if row < rows(2)-rows(1)+1
uicontrol(ctls(row+1, col)); % give focus to next control down
elseif rows(2) < maxrows
stringReady(hObject);
ud.rows = rows + 1;
set(panel, 'UserData', ud);
updateMemDisplay(panel);
setmemslider(panel);
end
case 'uparrow'
if row > 1
uicontrol(ctls(row-1, col)); % give focus to next control down
elseif rows(1) > 1
stringReady(hObject);
ud.rows = rows - 1;
set(panel, 'UserData', ud);
updateMemDisplay(panel);
setmemslider(panel);
end
case 'pagedown'
jumpsize = min(rows(2) - rows(1) + 1, maxrows - rows(2));
if jumpsize
stringReady(hObject);
ud.rows = rows + jumpsize;
set(panel, 'UserData', ud);
updateMemDisplay(panel);
setmemslider(panel);
end
case 'pageup'
jumpsize = min(rows(2) - rows(1) + 1, rows(1) - 1);
if jumpsize
stringReady(hObject);
ud.rows = rows - jumpsize;
set(panel, 'UserData', ud);
updateMemDisplay(panel);
setmemslider(panel);
end
end
running = [];
function updateMemDisplay(panel)
% Updates the memory display given its containing panel object
ud = get(panel, 'UserData');
ctls = ud.ctls;
rows = ud.rows;
oldpcrow = ud.pcrow;
handles = guidata(panel);
machine = handles.machine;
strings = memstrings(machine, rows, ud.insttype);
for row = 1:rows(2)-rows(1)+1
for col = 1:size(ctls, 2);
set(ctls(row, col), 'String', strings{row, col});
end
end
pcrow = double(machine.pc) + 2 - rows(1);
if pcrow ~= oldpcrow
disprows = diff(rows) + 1;
oldrows = [oldpcrow oldpcrow+1];
oldrows = oldrows(oldrows >= 1 & oldrows <= disprows);
set(ctls(oldrows, 1), 'Background', ud.textcol);
newrows = [pcrow pcrow+1];
newrows = newrows(newrows >= 1 & newrows <= disprows);
set(ctls(newrows, 1), 'Background', ud.pccol);
ud.pcrow = pcrow;
set(panel, 'UserData', ud);
end
if handles.bitmapDisplay.on
bitmapDisplay(panel);
end
function stringReady(hObject)
% Forces an edit control to make its string available as if return had been
% pressed, by moving focus to a text child. Very clumsy - there should be a
% good way to do this
ud = get(get(hObject, 'Parent'), 'UserData');
uicontrol(ud.textcontrol);
drawnow; % This is essential, as change of focus executes asynchronously
uicontrol(hObject);
function memresetbutton_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
function memresetbutton_Callback(hObject, eventdata, handles)
panel = get(hObject, 'Parent');
handles.machine.memory(:) = 0;
guidata(hObject, handles);
updateMemDisplay(panel);
function savemem_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
ud.file = '';
set(hObject, 'UserData', ud);
function savemem_Callback(hObject, eventdata, handles)
ud = get(hObject, 'UserData');
[filename, pathname] = uiputfile('*.txt', 'Save memory as', ud.file);
errDisplay(hObject, '');
if ~isequal(filename, 0) && ~isequal(pathname, 0)
file = fullfile(pathname, filename);
ud.file = file;
set(hObject, 'UserData', ud);
try
panelud = get(handles.mempanel, 'UserData');
savemem(handles.machine, file, panelud.insttype);
catch ME
errDisplay(hObject, ['Memory save failed:' ME.message]);
return;
end
end
function loadmem_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
ud.file = '';
set(hObject, 'UserData', ud);
function loadmem_Callback(hObject, eventdata, handles)
ud = get(hObject, 'UserData');
[filename, pathname] = uigetfile('*.txt', 'Load memory from', ud.file);
errDisplay(hObject, '');
if ~isequal(filename, 0) && ~isequal(pathname, 0)
file = fullfile(pathname, filename);
ud.file = file;
set(hObject, 'UserData', ud);
try
handles.machine = loadmem(handles.machine, readtext(file));
catch ME
errDisplay(hObject, ['Memory load failed:' ME.message]);
return;
end
guidata(hObject, handles);
updateMemDisplay(handles.mempanel);
end
function assembbutton_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
ud.file = '';
set(hObject, 'UserData', ud);
function assembbutton_Callback(hObject, eventdata, handles)
ud = get(hObject, 'UserData');
[filename, pathname] = uigetfile('*.txt', 'Assemble from', ud.file);
errDisplay(hObject, '');
if ~isequal(filename, 0) && ~isequal(pathname, 0)
file = fullfile(pathname, filename);
ud.file = file;
set(hObject, 'UserData', ud);
try
handles.machine = loadmem(handles.machine, assembler(file));
catch ME
errDisplay(hObject, ['Assembly/load failed:' ME.message]);
return;
end
guidata(hObject, handles);
updateMemDisplay(handles.mempanel);
end
function assembfilebutton_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
ud.filein = '';
ud.fileout = '';
set(hObject, 'UserData', ud);
function assembfilebutton_Callback(hObject, eventdata, handles)
ud = get(hObject, 'UserData');
[filenamein, pathnamein] = uigetfile('*.txt', 'Assemble from', ud.filein);
errDisplay(hObject, '');
if ~isequal(filenamein, 0) && ~isequal(pathnamein, 0)
filein = fullfile(pathnamein, filenamein);
ud.filein = filein;
set(hObject, 'UserData', ud);
try
machcode = assembler(filein);
catch ME
errDisplay(hObject, ['Assembly failed:' ME.message]);
return;
end
[filenameout, pathnameout] = uiputfile('*.txt', 'Save machine code as', ud.fileout);
if ~isequal(filenameout, 0) && ~isequal(pathnameout, 0)
fileout = fullfile(pathnameout, filenameout);
ud.fileout = fileout;
set(hObject, 'UserData', ud);
try
writetext(machcode, fileout);
catch ME
errDisplay(hObject, ['Memory save failed:' ME.message]);
return;
end
end
end
function assembhelpbutton_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
function assembhelpbutton_Callback(hObject, eventdata, handles)
showhelp('assembhelp');
function instrTextPanel_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
function descriptivetext_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
function descriptivetext_Callback(hObject, eventdata, handles)
panel = handles.mempanel;
ud = get(panel, 'UserData');
ud.insttype = 'descriptive';
set(panel, 'UserData', ud);
updateMemDisplay(panel);
function assembtext_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
function assembtext_Callback(hObject, eventdata, handles)
panel = handles.mempanel;
ud = get(panel, 'UserData');
ud.insttype = 'assembler';
set(panel, 'UserData', ud);
updateMemDisplay(panel);
function memslider_CreateFcn(hObject, eventdata, handles)
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor',[.9 .9 .9]);
end
set(hObject, ...
'Value', 1, ...
'SliderStep', [1/112 1/7], ...
'Interruptible', 'off', ...
'BusyAction', 'cancel');
set(hObject, 'UserData', false); % indicates whether slider being changed by program
function memslider_Callback(hObject, eventdata, handles)
if ~get(hObject, 'UserData') % avoid recursion
v = get(hObject, 'Value'); % default puts 0 at the bottom
panel = get(hObject, 'Parent');
ud = get(panel, 'UserData');
newrows = memsliderval2rows(v, ud.maxrows, ud.rows);
if ~isequal(newrows, ud.rows)
ud.rows = newrows;
set(panel, 'UserData', ud);
updateMemDisplay(panel);
end
end
function setmemslider(panel)
% Set the memory slider according to the current rows
handles = guidata(panel);
ud = get(panel, 'UserData');
v = memsliderrows2val(ud.rows, ud.maxrows);
slider = handles.memslider;
set(slider, 'Value', v);
function rows = memsliderval2rows(v, maxrows, rows)
% Convert slider value in range 0 to 1 to row range to display
disprows = diff(rows) + 1;
rows(1) = 1 + round((1-v) * (maxrows-disprows));
rows(2) = rows(1) + disprows - 1;
function v = memsliderrows2val(rows, maxrows)
% Inverse of above
v = 1 - (rows(1) - 1) / (maxrows - (diff(rows) + 1));
%---------------------- Register panel ------------------------------------
function regpanel_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
headers = regstrings;
strings = regstrings([]);
[nrows, ncols] = size(strings);
units = 'characters';
set(hObject, 'Units', units);
width = 12.5; % cell dimensions in units above
height = 1.25;
panelpos = get(hObject, 'Position');
l1 = 1; % left side x coord of leftmost cell
b = panelpos(4) - 2 - height; % bottom y coord of current cell
lpad = 0.2; % extra spacing
bpad = 0.75; % extra spacing
% array of data text/edit cells
uiregctls = zeros(nrows, ncols);
% create main text cells - not editable
for row = 0:nrows
l = l1;
for col = 1:ncols
if row == 0
str = headers{col};
else
str = strings{row, col};
end
h = uicontrol(hObject, ...
'Style', 'text', ...
'Units', units, ...
'Position', [l, b, width, height], ...
'String', str, ...
'BackgroundColor', [0.9 1 0.9] ...
);
l = l + width + lpad;
if row > 0
uiregctls(row, col) = h;
end
end
b = b - height - bpad;
end
% Data for callbacks
ud.ctls = uiregctls;
% Program counter
l = l1;
uicontrol(hObject, ...
'Style', 'text', ...
'Units', units, ...
'Position', [l, b, 2*width + lpad, height], ...
'String', 'Program counter', ...
'BackgroundColor', [1 0.8 0.8] ...
);
l = l + 2*(width + lpad);
ud.pcctl = uicontrol(hObject, ...
'Style', 'edit', ...
'Units', units, ...
'Position', [l, b, width, height], ...
'BackgroundColor', [1 0.8 0.8], ...
'String', strings{1, 3}, ...
'Callback', @pcedit_Callback ...
);
set(hObject, 'UserData', ud);
function updateRegDisplay(panel)
% Updates the register display, given its panel
ud = get(panel, 'UserData');
ctls = ud.ctls;
handles = guidata(panel);
machine = handles.machine;
strings = regstrings(machine);
for row = 1:size(strings, 1)
for col = 1:size(strings, 2);
set(ctls(row, col), 'String', strings{row, col});
end
end
pcstr = bits2strings(0, machine.pc);
set(ud.pcctl, 'String', pcstr{3});
function pcedit_Callback(hObject, eventdata, handles)
handles = guidata(hObject);
inp = get(hObject, 'String');
try
handles.machine.pc = string2val(3, inp);
catch err
if ~bmexception(err)
rethrow(err);
end
end
pcstr = bits2strings(0, handles.machine.pc);
set(hObject, 'String', pcstr{3});
% update
guidata(hObject, handles);
updateMemDisplay(handles.mempanel);
function resetbutton_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
function resetbutton_Callback(hObject, eventdata, handles)
machine = resetReg(handles.machine);
machine.pc = 0;
handles.machine = machine;
guidata(hObject, handles);
updateDisplays(handles);
errDisplay(hObject, '');
%---------------------- Information panel ---------------------------------
function infopanel_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
function instrucbutton_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
function instrucbutton_Callback(hObject, eventdata, handles)
showinstructions;
function helpbutton_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
function helpbutton_Callback(hObject, eventdata, handles)
showhelp('bmhelp');
function assembhelp2_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
function assembhelp2_Callback(hObject, eventdata, handles)
showhelp('assembhelp');
function errortext_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
function errDisplay(hObject, message)
handles = guidata(hObject);
set(handles.errortext, 'String', message);
%---------------------- Control panel -------------------------------------
function controlpanel_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
ud.maxdelay = 4;
ud.delay = ud.maxdelay;
set(hObject, 'UserData', ud);
function running = stepDisplay(hObject)
handles = guidata(hObject);
errDisplay(hObject, '');
try
handles.machine = step(handles.machine);
catch err
if ~bmexception(err)
rethrow(err);
end
handles.machine.running = false;
errDisplay(hObject, err.message);
end
running = handles.machine.running;
guidata(hObject, handles);
updateDisplays(handles);
function updateDisplays(handles)
updateMemDisplay(handles.mempanel);
updateRegDisplay(handles.regpanel);
%---------------------- Step button ---------------------------------------
function stepbutton_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
function stepbutton_Callback(hObject, eventdata, handles)
stepDisplay(hObject);
%---------------------- Reset & Run button --------------------------------
function resetrunbutton_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
ud.background1 = get(hObject, 'BackgroundColor');
ud.string1 = get(hObject, 'String');
ud.background2 = ud.background1*0.7;
ud.string2 = 'Halt';
set(hObject, 'UserData', ud);
function resetrunbutton_Callback(hObject, eventdata, handles)
runcpu(hObject, handles, true);
function runcpu(hObject, handles, reset)
runbutton = handles.resetrunbutton;
buttonud = get(runbutton, 'UserData');
if handles.machine.running
if reset % only take notice of run/reset/halt button
handles.machine.running = false;
guidata(hObject, handles);
end
else
if reset
machine = resetReg(handles.machine);
machine.pc = 0;
handles.machine = machine;
guidata(hObject, handles);
updateDisplays(handles);
end
errDisplay(hObject, '');
handles.machine.running = true;
guidata(hObject, handles);
ud = get(get(hObject, 'Parent'), 'UserData');
set(runbutton, 'BackgroundColor', buttonud.background2, ...
'String', buttonud.string2);
pause(ud.delay);
while stepDisplay(hObject)
drawnow;
ud = get(get(hObject, 'Parent'), 'UserData');
pause(ud.delay);
end
set(runbutton, 'BackgroundColor', buttonud.background1, ...
'String', buttonud.string1);
end
%---------------------- Continue button -----------------------------------
function contbutton_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
function contbutton_Callback(hObject, eventdata, handles)
runcpu(hObject, handles, false);
%---------------------- Speed slider --------------------------------------
function speedtext_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
function slider1_Callback(hObject, eventdata, handles)
panel = get(hObject, 'Parent');
ud = get(panel, 'UserData');
ud.delay = ud.maxdelay * (1 - get(hObject, 'Value'));
set(panel, 'UserData', ud);
function slider1_CreateFcn(hObject, eventdata, handles)
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor',[.9 .9 .9]);
end
% min and max set to 0 and 1 in Guide
ud = get(get(hObject, 'Parent'), 'UserData');
value = 1 - ud.delay/ud.maxdelay;
set(hObject, 'Value', value);
%---------------------- Bitmap display ------------------------------------
function bitmappanel_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
set(hObject, 'Units', 'pixels');
pos = get(hObject, 'Position');
panelsize = pos(3:4) - [150 20]; % allow for title encroachment and buttons
margin = 10;
imsize = 32 * floor((min(panelsize)-margin)/32);
impos = [(panelsize-imsize)/2 imsize imsize];
a = axes( ...
'Parent', hObject, ...
'Visible', 'off', ...
'Units', 'pixels', ...
'Position', impos, ...
'Xlim', [0.5 32.5], ...
'Ylim', [0.5 32.5]);
ud.image = image( ...
'Parent', a, ...
'Clipping', 'off', ...
'CData', 2 + zeros(32, 32, 'uint8'), ...
'Xdata', [1 32], ...
'YData', [32 1]);
ud.colourmap = [0 0 0; 1 1 1; 0.8 0.8 0.8];
ud.on = false;
set(hObject, 'UserData', ud); % figure puts this into gui handles
function bitmaptoggle_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
function bitmaptoggle_Callback(hObject, eventdata, handles)
if isequal(get(hObject, 'Value'), get(hObject, 'Max'))
handles.bitmapDisplay.on = true;
guidata(hObject, handles);
bitmapDisplay(hObject);
else
handles.bitmapDisplay.on = false;
im = get(handles.bitmapDisplay.image, 'CData');
im(:) = 2;
set(handles.bitmapDisplay.image, 'CData', im);
guidata(hObject, handles);
end
function saveDisplay_CreateFcn(hObject, eventdata, handles)
defaultFontSize(hObject);
ud.file = '';
set(hObject, 'UserData', ud);
function saveDisplay_Callback(hObject, eventdata, handles)
if handles.bitmapDisplay.on
errDisplay(hObject, '');
try
saveDisplay(hObject);
catch ME
errDisplay(hObject, ['Display save failed:' ME.message]);
return;
end
else
errDisplay(hObject, 'Display not switched on');
end
%---------------------- Utilities -----------------------------------------
function b = bmexception(err)
b = isequal(1, strmatch('bmachine', err.identifier));
function defaultFontSize(hObject)
% because guide insists on setting a fixed value
set(hObject, 'FontSize', 'default'); % because guide sets it to a fixed value