Flex: Prevent scrollbar from covering content when automatically displayed - apache-flex

I have a canvas in Flex that shall be able only to be scrolled in vertical direction, so I set the attributes of the canvas as follows:
verticalScrollPolicy="auto" horizontalScrollPolicy="off"
The problem here is that the vertical scrollbar covers the content when it appears - altough there is enough horizontal room left. I would have expected that the content size would have been automatically adjusted.
When setting the vertical scroll policy to "on", no content is covered also.
In case I set both scroll policies to 'auto' I also get a horizontal scroll bar just for scrolling to the area that is covered by the vertical scroll bar.
Is there a workaround how I can relayout the content of the canvas when the vertical scroll bar is shown so that it does not cover any content?

It's a bug. See Flex verticalScrollPolicy bug for a workaround.

Just a side note regarding this issue: it's actually not a bug, but known (and intended?) behaviour:
"Flex considers scroll bars in its sizing calculations only if you
explicitly set the scroll policy to
ScrollPolicy.ON. So, if you use an
auto scroll policy (the default), the
scroll bar overlaps the buttons. To
prevent this behavior, you can set the
height property for the HBox container
or allow the HBox container to resize
by setting a percentage-based width.
Remember that changing the height of
the HBox container causes other
components in your application to move
and resize according to their own
sizing rules."
-- From Sizing Components in the Flex 3 help, under "Using Scroll bars"

I had to find this workaround Flex ScrollPolicy.AUTO Not Good Enough which solved this issue, because Flex verticalScrollPolicy bug workaround did not work for me.

on vbox or another component based on Container, i solved that problem like that.
Wrong:
<mx:VBox width="100%" height="100%"
verticalScrollPolicy="auto" horizontalScrollPolicy="off">
<mx:Repeater dataProvider="{hede}">
<custom:RenderItem ........../>
</mx:Repeater>
</mx:VBox>
there is no scroll bar
Working version:
<mx:VBox width="100%" height="100%"
**minHeight="1"** horizontalScrollPolicy="off">
<mx:Repeater dataProvider="{hede}">
<custom:RenderItem ........../>
</mx:Repeater>
</mx:VBox>

I'm, too. I usually have some problems with the verticalScrollBar in Flex, so I prefer to use the browser's scrollbar for scrolling the complete application. You can found a workaround here: How to Resize the Flex Stage and Use the Browser Scrollbar.
The code I use:
In Flex:
ExternalInterface.call("setInitialFlashHeight", this.height);
In my HTML (JavaScript):
function setInitialFlashHeight(newHeight) {
document.getElementById('my_flash').style.height = newHeight + 'px';
}
And if you want to add (or remove) some height:
function addFlashHeight(height) {
var divHeight;
var obj = document.getElementById('my_flash');
if (obj.offsetHeight) {
divHeight = obj.offsetHeight;
} else if (obj.style.pixelHeight){
divHeight = obj.style.pixelHeight;
}
var newHeight = divHeight + height;
document.getElementById('my_flash').style.height = newHeight + 'px';
}
To remove, you use "-" instead of "+".

Related

Creating a scrollbar for a s:Panel in Flex

I am new to flex development.
In my proj, I have created a panel using this
<s:Panel x="46" y="193" width="75%" height="75%" dropShadowVisible="false">
what happens here is that, the part of the panel goes out of the browser view and I need to include scrollbars so that I can scroll to the right end and bottom end of the panel itself.
I would like to know how I can add scrollbars to the s:panel.
wrap it with a scroller! ;)
<s:Scroller>
...your content to scroll...
</s:Scroller>
In order to use your own scrollbars you need three things:
1. Your main (parent) container should implement IViewport (any subclasses of s:Group would do)
2. Set container's property 'clipAndEnableScrolling' to 'true'.
3. You assign this main container as 'viewport' property of your scrollbar.
HTH,
FTQuest

Horizontal scrollbar hides content of ApplicationControlBar

