How to prevent truncating the bottom of text in Flex comboboxes? - css

I am currently modifying a flex GUI to give it a new look. I am new to flex but I manage to get most of the work done. However I have a problem with comboboxes: I use a rather big font size and the bottom of some characters is truncated ("g" for example, or any character going under the baseline):
I first thought it was a problem with the component height, but even with a very large height the characters got truncated, with big empty spaces above and under the text.
I looked for a solution on the net but did not find one. Worst: I was not able to find references to my problem though it seems to be an important one. Is there a CSS property to prevent this behavior or do I have to look elsewhere?
edit: I use Flex 3 and Halo/MX components

The combobox component contains an inner TextInput. You have to extend the ComboBox class and modify the height of the textinput to what you need.
For example, lets say you put a font size of 20 and this extended class:
public class MyCb extends ComboBox
{
public function MyCb()
{
addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
}
private function onCreationComplete(e:Event):void {
this.textInput.height = 40;
}
}
Main application:
<mx:VBox width="100%" height="100%">
<mx:ComboBox fontSize="20" >
<mx:dataProvider>
<mx:Object label="goubigoulba"/>
<mx:Object label="goubigoulba"/>
</mx:dataProvider>
</mx:ComboBox>
<local:MyCb fontSize="20" >
<local:dataProvider>
<mx:Object label="goubigoulba"/>
<mx:Object label="goubigoulba"/>
</local:dataProvider>
</local:MyCb>
</mx:VBox>
You will get the following result:

I believe that this is not the Comobox itself, but its internal label. You can try setting paddingBottom, to see if the label will inherit that, but you might have better luck creating your own subClass of label and using it as the textFieldClass.

Related

How to add an icon to an AdvancedDataGrid column header and keep word wrap feature for the text

As stated, I'm trying to obtain column headers consisting of an icon and wrappable text in a flex AdvancedDataGrid.
(EDIT: I forgot to mention an important part of the context: the columns are added dynamically, in actionscript. This apparently changes the behavior.)
I've tried using a custom mxml headerRenderer, like so:
<mx:headerRenderer>
<fx:Component>
<mx:HBox width="100%"
height="100%"
verticalAlign="middle">
<mx:Image source="<image_url>"
width="10%"
height="100%"/>
<mx:Text text="{data.headerText}"
width="90%"
height="100%"/>
</mx:HBox>
</fx:Component>
</mx:headerRenderer>
but for some reason, the text here is truncated instead of wrapped (it works outside of a renderer).
I've also tried creating a subclass of AdvancedDataGridHeaderRenderer and overriding createChildren to add the icon:
override protected function createChildren():void
{
var icon:Image = new Image();
icon.source = <image_url>;
icon.width = 16;
icon.height = 16;
addChild(icon);
super.createChildren();
}
but then, the icon and the text get superimposed.
I'm out of ideas on this. Anyone else?
It worked for me when I removed the height="100%" attribute from mx:Text in your headerRenderer.
UPDATE: it only works like this when I manually stretch the AdvancedDataGrid component. I'll look into how to make it work unconditionally.
When the height of the Text component was set to 100%, it was constrained to its parent HBox's height. Therefore when a word was wrapped and moved to the next line, it wasn't visible because the height of the Text component didn't allow for it to be visible.
If you remove this constraint, Text component's height will be determined dynamically based on its contents, as will headerRenderer's. Also add minHeight to your Text so that it is visible when it's loaded.
Here's the code (I also removed scrollbars because they were showing during resize):
<mx:headerRenderer>
<fx:Component>
<mx:HBox width="100%"
height="100%"
verticalAlign="middle"
horizontalScrollPolicy="off"
verticalScrollPolicy="off">
<mx:Image source="<image_url>"
width="10%"
height="100%"/>
<mx:Text text="{data.headerText}"
width="90%"
minHeight="20"/>
</mx:HBox>
</fx:Component>
</mx:headerRenderer>
In case anyone is interested in how to do this with dynamically created columns, a combination of Hunternif's code for the renderer and some added code on column creation worked for me:
The columns need to have fixed widths and need to be invalidated to inform the AdvancedDataGrid that it needs to rerender:
var cols:Array = [];
for each (...) {
var column:AdvancedDataGridColumn = new AdvancedDataGridColumn();
...
// Fix the width of created columns
column.width = 150;
cols.push(column);
}
grid.columns = cols;
// Invalidate columns so that sizes are recalculated
grid.mx_internal::columnsInvalid = true;
// Take changes into account
grid.validateNow();

