Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
"hide" GUI uicontrol using slider

Subject: "hide" GUI uicontrol using slider

From: Rachel Laughs

Date: 26 Apr, 2010 16:44:05

Message: 1 of 7

I'm trying to create a vertical scrollbar effect in my programmatic GUI, using 2 uipanels and a vertically positioned slider. This idea is based off of an old thread here:
http://www.mathworks.com/matlabcentral/newsreader/view_thread/272337

The idea is that there is a uipanel which creates the space the user can see. A second panel is larger than the first panel, and is its child, causing the "overflow" of this second larger panel to be hidden from the user's eye.
An independent slider has a callback that adjusts the second panel's height, so that its content looks like it's passing through the 1st panel (vertically scrolling effect)

Problem: this only works with like axes and images, but uicontrols seem to remain visible no matter what. Any suggestions for achieving my desired effect if i want to use uicontrols?

(Also, I've considered ditching use of uicontrol just because i can't figure this out, but I DO have text that would need to scroll. Is there something besides text() that could do this, since isn't text() only available for inside an axes?)

Thank you!!


and here is working sample code:

===============
function testScrollPanel()
%Creates the figure. Arbitary size
S.fig = figure('units','pix','position',[300 150 900 900]);

%visiblePanel: Only content inside this area should be visible
visiblePanelPos = [10 250 500 500];
S.visiblePanel = uipanel('units','pix','position',visiblePanelPos,...
        'backgroundcolor',[0 0 0]);

%Content panel. this is what actually "scrolls"
        % used this to create it's position vector:
        scrollPanelHeight = 1000 ;
        scrollPanelHeightPos = -scrollPanelHeight+visiblePanelPos(3);
        S.scrollPanelPos = [-1 scrollPanelHeightPos 500 scrollPanelHeight];
    S.scrollingPanel = uipanel('parent',S.visiblePanel,...
            'units','pix','Position',S.scrollPanelPos,...
            'backgroundcolor',[.9 .9 .9]);
        
%Slider that acts as vertical scrollbar
    S.scrollMax = 4;
    S.vertScroll = uicontrol('Style', 'slider',...
            'Parent', S.visiblePanel,...
            'Units', 'normalized',...
            'Value',S.scrollMax,'Min',1,'Max',S.scrollMax,...
            'SliderStep',[1/(S.scrollMax-1) 1/(S.scrollMax-1)],...%integers
            'Position', [.96, 0, .04, 1]);
        
%Just an arbitrary, test content for scollingPanel.
    S.axes = axes('units','pix','parent',S.scrollingPanel,...
            'position',[150 1000-100 25 25]);
        
%Set the scrolling callback with the current structure:
    set(S.vertScroll,'callback',{@scroll,S});

end %function verticalScrollingPanel (creating components)


%% Callback for the vertical slider:
function scroll(varargin)
S = varargin{3}; %get structure
originalScrollPanelPos = S.scrollPanelPos;

%Determine height amount to scroll:
%Here is set to scroll half the visible amount
    scrollHeightPos = get(S.visiblePanel,'pos');
    scrollHeight = scrollHeightPos(3)/2 ;

%current scrollbar value:
val = get(S.vertScroll,'Value');
         
%Determine amount to adjust the scrollPanel's position:
%(val-100) so that initial value is considered = 0, not 1
%( -100 because initial top-position is actually max-slider value!)
change = [0, (val-S.scrollMax)*scrollHeight, 0, 0];
        
%Adjust the scrollingPanel's position:
set(S.scrollingPanel, 'Units', 'pix', ...
            'Position', originalScrollPanelPos-change);
      
end %callback scroll

======

Subject: "hide" GUI uicontrol using slider

From: Rachel Laughs

Date: 26 Apr, 2010 16:56:05

Message: 2 of 7

Should I just make all uicontrols be 'visible','off' and then include some sort of check in my slider callback that checks the positions of each child uicontrol element of scollPanel to see if its height is within range of the current "view", and if so, set that object's visible property to 'on'?

That just seems rather tedious and inappropriate..

Looking forward to feedback on this, thanks!



(Oh, and also in one of the comments of above code i said "val-100" in the slider callback. that's incorrect, "100" should refer to the slider max)

Subject: "hide" GUI uicontrol using slider

From: matt dash

Date: 26 Apr, 2010 20:21:05

Message: 3 of 7

"Rachel Laughs" <remove.thisrachellaughs@gmail.com> wrote in message <hr4gj5$4vm$1@fred.mathworks.com>...
> Should I just make all uicontrols be 'visible','off' and then include some sort of check in my slider callback that checks the positions of each child uicontrol element of scollPanel to see if its height is within range of the current "view", and if so, set that object's visible property to 'on'?
>
> That just seems rather tedious and inappropriate..
>
> Looking forward to feedback on this, thanks!
>
>
>
> (Oh, and also in one of the comments of above code i said "val-100" in the slider callback. that's incorrect, "100" should refer to the slider max)


Ohhhh I know all about this problem. The short answer is, no, there is no way to partially hide a uicontrol behind anything other than another uicontrol, and even that is unpredictable. Uicontrols are basically java swing controls and they are all drawn in a layer that is above the layers used by normal matlab graphics objects. Similarly you can't partially hide an mtable or an mtree, cause those are also java objects.

You can do what you suggested and have them discretely appear/disappear as they cross the border, but that can make it look amateurish. Another alternative is to draw everything using matlab graphics objects in an axes.

Like you said before, text has to be in an axes, but it's easy enough to make an axes that fills the whole uipanel (set the axes visibility to off) and set it's x/y limits to the height/width of your panel, then plot text into that instead of using the uicontrol text.

Editable text is a little harder, but you can make text created using the "text" command editable, and with a little work using it's buttondownfcn you could probably make a very convincing text box.

For buttons, you can just draw a rectangle with its hittest on and use it's buttondownfcn like you would use the callback of a button. Or even better, make an image that shows the bevel around the button by changing the colors of the edge pixels

Pop-up menus are probably the hardest... i havent come up with a good solution for these yet (but i havent tried)

For scroll bars, I have code that draws fully working scrollbars (that look completely authentic) out of axes and images. I've been meaining to put it on the file exchange, and i can send it to you if you'd like, but be aware that it uses a different way of calculating the value than the matlab sliders so it might take a little work to implement (which I think is much more logical if you're using them as scrollbars, less so if you're using as a replacement for a jslider). Of course you'd only need this for 3-level deep scrolling.

I'm working on a table made out of lines/text, but it's harder than it sounds and not ready to distribute

...I realize none of these are easy to implement, but hey, if you want results....

Subject: "hide" GUI uicontrol using slider

From: Rachel Laughs

Date: 26 Apr, 2010 21:10:06

Message: 4 of 7

"matt dash" <n.a@mail.com> wrote in message <hr4sjh$f78$1@fred.mathworks.com>...
> Ohhhh I know all about this problem. The short answer is, no, there is no way to partially hide a uicontrol behind anything other than another uicontrol, and even that is unpredictable. Uicontrols are basically java swing controls and they are all drawn in a layer that is above the layers used by normal matlab graphics objects. Similarly you can't partially hide an mtable or an mtree, cause those are also java objects.


Oh my goodness, your post made me laugh - how wonderful to know that I've been working on something that is impossible! Haha! But i'm glad to see that others have experienced this before.

Thank you very much for the suggestions. I will keep all of this in mind as I think about how to re-design my GUI to keep all the controls in a separate panel (lots of pop up menus) and what I can keep in the scrollable area. At the least it will have to be axes and images. I've never drawn any graphics objects before, so this will be an interesting new area to get into..

But yes, I would love to see how you did your "scrollbars"! You may contact me at my sneakily posted email if you don't plan on posting it on FEX yet. Thanks again for sharing your experience with this!!

Subject: "hide" GUI uicontrol using slider

From: Yair Altman

Date: 27 Apr, 2010 00:25:22

Message: 5 of 7

"matt dash" <n.a@mail.com> wrote in message <hr4sjh$f78$1@fred.mathworks.com>...
> Ohhhh I know all about this problem. The short answer is, no, there is no way to partially hide a uicontrol behind anything other than another uicontrol, and even that is unpredictable. Uicontrols are basically java swing controls and they are all drawn in a layer that is above the layers used by normal matlab graphics objects. Similarly you can't partially hide an mtable or an mtree, cause those are also java objects.
>
> You can do what you suggested and have them discretely appear/disappear as they cross the border, but that can make it look amateurish. Another alternative is to draw everything using matlab graphics objects in an axes.
[snip]


You can take a snapshot image of all the uicontrols and replace the controls with their image. Something similar is done by Matlab when it prints figures. This way, the uicontrols are really small images that can indeed be partially obscured. If you only hide the controls during scrolling and unhide them immediately afterwards, you should be ok with user interaction (mouse clicks etc.). You can use my ScreenCapture utility on the FEX to get the image of any specified uicontrol (there might be alternatives - I haven't checked).

It's not simple to do correctly, but it's also not rocket science.

BTW: I think that a generic scrollbar utility using the ideas in this thread could be a blockbuster on FEX... Anyone pick the challenge?

Yair Altman
http://UndocumentedMatlab.com

Subject: "hide" GUI uicontrol using slider

From: matt dash

Date: 27 Apr, 2010 16:46:05

Message: 6 of 7

"Yair Altman" <altmanyDEL@gmailDEL.comDEL> wrote in message <hr5ati$nv8$1@fred.mathworks.com>...
> "matt dash" <n.a@mail.com> wrote in message <hr4sjh$f78$1@fred.mathworks.com>...
> > Ohhhh I know all about this problem. The short answer is, no, there is no way to partially hide a uicontrol behind anything other than another uicontrol, and even that is unpredictable. Uicontrols are basically java swing controls and they are all drawn in a layer that is above the layers used by normal matlab graphics objects. Similarly you can't partially hide an mtable or an mtree, cause those are also java objects.
> >
> > You can do what you suggested and have them discretely appear/disappear as they cross the border, but that can make it look amateurish. Another alternative is to draw everything using matlab graphics objects in an axes.
> [snip]
>
>
> You can take a snapshot image of all the uicontrols and replace the controls with their image. Something similar is done by Matlab when it prints figures. This way, the uicontrols are really small images that can indeed be partially obscured. If you only hide the controls during scrolling and unhide them immediately afterwards, you should be ok with user interaction (mouse clicks etc.). You can use my ScreenCapture utility on the FEX to get the image of any specified uicontrol (there might be alternatives - I haven't checked).
>
> It's not simple to do correctly, but it's also not rocket science.
>
> BTW: I think that a generic scrollbar utility using the ideas in this thread could be a blockbuster on FEX... Anyone pick the challenge?
>
> Yair Altman
> http://UndocumentedMatlab.com


Rachel - I sent you an email with the files. Let me know if you didnt get it.

Yair - Looks like your ScreenCapture is similar (though much more extensive) to my getscreen. I never thought of using it to try to solve the uicontrol problem. I agree a scroll pane utility would be nice to have... I wish I had the time to make a good one.

Subject: "hide" GUI uicontrol using slider

From: Sergey

Date: 13 Apr, 2013 16:54:08

Message: 7 of 7

Maybe it'll be useful:

f=figure('MenuBar','none','NumberTitle','off','Units','pixels','Position',[200, 100, 600, 400]);

p1=uipanel('Parent', f,'Units','pixels','Position',[ 0, 0,600,400]);
p2=uipanel('Parent',p1,'Units','pixels','Position',[ -1,-1,300,400]);

uicontrol('Parent',p1,'Style','frame','Position',[297 0 300 399],'ForegroundColor',[0.502 0.502 0.502]);
uicontrol('Parent',p1,'Style','frame','Position',[298 0 299 398],'ForegroundColor',[ 1 1 1]);

uicontrol('Parent',p1,'Style','pushbutton','Position',[310 175 100 50],'String','BBBBBBB');
uicontrol('Parent',p2,'Style','pushbutton','Position',[250 175 100 50],'String','AAAAAAA');

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us