본문 바로가기

Enginius/Matlab

MATLAB add slider and button to figure

Adding a slider and a play/pause button to a figure for playback purposes.

 

Main script

더보기

fig = figure(1);
set_fig_size(fig,[0.5,0.5,0.25,0.3]);
h_title = title('Slider demo','fontsize',20,'fontname','consolas','interpreter','none');

% Add slider to figure
slider_max = 100;
HZ = 30;
sb = add_slider_and_button_to_figure(fig,slider_max,HZ,'y_offset',0.005,'y_height',0.05,...
    'sliderstep',1/40,'fontsize',12,'VERBOSE',0);

while ishandle(fig)
    sb = process_slider_and_button(sb); % process slider and button
    h_title.String = sprintf('PLAY:[%d] sec_wall:[%.2f]s sec_sim:[%.2f]s tick:[%d/%d]',...
        sb.PLAY,sb.sec_wall,sb.sec_sim,sb.tick_slider,sb.slider_max);
    drawnow limitrate;
end

 

add_slider_and_button_to_figure.m

더보기

function sb = add_slider_and_button_to_figure(fig,slider_max,HZ,varargin)
global g

% Parse options
p = inputParser;
addParameter(p,'y_offset',0.005);
addParameter(p,'y_height',0.06);
addParameter(p,'sliderstep',max(1/slider_max,1/100));
addParameter(p,'fontsize',15);
addParameter(p,'VERBOSE',1);
parse(p,varargin{:});
y_offset = p.Results.y_offset;
y_height = p.Results.y_height;
sliderstep = p.Results.sliderstep;
fontsize = p.Results.fontsize;
VERBOSE = p.Results.VERBOSE;

% Options
sb.VERBOSE = VERBOSE;

% Add slider
sb.h_slider = uicontrol('parent',fig,'style','slider','units','normalized',...
    'sliderstep',[sliderstep,sliderstep],...
    'BackgroundColor', [0.5,0.7,0.9,0.5],...
    'position',[0.04, y_offset, 0.82, y_height],'min',1,'max',slider_max);
addlistener(sb.h_slider,'Value','PostSet',@cb_slider);
g.slider_val = sb.h_slider.Min;
sb.h_slider.Value = g.slider_val; % make sure to update slider value
sb.slider_max = slider_max; % slider max

% Add play button 
sb.h_play_button = uicontrol('parent',fig,'style','pushbutton','units','normalized',...
    'position',[0.8615, y_offset, 0.05, y_height],'string','PLAY','fontsize',fontsize,...
    'BackgroundColor', [0.5,0.7,0.9],'CallBack',@cb_play_button);
g.play_button_pressed = false;
sb.PLAY = false; % default is to not play
sb.HZ = HZ;
sb.iclk = clock; % initial clock 

% Add text box
sb.h_textbox = uicontrol('parent',fig,'style','edit','units','normalized',...
    'position',[0.915, y_offset, 0.05, y_height],'string','1.00',...
    'fontsize',fontsize,'BackgroundColor', [0.5,0.7,0.9], 'CallBack', @cb_textbox);
g.textbox_string = '1.00';
sb.SPEED = 1.00;

process_slider_and_button.m

더보기

function sb = process_slider_and_button(sb)
global g

if g.play_button_pressed % if button pressed
    if sb.VERBOSE
        fprintf('Play button pressed.\n');
    end
    g.play_button_pressed = false;
    sb.PLAY = ~sb.PLAY; % toggle play
    if sb.PLAY
        pause(0.5); % little pause here
        sb.iclk = clock;
        sb.h_play_button.BackgroundColor = [0.9,0.3,0.15];
        sb.h_play_button.String = 'PAUSE';
        % Get speed based on edit box
        sb.SPEED = str2double(g.textbox_string);
        if isnan(sb.SPEED)
            sb.SPEED = 1.0;
        end
        % Update edit box
        sb.h_textbox.String = sprintf('%.2f',sb.SPEED);
    else
        sb.h_play_button.BackgroundColor = [0.5,0.7,0.9];
        sb.h_play_button.String = 'PLAY';
    end
end

if sb.PLAY % play
    esec = etime(clock, sb.iclk); % elapsed time in sec since start
    tick_estimated = round(esec*sb.HZ*sb.SPEED)+1; % estimated tick based on esec and SPEED
    g.slider_val = tick_estimated;
    sb.h_slider.Value = g.slider_val; % make sure to update slider value
    if g.slider_val > sb.slider_max
        g.slider_val = sb.h_slider.Min; % reset slider
        sb.h_slider.Value = g.slider_val; % make sure to update slider value
        sb.PLAY = false; % stop playing
        sb.h_play_button.BackgroundColor = [0.5,0.7,0.9];
        sb.h_play_button.String = 'PLAY';
    end
end

sb.tick_slider = round(g.slider_val);
sb.sec_sim = sb.tick_slider / sb.HZ; % simulator time
sb.sec_wall = etime(clock, sb.iclk); % wall-clock time

set_fig_size.m

더보기

function fig = set_fig_size(fig,fig_sz,varargin)
%
% Set figure size based on current screen size
%

% Parse options
p = inputParser;
addParameter(p,'monitor',1);
parse(p,varargin{:});
monitor = p.Results.monitor;

sz = get(0, 'ScreenSize'); 
mp = get(0, 'MonitorPositions');
if monitor == 2
    sz(3:4) = mp(2,3:4);
end

fig_pos = [fig_sz(1)*sz(3),fig_sz(2)*sz(4),fig_sz(3)*sz(3),fig_sz(4)*sz(4)];
set(fig,'Position',fig_pos); 

% Take care of stupid MATLAB modifications of toolbar..
addToolbarExplorationButtons(gcf);
ax = gca;
% ax.Toolbar.Visible = 'off'; % Turns off the axes toolbar
ax.Toolbar = []; % Removes axes toolbar data

 

cb_slider.m

더보기

function cb_slider(~, eventdata)
global g

slider_val = get(eventdata.AffectedObject, 'Value');
g.slider_val = slider_val;

cb_play_button.m

더보기

function cb_play_button(~, ~)
global g

g.play_button_pressed = true;

cb_textbox.m

더보기

function cb_textbox(h,~)
global g

g.textbox_string = get(h,'string');