Flex 4 UIMovieClip Modify the Width of a Child DisplayObject

I have a collection of UIMovieClip components which reside in an s:HGroup tag. In ActionScript code I am modifying the width of a child clip in one of the UIMovieClips but these changes are not reflected by the s:HGroup.
<s:HGroup id="_buttonGroup">
<uiassets:NavigationTabButtonSWC id="_lobby" />
<uiassets:NavigationTabButtonSWC id="_achievements" />
</s:HGroup>
<fx:Script>
<![CDATA[
protected function init() : void
{
// The HGroup does not pickup this change and so my buttons
// are no longer evenly spaced out and overlap!
_lobby.getChildByName("background").width += 200;
}
]]>
</fx:Script>
Thanks!
There's a few reasons for this. Just changing one child's width doesn't mean it'll change the whole UIMovieClip's width, so you should check that first.
Second, Flex has a very specific way of doing things (called the component lifecycle), which the UIMovieClip doesn't implement so you can't manage the width yourself in the 'measure' function. I'm guessing that you just have other children in your movieclip that doesn't let you resize it all. Try changing the width of the MovieClip itself and it should work. If it doesn't, then there's another problem.

Flex dynamic form height

I'm not sure if this is possible, is there a way to get the <mx:Form> to set its own height based on the position of an element within it?
For example something like this:
<mx:Form height="{submitBtn.y + submitBtn.height}">
<mx:FormItem>... </mx:FormItem>
<mx:FormItem>... </mx:FormItem>
<mx:FormItem>... </mx:FormItem>
<mx:FormItem>
<s:Button id="submitBtn" label="Submit" />
</mx:FormItem>
</mx:Form>
where the form height is dynamically set based on submitBtn's y position and its height.
I tried using Alert.show to show these values and turned out submitBtn.y = 0 and submitBtn.height = 21. height sounds reasonable, but I know the submitBtn.y can't be 0 since it's below several other
Is it possible to set the form height dynamically?
Yes. Do it in the measure method:
private var n:Number = 0;
override protected function measure() : void {
super.measure();
if (submitBtn) {
var fi:FormItem = FormItem(submitBtn.parent);
n = fi.y + fi.height;
}
}
Then just set the height to n.
Edit: I changed this to specify the containing FormItem, not the button, which is what I tested in my own sample code first. You can either get the button's parent or give that FormItem an ID. But this way does work.
your submitBtn.y will always return 0, since it's the y position inside the mx:FormItem element (like the relative y position)
So as I guess you want to set the y position of a form based of the y position of a button inside the form. why do you want that ?
check out the localToGlobal() method available to all children of DisplayObject. It will convert your x,y coordinates to the global x,y. You should be able to use this in your calculations.
I hope that thread is not closed cause I just have had the same problem like you and found the correct solution, so I will try to explain.
Whenever my application starts it reads a file and parse it, containing some information that will fit some forms, and I create them dynamically without specificating any height or width.
I add them to a viewStack like this:
<mx:ViewStack id="viewStack" resizeToContent="true">
</mx:ViewStack>
that is inside a component to show Information for some items, depending the class of the item one of the form is shown fitting the necessary information in.
As you can notice, the viewstack has inside a property resizeToContent that when I select an item from a datagrid, the viewstack changes the selectedIndex (indicating another form) and automatically changing its size resizing to the new content.
If for some reason you need the height of the form, you can use, instead of measure(), the measuredHeight property.
I will add some of the code used for you to understand:
onCreationComplete(){
...
for each (var form:Form in DataModel.getForms())
{
viewStack.addChild(form);
}
...
}

Can't autoscroll a VBox unless height is explicity set(in pixels) in Flex 3

