I have a TextArea that shows the conversation from selected chat room. For valueCommit event I use: verticalScrollPosition = maxVerticalScrollPosition; And it works fine scrolling text to the bottom. However in one case it doesn't work as expected. There's verylittle text, so TextArea has no scrollbar and then I put a lot of text and a scrollbar is necessary. The text is scrolled almost to the bottom (still a few lines need to be scrolled down). I am pretty sure it gets maxVerticalScrollPosition as if there was no scrollbar. So the question is how can I wait with updating verticalScrollPosition with respect to TextArea's new size (that is now with a scrollbar). I tried calling validateSize and other methods that start with 'validate' but unfortunately with no luck. I also tried the old trick of putting caret at the end of text. So the TextArea's scrollbar makes a difference when getting maxVerticalScrollPosition and I need to update verticalScrollPosition once all measurements are done.
I forgot to mention. I use htmlText.
In the comments of the answer you accepted you mentioned a more elegant solution. Yeah, a timer probably isn't the best option -- you have eventListener cleanup if you remove the component from the stage; if you use the component more than once, you have another timer instance; etc., etc.
If you don't have a lot of post-commit-property actions, the quickest solution would be a call later on the setter of text or htmlText
override public function set text(value:String):void
{
super.text = value;
callLater( scrollToEndAfterTextCommitted );
}
protected function scrollToEndAfterTextCommitted():void
{
this.verticalScrollPosition = this.maxVerticalScrollPosition;
}
I hope that helps.
Best of luck!
Assuming the issue is fixed after you add additional text again, you could probably get by using a Timer, or a call to setTimeout and have the verticalScrollPosition = maxVerticalScrollPosition called a fraction of a second later and see if that fixes it.
Related
I'd like to force a redraw over a QPlainTextEdit widget, because my highlighting rules changed. However, all lines and blocks aren't redrawn, respecting the new rules.
This is true because if I modify a line, the correct highlighting is applied, and I am happy. But I cannot force-modify each block to see any change!
Is there a way to force a redraw? I tried update() and similars, but nothing seems to work.
Thanks!
QPlainTextEdit inherits QAbstractScrollArea, so its content is located in viewport widget. Try this:
text_edit->viewport()->update();
You have to call QSyntaxHighlighter::rehighlight() to apply the new highlighting rules to the whole document.
You can try:
text_edit->repaint();
In my case simply calling rehighlight don't update view. In my case i want update highlight when cursor moves so:
void MyHighlighter::onSelectionChanged(int start, int end)
{
_visibleCursor.setPosition(end);
document()->documentLayout()->updateBlock(_visibleCursor.block());
rehighlightBlock(_visibleCursor.block());
}
Is there a way to stop a label control that is not visible from taking up space on a form?
server side:
label.Attributes["style"] = "display:none";
or
label.Visible = false;
or, client-side (css):
#label-id { display: none; }
Set it's visibility to hidden through CSS. Or set it through the code behind to false. From the code behind a false setting should cause it to not be rendered at all.
Optionally, replace the label with a literal control and only emit something to it when you need to.
2 good answers already, so just a couple of notes:
Using Visible=false at the server-side is usually better since that will not output any HTML at all, as opposed to CSS which will output it but just hide it. Unless of course you need it there so you can unhide client-side.
The label itself usually doesn't add any space, it is the white-space before/after it that might, so yet another option (if you work in HTML source view 99% of the time like I do) is to remove any white-space before/after the control. Not as robust as the other options since it could be easy to get that white-space back by mistake (especially if the IDE does it for you while working in design view). Just thought I'd mention it, since this can be good to know if you want the label VISIBLE but don't want the "extra space".
Background:
I am doing some UI work where I allow the user to programatically add and resize controls on a canvas.
Problem:
When resizing a combo box through AS the dropdown stays at the same width as the first time it drops down. So user places combo box on the page, clicks the down arrow, sees the options, selects an option or clicks down arrow again to close, resizes the width of the drop down, clicks the down arrow. Now drop down is the same width as original.
Have tried simple things like setting the width of the dropdown specifically and invalidating display list but it still doesn't work.
Example:
Code Example pending
While trimming my code down to an example I solved my problem. A combobox has a dropdownWidth property. I was trying to set this myComboBox.dropdownWidth = newWidth, which doesn't work (not entirely sure why, didn't dig into the SDK). However if I change my code to myComboBox.dropdown.width = newWidth it actually goes to the dropdown element and re-sizes it directly which does work.
comboBox.dropdown.width did not work for me. I had to use
comboBox.dropdown.percentWidth = 100;
It seems to work without having to call invalidateSize()
In the ComboBox, overriding the set dataProvider and performing the following seemed to work, because the dataProvider field is bound to the collectionChange event.
ComboBox.calculatePreferredSizeFromData(count:int):Object
override public function set dataProvider(value:Object):void {
super.dataProvider = value;
var size:Object = calculatePreferredSizeFromData(dataProvider.length);
this.dropdownWidth = size.width;
this.dropdown.width = this.dropdownWidth;
this.invalidateSize();
}
I have an HBox with width=500.
I actually want to add two arrows buttons that will scroll the contents of the HBox.
But when I turn HBox's scroll policy to off, I can't scroll it programmatically using horizontalScrollPosition.
What should i do now?
Thanks
I've hacked together this custom HBox that you could use. Simply set horizontalScrollPolicy to either "on" or "auto". I really haven't tested it all that much, works for a simple test I did...
public class CustomHBox extends HBox
{
override public function validateDisplayList():void
{
super.validateDisplayList();
if (horizontalScrollBar)
horizontalScrollBar.visible = false;
}
}
Scroll bars will not be displayed when scrollPolicy is turned off.
I think for what you want, you want to subclass ScrollBar make it look and feel the way you would like, then set it on your Container.horizontalScrollBar
I'm no Flex expert, but this is possible without too much trouble (using Flex SDK 3.2, anyway). You're right - when you turn off the horizontalScrollPolicy, the maxHorizontalScollPosition is set to 0, UNLESS you specify both a width value AND a maxWidth value. Then, maxHorizontalScrollPosition will again contain a useable value, and you'll be able to programmatically set the horizontalScrollPosition.
I have a component composed of two parts, let's say two Hbox A and B in a Vbox.
On a specific call I want to:
- Hide B with B.visible = false
- setStyle("borderSkin", FooBorderOn);
The problem is that the border get drawn before the resizing of the parent Vbox happen,
so i end up with a border Around the Vbox with B invisible :
.....................
. A .
. .
. .
. .
. BLANK SPACE .
.....................
I would like the border to et around the next updated size of the vbox.
Is there something like "do that afer redraw" ? in flex ?
Thanks a lot
Take a look at the callLater method. This will postpone a method call until the next frame update.
It was callLater ... I had it in my memory somewhere
Even if you hide the VBox, HBox B is still there. I would shrink the height of the VBox, set the VerticalScrollPolicy to false (so that the scroll bar won't show), or just plain remove the HBox from the VBox (myVBox.removeChild () ).
There are several ways to postpone actions. If you're developing a UI component yourself, take a look at invalidateProperties / commitProperties. This is a mechanism to not get stuck in update loops: you mark a property to be updated (usually by storing it in a temp var and/or adding a xxxChanged Boolean) and call invalidateProperties(). Flex will then call commitProperties() a bit later - accumulating several changes which might affect each other - where you can do your actual change.
callLater would also be an option, though usually it's not as "later" as one would think :)
(It's the next screen refresh, which could happen quite soon, even before other queued actions)
However in your case, from your description, I think you just missed the "includeInLayout" property. Containers will decide to display (visible) or make room for (includeInLayout) for objects based on those two, separate properties. See also Preventing layout of hidden controls.