12 Replies Latest reply on Oct 3, 2007 3:12 AM by JabbyPandaUA

    Label Rotation big problem

    PrideU2
      I have a simple task, to rotate the label, inside a repeater. The rotation works fine since the font is already emb.

      <mx:Repeater id="rp2" dataProvider="{wsProyectos.ObtenerProyectos.lastResult}">
      <mx:Label id="Titulos" left="0" textAlign="left" rotation="280" styleName="mystyle1" color="white" text="{rp2.currentItem.Proyecto}" ></mx:Label>
      </mx:Repeater>

      The problem is that the labels are rotated, and also width and height. So, it keeps the distance between each repetition as if it was the same width. I was searching for an event triggered after rotation, but couldn't find the solution.

      Here you can see a screenshot of the problem. The labels I mention are the ones of the top of course.

      Image of Flex Output

      Any idea or direction will be greatly appreciated.

      Victor

        • 1. Re: Label Rotation big problem
          Flex harUI Adobe Employee
          For performance and code size reasons, the Flex containers do not factor rotation into the measurement and layout code. I would recommend making a subclass of Label (let's call it RotatedLabel) and beef up its measurement and other related code to handle the fact that it will be rotated. Once RotatedLabel returns the appropriate width/height it will layout appropriately, but if you want the labels so close together that the right edge of one overlaps the left edge of another, you might just be better off writing code to place them in a subclass of Canvas by overriding updateDisplayList.
          • 2. Re: Label Rotation big problem
            PrideU2 Level 1
            Good answer indeed. I'll go for the subclass then.
            Thank you so much for the good idea.

            Victor
            • 3. Re: Label Rotation big problem
              PrideU2 Level 1
              I managed to reposition the labels using a class extendning the HBox, and working with the updateDisplayList. The problem is that the container object has its width large becuase its calculated by the width of all labels before rotation.

              Is there a way to CROP a component? so i leave out the empty space I have now?
              Victor
              • 4. Re: Label Rotation big problem
                Flex harUI Adobe Employee
                You want to avoid using HBox/VBox and most of our containers as they measure assuming rotation=0. Your subclass should just subclass Label, or alternatively, subclass UIComponent and put the Label as the only child.
                • 5. Re: Label Rotation big problem
                  PrideU2 Level 1
                  excellent!!. It's working like a charm right now... I cannot thank you enough for the tips you gave me.
                  • 6. Label Rotation big problem
                    rmarp
                    Any chance you could post the code for this RotatedLabel class? I was trying it myself but I'm not completely clear what I should be doing in the subclass with respect to dimensions/position.

                    Thanks!
                    • 7. Re: Label Rotation big problem
                      PrideU2 Level 1
                      Sure, no trouble at all, here's the code. Hope it helps, if you want , you can send me an email if you have further trouble.

                      It's solved simpler in this stage, first a style:
                      <mx:Style>
                      .estiloRotado {
                      fontFamily:"Arial";
                      fontSize: 12px;
                      fontAntiAliasType:advanced;
                      background-alpha:0;

                      }
                      </mx:Style>

                      <mx:Label width="150" id="Titulos" left="0" textAlign="left" rotation="280" styleName="estiloRotado" color="white" text="{' ' + rp2.currentItem.Proyecto}" ></mx:Label>

                      I placed this label inside a repeater, which then uses another class to place the repeated labels, because as you know , once you rotate the label the X and Y work strangely. Here's the class that controls positioning , extending an HBOX, which includes the repeater of the rotated labels.

                      package
                      {

                      import mx.containers.VBox;
                      import mx.core.EdgeMetrics;
                      import mx.core.UIComponent;
                      import mx.containers.HBox;
                      import mx.containers.Canvas;
                      import mx.controls.Label;

                      public class LabelRotada extends HBox
                      {

                      public function LabelRotada() {
                      super();

                      }
                      override protected function updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void {

                      super.updateDisplayList(unscaledWidth, unscaledHeight);
                      var obj:Label;
                      var posX:int=0;


                      for (var i:int = 0; i < numChildren; i++)
                      {
                      obj = Label(getChildAt(i));
                      obj.x=posX;
                      posX=posX+38;
                      }

                      }
                      }
                      }
                      • 8. Label Rotation big problem
                        FlightGuy Level 1
                        Here's the reusable solution - I've overridden two methods: measure() and updateDisplayList(). I don't call super.updateDisplayList, since I don't want it to truncate the label or wrap (a result of the width being less than the text width). I don't need it to support this - just have a single line of text, though you could extend Text rather than Label, and give it just a little attention in the updateDisplayList, duplicating what's done in the mx:Text class, but using unrotatedWidth and unrotatedHeight in place of unscaledWidth and unscaledHeight.

                        The reason for overriding updateDisplayList is to move the textField such that, after rotation, the top left corner of the box containing the rotated text is placed at the control's x and y coords. Because the width and height are now correct, this will correctly center as well.

                        Tim

                        import mx.controls.Label;

                        public class RotableText extends Label
                        {
                        private var unrotatedWidth:Number;
                        private var unrotatedHeight:Number;

                        override protected function measure():void{
                        super.measure();
                        var rotationRadians:Number = -rotation * Math.PI / 180;
                        unrotatedHeight = measuredHeight;
                        unrotatedWidth = measuredWidth;
                        measuredHeight = unrotatedHeight * Math.cos(rotationRadians) + unrotatedWidth * Math.sin(rotationRadians);
                        measuredWidth = unrotatedHeight * Math.sin(rotationRadians) + unrotatedWidth * Math.cos(rotationRadians);
                        }

                        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
                        var rotationRadians:Number = -rotation * Math.PI / 180;
                        var sinRot:Number = Math.sin(rotationRadians);
                        var cosRot:Number = Math.cos(rotationRadians);
                        textField.y = unrotatedWidth * sinRot * cosRot;
                        textField.x = -unrotatedWidth * sinRot * sinRot;
                        textField.setActualSize(unrotatedWidth, unrotatedHeight);
                        }
                        }
                        • 9. Re: Label Rotation big problem
                          FlightGuy Level 1
                          Here's a later version that supports rotation to any angle (the former only supported -90 < r < 0 - the normal rotation for angled text). I also streamlined it a bit so it only does the trig calculations when the rotation is set.

                          import mx.controls.Label;

                          public class RotableText extends Label
                          {
                          protected var unrotatedWidth:Number;
                          protected var unrotatedHeight:Number;
                          protected var sinRot:Number = 0;
                          protected var cosRot:Number = 1;

                          override public function set rotation(value:Number):void{
                          super.rotation = value;
                          var rotationRadians:Number = rotation * Math.PI / 180;
                          sinRot = Math.sin(rotationRadians);
                          cosRot = Math.cos(rotationRadians);
                          }

                          override protected function measure():void{
                          super.measure();
                          unrotatedHeight = measuredHeight;
                          unrotatedWidth = measuredWidth;
                          measuredHeight = Math.abs(unrotatedHeight * cosRot) + Math.abs(unrotatedWidth * sinRot);
                          measuredWidth = Math.abs(unrotatedWidth * cosRot) + Math.abs(unrotatedHeight * sinRot);
                          }

                          override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
                          if (sinRot >= 0){
                          if (cosRot >= 0){
                          textField.x = unrotatedHeight * sinRot * cosRot;
                          textField.y = -unrotatedHeight * sinRot * sinRot;
                          } else {
                          textField.x = unrotatedWidth * (sinRot * sinRot - 1);
                          textField.y = -unrotatedHeight + unrotatedWidth * sinRot * cosRot;
                          }
                          } else {
                          if (cosRot >=0){
                          textField.x = -unrotatedWidth * sinRot * sinRot;
                          textField.y = -unrotatedWidth * sinRot * cosRot;
                          } else {
                          textField.x = - unrotatedWidth - unrotatedHeight * sinRot * cosRot;
                          textField.y = unrotatedHeight * (sinRot * sinRot - 1);
                          }
                          }
                          textField.setActualSize(unrotatedWidth, unrotatedHeight);
                          }
                          }
                          • 10. Re: Label Rotation big problem
                            PrideU2 Level 1
                            great, thanks for the update!
                            • 11. Re: Label Rotation big problem
                              Gil1 Level 1
                              Hi,

                              I would like to know how to use this class.

                              I have tried adding a RotableText element directly in the MXML section like:

                              <local:RotableText x="185" y="75" text="SOme leabel stuff here" width="374" rotation="90"/>

                              It does not produce a compilation error, but when I run it the screen appears blank.

                              Then, I tried with AS like:

                              var text1:RotableText = new RotableText;
                              text1.rotation =90;
                              text1.x =100;
                              text1.y =100;
                              text1.text = "Hello world";

                              But it produces a compilation error saying "Access to an undefined property text1"

                              Gilbert
                              • 12. Re: Label Rotation big problem
                                JabbyPandaUA Level 3
                                You must embed fonts in order to view the text while rotating it.

                                http://livedocs.adobe.com/flex/2/docs/00000787.html