Programmatic Skinning: Drawing formatted text into a bitmapdata object

May 28th, 2008 by Unknown Morphician

I came upon a challenge creating a custom ToggleButtonBar component. The challenge was to display dynamic text on each button while displaying button states (up, over, down, selected). This is not a problem when you have simple formatted text. You can assign and style the text via the label property of the button. But, I needed to display two text values. One value that needed to be rotated and formatted a different way.

By programmaticly skinning the buttons, I was able to add uniquely formatted text to a sprite that is then drawn to the button state skin. If you're new to Programmatic Skinning, check out Joey Lott and Chafic Kazoun's book - Programming Flex 2.

Here is a scaled down version of this functionality. In most cases, you would use a different background image per button state. In this example, I am embedding one background image and a text element with an embedded font.


package com.myProject.skins
{
   import flash.display.BitmapData;
   import flash.display.IBitmapDrawable;
   import flash.display.Sprite;
   import flash.text.TextField;
   import flash.text.TextFieldAutoSize;
   import flash.text.TextFormat;
   import flash.text.AntiAliasType;
   import mx.controls.Button;
   import mx.core.UIComponent;
   import mx.skins.ProgrammaticSkin;

   public class CustomButtonSkin extends ProgrammaticSkin
   {

      [Embed(source='C:\\WINDOWS\\Fonts\\framd.ttf',
      fontName='FranklinMed', mimeType='application/x-font')]
      private var FranklinMed:Class;

      /* This path is assuming that you have an image in this folder */
      [Embed(source="assets/images/skinsRed.png")]
      private var skinImgRed:Class;

      public function CustomButtonSkin(){}

      override protected function updateDisplayList(unscaledWidth:Number,
           unscaledHeight:Number):void
      {
           var _backgroundImg:Sprite = new Sprite();
           var _mainSprite:Sprite = new Sprite();
           var _bitmapData:BitmapData =
                new BitmapData(int(unscaledWidth), int(unscaledHeight));
           var _mainBitmapData:BitmapData =
                new BitmapData(int(unscaledWidth), int(unscaledHeight));
           var _skinImg:IBitmapDrawable = new skinImgRed();

           /*
               Drawing the embedded image to sprite(backgroundImg)
               and then add it to mainSprite.
           */
           _bitmapData.draw(_skinImg);
           _backgroundImg.graphics.beginBitmapFill(_bitmapData);
           _backgroundImg.graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);
           _backgroundImg.graphics.endFill();
           _mainSprite.addChild(_backgroundImg);

           /*
              Create and format the textfield. Then add it to mainSprite.
              Note: Using an embedded font in order to change the rotation.
           */
           var _labelName:TextField = new TextField();
           _labelName.embedFonts = true;
           _labelName.textColor = 0xffffff;
           _labelName.autoSize = TextFieldAutoSize.RIGHT;
           _labelName.text = "dynamic text"; // example - Button.Data property
           var _textFormat:TextFormat = new TextFormat();
           _textFormat.font = "FranklinMed";
           _textFormat.size = 14;
           _labelName.antiAliasType = AntiAliasType.ADVANCED;
           _labelName.setTextFormat(_textFormat);
           _labelName.rotation = -90;
           _labelName.y = 10 + _labelName.textWidth;
           _mainSprite.addChild(_labelName);

           /* Draw mainSprite to CustomButtonSkin object */
           _mainBitmapData.draw(_mainSprite);
           graphics.beginBitmapFill(_mainBitmapData);
           graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);
           graphics.endFill();

      }

   }

}
Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • DZone
  • Fark
  • LinkedIn
  • Live
  • Reddit
  • Slashdot
  • StumbleUpon
  • Technorati
  • Twitter
  • Yahoo! Bookmarks
  • RSS
  • email

One Response to “Programmatic Skinning: Drawing formatted text into a bitmapdata object”

  1. Chris Wyatt says:

    Is a CreationComplete event required when adding the TextField to the sprite?

    I have a problem where the right of my text is chopped off even though the text field I set is much larger than the text (the font isn’t italic or anything). Wondering if it’s maybe because I’m drawing it before it’s initialised properly.

    Thanks.

Leave a Reply