4 Replies Latest reply on Feb 27, 2009 7:11 PM by jbucaran

    How do I apply programmatic skins for completely custom drawn components of a Flex library project?

    jbucaran
      Hello folks,

      I am looking for best practices advice when (1) creating custom components and (2) styling and skinning.

      I already know how to skin a component part of the Flex framework. I can make a class extending ProgrammaticSkin and have my component skinned using CSS to link the component with the reference to my custom class.

      However what about those cases when you are completely creating a component from scratch?

      Imagine a "Freehand Drawing Canvas" component that allows the user to draw on it and has some buttons to set color styles, line styles, etc., or imagine a "Screen Flow Gallery" component that displays visual objects in a fashion similar to Cover Flow in the Mac.

      In many components I am aware you may reuse other components part of the Flex framework but I am trying to picture an scenario where you would need to draw everything yourself because there just isn't something to base it upon so you will end up drawing it from scratch.

      To learn how instead of building one of those components I mentioned previously I decided to start with something simple that would illustrate this like a LiteButton component that will behave just like the Flex mx.controls.Button but will extend UIComponent and be completely custom drawn.

      The component will have a default look and will also be style-able and skin-able. I will provide styles for users of the component to modify and regarding skinning anyone can create a custom ProgrammaticSkin adding its own drawing logic and link it to the component via CSS with the ClassReference applied to the skin selector.

      So far so good and it's clear what I want to achieve. I actually know how to do most of the stuff here but I have one single problem.

      Here is my question, where should I put my custom drawing logic? If I do it in the updateDisplayList inside the class extending UIComponent it works, however I thought that it would be a better practice to do it using programmatic skins, that way I could provide different skin themes for my component set.

      The problem is that I can't make the programmatic work in this scenario. I tried instantiating the custom programmatic skin during the updateDisplayList of the LiteButton component and adding it to my display object via addChild but that didn't do anything. I also tried creating a "default.css" stylesheet and tried to use ClassReference as I would normally do to skin an already existing component (or composite component as well) but that didn't do anything either.

      So how do I apply programmatic skins for completely custom drawn components of my Flex library project?

      I could do it inside the updateDisplayList of the LiteButton class extending UIComponent but again I would like to provide different theme sets for my components so it makes sense using programmatic skins.
        • 1. Re: So how do I apply programmatic skins with the default look for custom drawn components?
          Level 7

          "jbucaran" <webforumsuser@macromedia.com> wrote in message
          news:gnvsfq$696$1@forums.macromedia.com...
          > Hello folks,
          >
          > I am looking for best practices advice when (1) creating custom components
          > and
          > (2) styling and skinning.
          >
          > I already know how to skin a component part of the Flex framework. I can
          > make
          > a class extending ProgrammaticSkin and have my component skinned using CSS
          > to
          > link the component with the reference to my custom class.
          >
          > However what about those cases when you are completely creating a
          > component
          > from scratch?
          >
          > Imagine a "Freehand Drawing Canvas" component that allows the user to draw
          > on
          > it and has some buttons to set color styles, line styles, etc., or imagine
          > a
          > "Screen Flow Gallery" component that displays visual objects in a fashion
          > similar to Cover Flow in the Mac.
          >
          > In many components I am aware you may reuse other components part of the
          > Flex
          > framework but I am trying to picture an scenario where you would need to
          > draw
          > everything yourself because there just isn't something to base it upon so
          > you
          > will end up drawing it from scratch.

          This may help with that
          http://livedocs.adobe.com/flex/3/html/help.html?content=skinstyle_3.html

          > To learn how instead of building one of those components I mentioned
          > previously I decided to start with something simple that would illustrate
          > this
          > like a LiteButton component that will behave just like the Flex
          > mx.controls.Button but will extend UIComponent and be completely custom
          > drawn.
          >
          > The component will have a default look and will also be style-able and
          > skin-able. I will provide styles for users of the component to modify and
          > regarding skinning anyone can create a custom ProgrammaticSkin adding its
          > own
          > drawing logic and link it to the component via CSS with the ClassReference
          > applied to the skin selector.
          >
          > So far so good and it's clear what I want to achieve. Actually after
          > playing
          > with the weekend and today I know how to do most of the stuff but I have
          > one
          > single problem. So here is my question, where should I provide my custom
          > drawing logic? If I do it in the updateDisplayList inside the class
          > extending
          > UIComponent it works, however I thought that it would be a better practice
          > to
          > do it using programmatic skins, that way I could provide different skin
          > themes
          > for my component set.

          These aren't mutually exclusive. When you provide a skin with a
          TypeSelector, you have to add it to the display list somewhere, and this is
          typically done in updateDisplayList or addChildren. I prefer to do it in
          updateDisplayList, because you can then change it if the style changes.

          > The problem is that I can't make the programmatic work in this scenario. I
          > tried instantiating the custom programmatic skin during the
          > updateDisplayList
          > of the LiteButton component and adding it to my display object via
          > addChild but
          > that didn't do anything.

          Exactly what did you do?

          > I also tried creating a "default.css" stylesheet and
          > tried to use ClassReference as I would normally do to skin an already
          > existing
          > component (or composite component as well) but that didn't do anything
          > either.

          I've never had any problem using an approach similar to this...but I will
          say that I couldn't see any advantage in creating a default.css style sheet,
          since it's not really default in the way that the one that comes with Flex
          is. It's much more obvious to anyone using your component what's going on
          there if you create a style sheet where they're likely to spot it.

          > So how do I apply programmatic skins with the default look for custom
          > drawn
          > components?

          It seems like your approach is fine, but maybe you've made a mistake in your
          implementation.

          > I could do it inside the updateDisplayList of the LiteButton class
          > extending
          > UIComponent but again I would like to provide different theme sets for my
          > components so it makes sense using programmatic skins.

          You might want to consider also adding an instance of HaloBorder to your
          component. That brings a lot of functionality with it.

          HTH;

          Amy


          • 2. Re: How do I apply programmatic skins for completely custom drawn components of a Flex library project?
            jbucaran Level 1
            Thanks for your response

            I believe the problem is when adding the programmatic class instance to the DisplayList. I am not sure if I am doing it correctly.

            This my updateDisplayList code:

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

            var skinClass:Class = this.getStyle("skin") as Class;
            if (skinClass != null)
            {
            skinObject = new skinClass();
            addChild(skinObject);
            }
            }
            • 3. Re: How do I apply programmatic skins for completely custom drawn components of a Flex library project?
              jbucaran Level 1
              This worked:

              skinObject.setActualSize(unscaledWidth, unscaledHeight)

              All of this trouble was worth it.

              Thanks for that push Amy I appreciate it a lot.

              You can reach me at jbucaran@gmail.com

              Cheers.
              • 4. Re: How do I apply programmatic skins for completely custom drawn components of a Flex library project?
                jbucaran Level 1
                Now I am presenting the problem that at design time I can't see my component being drawn but only at run time.

                How do I make sure everything that I draw is also drawn during design time in the Flex design view?

                Thanks.