I have an application control bar at the bottom of my Flex application (with attributes width="100%", dock="false", left="0", bottom="0", height="50"). It contains a lot of elements (like buttons and labels). The width of the SWF is the width of the browser.
When the user makes the width of the browser window smaller, after a certain point, the components on the application control bar gets "squished": they are forced on top of each other. And so, it becomes confusing and ugly. To ensure that that doesn't happen, I've set the minWidth attribute to a value so that it'll always display the components without them overlapping each other.
But then, a horizontal scrollbar appears and hides the bottom half of the application control bar.
I've googled and I found this article: flex verticalscrollpolicy bug (referenced by this SO question: Flex: Prevent scrollbar from covering content when automatically displayed).
But that seems to apply only to a fixed size component. My component's width is a percentage. Any ideas on how to have the horizontal scrollbar appear and have it not cover up the application control bar?
Thanks!
See if adding the following code to the overriden validateSize method (as in the scrollpolicy bug page you linked to) solves the problem.
if (width < measuredWidth)
{
height = normal-height + height-of-the-horizontal-scrollbar;
}
else
height = normal-height;
(Find the normal height of the application control bar and the scroll bar (trace them out) and use those values).
So this happens when the ApplicationControlBar is fixed at the bottom: bottom=0 and left=0. The easiest solution is to make the bar a lot taller (that'll push the content way higher than the scrollbar height). But that makes it kinda ugly.
So another solution: in the MXML file, I capture the Resize event. And in that function, I do this:
if (width < bar.minWidth) // width is the width of the SWF
{
bar.height = ORIGINAL_SIZE + 10;
hbox.setStyle("verticalAlign", "top");
hbox.setStyle("verticalCenter", -10);
} else {
// normal case
box.height = ORIGINAL_SIZE;
hbox.setStyle("verticalAlign", "middle");
hbox.setStyle("verticalCenter", 0);
}
And the horizontal scrollbar doesn't hide the content anymore! Also, the Resize event doesn't get triggered when the bar has a minWidth & the width of the stage is less than that.
I had this come up today and I slightly tweaked sri's if statement like this:
if (buttonContainer.horizontalScrollbar)
{
// Change height & style properties
}
else
{
// Return to original properties.
}

Trouble with Flex scrolling

I have the following code in my flex project.
<mx:Canvas id="scroller" styleName="myCanvas" width="635" horizontalScrollPolicy="off" y="60" height="370" >
<mx:Canvas id="thumbContent" width="635" verticalScrollPolicy="off"
horizontalScrollPolicy="off" y="0" backgroundColor="#00ff00"
backgroundAlpha="0" height="370"/>
</mx:Canvas>
</mx:Canvas>
I want to dynamically add different items to thumbContent canvas and use scroller canvas to scroll. I see than the height of thumbContent bigger than 7977 it truncate from scrolling.
So - I see the scroller canvas with empty space on top. Then I scroll to bottom - I see the content of thumbContent and at bottom scrolling I see empty space too.
It looks like thumbContent is under hidden mask, is this correct?
Looks like you want thumbContent to expand dynamically as you add content. In this case, you need to remove the height attribute from thumbContent, otherwise it will want to cram more content into it than it can hold, especially if the H and V scroll bars are off.
Keep the height attribute for scroller, though, because that's what you want to use to scroll (fixed dimensions).
Also, use percentages in your application. make thumbContent width="100%" if you want it to fill up the entire width of scroller.

Flex Bipmapdata and Scrolled Canvas

I have a canvas wich is a drawing area. This canvas can be scrolled horizontally and vertically.
I am trying to make a screenshot of the whole canvas, this include visible and scrolled parts.
var bmd:BitmapData = new BitmapData(board.width, board.height, false, 0xffffff);
bmd.draw(board);
This would only show me the visible part of the canvas and its scrolling bars :/
How would you solve such a problem ?
Using board.width + board.horizontalScrollPosition wont help in this case.
Thanks a lot.
I think your best bet is to nest canvases. One canvas is a fixed size which contains the smaller scrollable area and the other is the full canvas. Something like
<mx:Canvas id="boardContainer" width="800" height="600">
<mx:Canvas id="board" width="800" height="1200" />
</mx:Canvas>
That way you have a reference to a canvas that isn't masked and you should be able to take a bitmapData of the entire area.

How do I visually "break out" of a Container in Flex?

Here's my problem - I have some code like this:
<mx:Canvas width="300" height="300">
<mx:Button x="800" />
</mx:Canvas>
So the problem is that the Button inside the canvas has an x property way in excess of the Canvas's width - since it's a child of the Canvas, the Canvas masks it and creates some scrollbars for me to scroll over to the button.
What I'd like is to display the button - 800 pixels to the left of the Canvas without the scrollbars while still leaving the button as a child of the Canvas. How do I do that?
I figured it out - apparently the Container has a property called clipContent - here's the description from Adobe:
Whether to apply a clip mask if the positions and/or sizes of this container's children extend outside the borders of this container. If false, the children of this container remain visible when they are moved or sized outside the borders of this container. If true, the children of this container are clipped.
If clipContent is false, then scrolling is disabled for this container and scrollbars will not appear. If clipContent is true, then scrollbars will usually appear when the container's children extend outside the border of the container. For additional control over the appearance of scrollbars, see horizontalScrollPolicy and verticalScrollPolicy.
The default value is true.
So basically - to show the button outside of the bounds of the container I need to do the following:
<mx:Canvas width="300" height="300" clipContent="false" >
<mx:Button x="800" />
</mx:Canvas>
That was easier than I thought it was going to be. :)
Here's the official doc...
You should be able to use the includeInLayout property also, which would allow you to apply it to each child component independently.

Resources