0
votes

I am stuck trying to center a text (RichEditableText) inside a container. My code so far looks like this

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                   xmlns:s="library://ns.adobe.com/flex/spark" 
                   xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Declarations>
    <!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>

<mx:Box id="myCustomBox" height="100%" width="100%" initialize="init();">


    <fx:Script>

        <![CDATA[

            import mx.containers.Box;
            import mx.containers.HBox;
            import mx.containers.VBox;
            import mx.controls.Button;
            import mx.controls.Image;

            import spark.components.RichEditableText;

            import flashx.textLayout.elements.ParagraphElement;
            import flashx.textLayout.elements.SpanElement;
            import flashx.textLayout.elements.TextFlow;
            import flashx.textLayout.formats.TextAlign;

            [Embed("dialog_error.png")] 
            private var myImage:Class; 


            public function init():void {
                var img:Image = new Image();
                img.source = myImage;

                this.addElement(buildPane("Something went wrong", img));

            }

            private function buildPane(message:String, image:Image):Box{
                var exPane:HBox = new HBox();
                exPane.percentHeight = 100;
                exPane.percentWidth = 100;
                exPane.setStyle("horizontalGap","0");

                //Image hosting pane
                var imPane:VBox = new VBox;
                imPane.setStyle("backgroundColor","blue");
                imPane.percentHeight = 100;
                imPane.explicitWidth = 50;
                image.minHeight = 16;
                image.minWidth = 16;
                imPane.setStyle("paddingLeft",10);
                imPane.setStyle("paddingRight",10);
                var invisBtn1:Button = new Button();
                invisBtn1.percentHeight = 40;
                invisBtn1.visible = false;
                imPane.addChild(invisBtn1);
                image.percentHeight = 20;
                imPane.addChild(image);
                var invisBtn2:Button = new Button();
                invisBtn2.visible = false;
                invisBtn2.percentHeight = 40;
                imPane.addChild(invisBtn2);
                exPane.addChild(imPane);

                //Text hosting pane
                var txtPane:Box = new Box();
                txtPane.setStyle("backgroundColor","yellow");
                txtPane.percentHeight = 100;
                //txtPane.setStyle("paddingBottom",10);
                txtPane.setStyle("paddingLeft",0);
                //txtPane.setStyle("paddingTop",30);
                txtPane.setStyle("paddingRight",5);
                //Specify text alignment
                var errMsgLabel:RichEditableText = new RichEditableText;
                var textFlow:TextFlow = new TextFlow();
                var pCenter:ParagraphElement = new ParagraphElement();
                var spanCenter:SpanElement = new SpanElement();
                spanCenter.text = message;
                pCenter.addChild(spanCenter);
                pCenter.textAlign = TextAlign.CENTER;
                textFlow.addChild(pCenter);
                errMsgLabel.textFlow = textFlow;
                errMsgLabel.percentHeight = 100;
                errMsgLabel.percentWidth = 100;
                errMsgLabel.multiline = true;
                txtPane.addChild(errMsgLabel);
                exPane.addChild(txtPane);

                return exPane;

            }

        ]]>
    </fx:Script>

</mx:Box>
</s:WindowedApplication>

I would like the text to be at the same level as the dialog_error icon (Usual X mark icon). So if the text is taller, the icon needs to center itself in the middle of the text. Any pointers would be helpful.

Thank you.

1
Is there a reason you're doing all that in ActionScript rather than MXML? That makes it very hard to follow what you're doing. You may be looking for verticalAlign="middle", but I'm not sure what you're up to and can't quickly see what other containers are at play here... Can you post a clearer example? - Manius
Apologies for the late reply. But I have to do this in action script since the actual thing I am working on is in the context of a plugin where the infrastructure is in action script. This is a standalone example that can be executed directly without any change; not sure how to make this any clearer. - user2789284

1 Answers

0
votes

I can think of no good reason why you would be writing all of this in ActionScript instead of MXML. You're just making things harder for yourself.

The whole 100 lines of code in your question can be reduced to this:

<s:HGroup width="100%" gap="0">
    <s:VGroup width="50" height="100%" paddingLeft="10" paddingRight="10" 
              verticalAlign="middle">
        <s:Image id="msgIcon" source="@Embed('dialog_error.png')"/>
        <s:Button visible="false" includeInLayout="false"/>
        <s:Button visible="false" includeInLayout="false"/>
    </s:VGroup>
    <s:RichEditableText id="errMsgLabel" width="100%"/>
</s:HGroup>

This code also contains the necessary fixes to center the error icon horizontally with respect to the error message's text height.

  • removed the 100% height on the HGroup; this caused the Image to be centered in the middle of the entire container, not just the text height.
  • added verticalAlign="middle" to the VGroup containing Image and Buttons; this property will align the content of this container to its vertical center.
  • added includeInLayout="false" to the invisible Buttons; if you just make the Buttons invisible, they will still take up space in the layout, pushing the Image up a little; setting this property to false will tell the VGroup container to act as if the Buttons really weren't there to do its layout.
  • removed the 100% height on the RichEditableText so that it is only as high as its text content, otherwise the icon will still be centered to the middle of the entire container.
  • removed a bunch of redundant containers.

Note that I assumed you applied the background colors only for testing purposes, to see how the containers are laid out.


I understand you want to dynamically change the icon. You can easily achieve this by setting its source property programatically afterwards:

msgIcon.source = otherEmbeddedImage;

Or even better, through data binding:

<s:Image source="{msgIcon}"/>

msgIcon = otherEmbeddedImage;