3 Replies Latest reply on Aug 13, 2010 3:14 PM by Scottae031

    Setting skinClass from a css swf or an RSL

    Scottae031

      I have been trying to set the skinClass of some components by loading a css swf using loadStyleDeclarations.  I can't figure out how to get it to work.  I figured since you can load a css swf at runtime and set regular styles of components, that it would be possible to set the skinClass of those components because it is also a style for skinnable components.  Say if I have a css file which I compile to a swf that looks like this:

       

      @namespace s "library://ns.adobe.com/flex/spark";
      
      s|Application{
          skinClass: ClassReference("MyAppSkin");
      }
      

       

      And MyAppSkin class is just a simple ApplicationSkin that has like a red rectangle for a background or something.  When I execute the loadStyleDeclarations method, my ApplicationSkin never changes.  I wonder if what I am trying to do is possible and if so, what I need to do to make it happen.  I've also tried loading some skin classes from an RSL but I've had no luck.  Can someone point me in the right direction?

      Thanks

        • 1. Re: Setting skinClass from a css swf or an RSL
          Scottae031 Level 1

          So I've done some testing and I am able to get it working as long as the HostComponent is of a built in component.  So for example I have a custom component class which extends Button:

           

           

          package {
               import spark.components.Button;
          
               [SkinState("up")]
               [SkinState("over")]
               [SkinState("down")]
               [SkinState("disabled")]
               
               public class CustomButton extends Button {
                    public function CustomButton() {
                         super();
                    }
               }
          }
          

           

           

          Then I have a custom skin class with it's host component set the spark Button and not my CustomButton:

           

           

          <?xml version="1.0" encoding="utf-8"?>
          <s:SparkSkin 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:Metadata>
                  [HostComponent("spark.components.Button")]
              </fx:Metadata> 
          
              <s:states>
                  <s:State name="up"/>
                  <s:State name="over"/>
                  <s:State name="down"/>
                  <s:State name="disabled"/>
              </s:states>
               
               <s:Rect width="100%" height="100%"><s:fill><s:SolidColor color.up="#AA0000" color.over="#FF0000" color.down="#660000"/></s:fill></s:Rect>
               <s:Label id="labelDisplay"/>
          </s:SparkSkin>
          

           

           

          My css file which is compiled into a swf to be loaded at runtime:

           

           

          .customButton {
              fontSize:  20;
              color: #0000FF;
              skinClass: ClassReference("CustomSkin");
          }
          

           

           

          And finally my main application file:

           

           

          <?xml version="1.0"?>
          <s:Application 
              xmlns:fx="http://ns.adobe.com/mxml/2009" 
              xmlns:mx="library://ns.adobe.com/flex/mx" 
              xmlns:s="library://ns.adobe.com/flex/spark"
              xmlns:themes="*">
          
              <fx:Script>
                  <![CDATA[
                       public function applyRuntimeStyleSheet():void {
                           styleManager.loadStyleDeclarations("theme.swf");
                       }
                  ]]>
              </fx:Script>    
          
              <s:VGroup>
                  <s:Label text="Click the button to load a new CSS-based SWF file."/>
                  <s:Button label="Load css swf" click="applyRuntimeStyleSheet()"/>
                  <themes:CustomButton label="Custom Button" styleName="customButton"/>
              </s:VGroup>
          
          </s:Application>
          

           

           

          But now if I set the HostComponent to the CustomButton instead of spark Button, I get the following error when trying to compile my css swf:

           

          Error: Type was not found or was not a compile-time constant: CustomButton

           

          Any help would be appreciated.

          • 2. Re: Setting skinClass from a css swf or an RSL
            baduncaduncan

            I have the same problem - same error.

             

            I have created a custom class extending from skinnable container and a custom skin for that class.  I decided to assign this skin through css and a type selector:

             

            mynamespace|MyClass

            {

                skinClass: ClassReference("com.company.blah.skins.MyClassSkin");

            }

             

            I get an error on the skinClass line stating: Definition com.company.blah.skins.MyClassSkin cannot be found.

             

            I have also tried adding -includes com.company.blah.skins.MyClassSkin to the compiler options and commenting out the skinClass line.  The IDE STILL thinks the class doesn't exist.  MyClassSkin is certainly there as an mxml component extended from skin.  This is the first time I've tried assigning a skinclass this way, is assigning skinClass this way possible?

             

             

            Edit: Found the solution to my problem.  It was my project structure.  my css file was under assets/ (included in the project as a source directory) while the skin itself was in src/.  Within the context of the css file, there IS no com.company.blah.skins namespace.  My workaround for now is to move the css file inside src/.

            1 person found this helpful
            • 3. Re: Setting skinClass from a css swf or an RSL
              Scottae031 Level 1

              I figured out my issue a while back, but never bothered to respond with my solution because I didn't think anyone here would bother to read this post.

               

              So my issue was a silly mistake.  The custom class does not exist where my theme skin exists.  So what I did to work around it is keep the HostComponent as the closest common super class.  In this example it is:

               

              spark.components.Button 

               

              But in many cases I set it to:

               

              spark.components.supportClasses.SkinnableComponent

               

              Then in order to get data from the custom host component, I specify it via styles.  So on the custom component, you define some style meta data like this:

               

              [Style(name="someStyle", type="uint", format="Color")]

               

              And the skin can access this style value like so:

               

              hostComponent.getStyle('someStyle')

               

              And now you just need to set the style value on the custom component.  You can do so like this in mxml:

               

              <custom:CustomButton someStyle="#FF0000"/>

               

              or you can use setStyle in ActionScript:

               

              customButton.setStyle("someStyle", 0xFF0000);
              

               

               

              I don't know if this is best practice, but this got things rolling for me.