I have a VBox who dynamically adds and removes children programatically. The height is set to 100% and verticalScrollPolicy=auto.
When a user wants to add another child to that Vbox, I want it to autoscroll to the bottom of the VBox since that is where the child is added.
I've tried every solution I could find online, but no matter what, the verticalScrollPosition and maxVerticalScrollPosition are both ALWAYS equal to 0. Even if I manually scroll to the bottom of the VBox and press a button that alerts these numbers.(Even after 'validateNow()' as well).
The only time I can get these numbers to change programmaticaly is when the VBox height is set in pixels, which I don't want since the children all have varying heights.
Plllease tell me that it's possible to set verticalScrollPosition without hard coding the height in pixels? Am I missing something totally obvious here?
You might not be scrolling the VBox, actually; there's a good chance that if your VBox is contained by another container, like a Canvas or the like, and you're adding items to the VBox as you say you are, it's the Canvas that's doing the scrolling, not the VBox -- in which case the VBox would indeed return 0 for its scroll position.
One way or another, you're right -- you have to set the component's height; even constraint-layout settings (e.g., "bottom='10'", etc.) won't work. But if you can manage to set the height of the VBox, either by binding its dimensions somehow to another control or by setting them explicitly as part of a child's appending/creation process, you should be able to accomplish what you're after.
Here's an example of an AIR app I've mocked up to illustrate the example. Basically it just adds randomly sized boxes to a VBox, and scrolls to the bottom of the VBox after each child gets created.
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" verticalScrollPolicy="off" horizontalScrollPolicy="off" width="250">
<mx:Script>
<![CDATA[
import mx.core.Application;
import mx.containers.Box;
import mx.events.FlexEvent;
private function addItem(h:Number):void
{
var b:Box = new Box();
b.width = 200;
b.setStyle("backgroundColor", 0xFFFFFF);
b.height = h;
// Wait for the component to complete its creation, so you can measure and scroll accordingly later
b.addEventListener(FlexEvent.CREATION_COMPLETE, b_creationComplete);
vb.addChild(b);
}
private function b_creationComplete(event:FlexEvent):void
{
event.currentTarget.removeEventListener(FlexEvent.CREATION_COMPLETE, b_creationComplete);
vb.verticalScrollPosition = vb.getChildAt(vb.numChildren - 1).y;
}
]]>
</mx:Script>
<mx:VBox id="vb" top="10" right="10" left="10" height="{Application.application.height - 80}" verticalScrollPolicy="on" />
<mx:Button label="Add Item" click="addItem(Math.random() * 100)" bottom="10" left="10" />
</mx:WindowedApplication>
In this case, the height of the VBox is being bound to the height of its containing component (here, just the Application). Everything else should be pretty self-explanatory.
Hope that helps! Post back if you have any questions.

Flex: Scrolling in datagrids

I have 2 questions about flex datagrids:
How can I scroll it automatically to the bottom when new portion of data arrived to it (e.g. I added new items)
Strange, but seems it doesn't scroll when I use scrolling wheel, is there any trick about it (especially for mac Users)
Thanks in advance
Some changes:
public function scroll():void
{
trace(chatboard.maxVerticalScrollPosition);
chatboard.verticalScrollPosition = chatboard.maxVerticalScrollPosition;
}
<mx:TextArea id="chatboard" x="10" y="10" width="310" height="181" text="{chatMessages}" editable="false" verticalScrollPolicy="on" resize="scroll()"/>
But actually it don't help. The text area is not autoscrolled :(
Seems that 1) scroll is not called after new string is added to chatMessages
I find here that the mouse wheel scrolls the text area by default. Are you looking for a different behavior?
As far as skipping to the end goes:
in your TextArea wire up to the updateComplete and it seems to work as you would like:
<mx:TextArea id="textArea1" liveScrolling="true" updateComplete="textArea1_Changed(event);" />
then
private function textArea1_Changed(event:Event):void {textArea1.verticalScrollPosition = textArea1.maxVerticalScrollPosition;}
finally, you can test with something like:
private function btnClick(e:Event):void{textArea1.text += new Date().getTime().toString() + "\n";}
1) dataGrid.verticalScrollPosition=dataGrid.maxVerticalScrollPosition

Resources