4 Replies Latest reply on Jul 8, 2011 4:28 AM by Benoitcn

    custom VScrollBar skin issue

    Benoitcn Level 1

      dropdownlist.png

      My VScrollBar skin only have two part track and thumb.

      I find my VScrollBar can't drag to the end ?

      Can somebody give some suggestion ?

      I'm using flex4.5.1.

      <s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
            xmlns:fb="http://ns.adobe.com/flashbuilder/2009" minWidth="15" minHeight="35" 
            alpha.disabled="0.5" top="2" bottom="2">
      
          <fx:Metadata>
              /** 
               * @copy spark.skins.spark.ApplicationSkin#hostComponent
               */
              [HostComponent("spark.components.mediaClasses.ScrubBar")]
          </fx:Metadata> 
          
          <fx:Script fb:purpose="styling">
              /* Define the skin elements that should not be colorized. */
              static private const exclusions:Array = ["track", "thumb"];
              
              /**
               * @private
               */
              override public function get colorizeExclusions():Array {return exclusions;}
              
              /**
               * @private
               */
              override protected function initializationComplete():void
              {
                  useChromeColor = true;
                  super.initializationComplete();
              }
          </fx:Script>
          
          <s:states>
              <s:State name="normal" />
              <s:State name="disabled" />
                <s:State name="inactive"/>
          </s:states>
          
          <fx:Declarations>
              <!--- Defines the appearance of the ScrubBar skin's data tip. To customize the data tip's appearance, create a custom ScrubBarSkin class. -->
              <fx:Component id="dataTip">     
                  <s:DataRenderer minHeight="24" minWidth="40" y="-34">
                      <s:RectangularDropShadow id="shadow" distance="3" 
                          angle="90" color="#999999" left="0" top="0" right="0" bottom="0"/>
                          
                      <s:Rect top="0" left="0" right="0" bottom="0">
                          <s:fill>
                              <s:SolidColor color="0x000000" alpha=".9"/>
                          </s:fill>
                      </s:Rect>
                      
                      <s:Label id="labelDisplay" text="{data}"
                               horizontalCenter="0" verticalCenter="1"
                               left="5" right="5" top="5" bottom="5"
                               textAlign="center" verticalAlign="middle"
                               fontWeight="normal" color="white" fontSize="11">
                      </s:Label>
                  </s:DataRenderer>
              </fx:Component>
          </fx:Declarations>
          
          <!--- The skin pat that defines the video timeline. The timeline shows the current playhead location  
                in the video, the amount of the video previously played, and the loaded in part of the video. -->
      
          <!--- @copy spark.components.mediaClasses.ScrubBar#loadedRangeArea -->
          <s:Group id="loadedRangeArea" x="0" y="0" height="11" includeInLayout="false">
          
              <!-- inset 7 and 6 pixels because that's thumbSize/2 -->
              <s:Group left="7" right="6" top="0" bottom="0" minWidth="0">
              
                  <!-- fill -->
                  <s:Rect left="1" right="1" top="1" bottom="1">
                      <s:fill>
                          <s:SolidColor color="0xD7D7D7" />
                      </s:fill>
                  </s:Rect>
                  
                  <!-- inner glow -->
                  <!-- set height to 100%, maxHeight=1, minHeight=0 b/c only want this line to show up 
                       if there's room for it -->
                  <s:Rect left="1" top="1" bottom="1" width="100%" maxWidth="1" minWidth="0">
                      <s:fill>
                          <s:SolidColor color="0x000000" alpha="0.12" />
                      </s:fill>
                  </s:Rect>
                  <s:Rect left="2" right="1" top="1" height="100%" maxHeight="1" minHeight="0">
                      <s:fill>
                          <s:SolidColor color="0x000000" alpha="0.12" />
                      </s:fill>
                  </s:Rect>
                  
                  <!-- black line on right -->
                  <!-- set width to 100%, maxWidth=1, minWidth=0 b/c only want this line to show up 
                       if there's room for it -->
                  <s:Rect right="0" top="1" bottom="1" width="100%" maxWidth="1" minWidth="0">
                      <s:fill>
                          <s:SolidColor color="0x000000" alpha=".5"/>
                      </s:fill>
                  </s:Rect>
                  
              </s:Group>    
          </s:Group>
          
          <!--- @copy spark.components.mediaClasses.ScrubBar#playedArea -->
          <s:Group id="playedArea" x="0" y="0" height="11" includeInLayout="false">
          
              <!-- inset 7 and 6 pixels because that's thumbSize/2 -->
              <s:Group left="7" right="6" top="0" bottom="0" minWidth="0">
              
                  <!-- inner glow -->
                  <s:Rect left="1" right="1" top="1" bottom="1">
                      <s:fill>
                          <s:LinearGradient rotation="90">
                              <s:GradientEntry color="0xFEFEFE"/>
                              <s:GradientEntry color="0xECECEC"/>
                          </s:LinearGradient>
                      </s:fill>
                  </s:Rect>
                  
                  <!-- fill -->
                  <s:Rect left="2" right="2" top="2" bottom="2">
                      <s:fill>
                          <s:LinearGradient rotation="90">
                              <s:GradientEntry color="0xFFFFFF" alpha="0.85"/>
                              <s:GradientEntry color="0xE1E1E1" alpha="0.85"/>
                          </s:LinearGradient>
                      </s:fill>
                  </s:Rect>
                  
                  <!-- black line on right -->
                  <!-- set width to 100%, maxWidth=1, minWidth=0 b/c only want this line to show up 
                       if there's room for it -->
                  <s:Rect right="0" top="1" bottom="1" width="100%" maxWidth="1" minWidth="0">
                      <s:fill>
                          <s:SolidColor color="0x131313"/>
                      </s:fill>
                  </s:Rect>
                  
              </s:Group>  
          </s:Group>
      
          <!--- A skin part that defines a button that can be dragged along the track to increase or decrease 
                the playhead location in the video.   -->
           
           <s:Button skinClass="skin.MyTrackSkin" id="track" horizontalCenter="0" minHeight="14"
                       focusEnabled="false" tabEnabled="false" top="2" bottom="2">
                <s:filters>
                     <s:GlowFilter includeIn="normal" blurX="6.0" blurY="6.0" inner="false" color="0x5380d0" strength="1" alpha="1.0" quality="2" knockout="false"/>
                </s:filters>
           </s:Button>
           
           <s:Button skinClass="skin.MyThumbSkin" id="thumb" focusEnabled="false" visible.inactive="false" tabEnabled="false" verticalCenter="0">
                <s:filters>
                     <s:GlowFilter includeIn="normal" blurX="13" blurY="13" inner="false" color="#000000" strength="2" alpha="1.0" quality="2" knockout="false"/>
                </s:filters>
           </s:Button>
           
           <s:transitions>
                <s:Transition fromState="normal" toState="disabled" autoReverse="true">
                     <s:Parallel>
                          <s:Parallel target="{thumb}">
                               <s:Move duration="0" autoCenterTransform="true"/>
                          </s:Parallel>
                     </s:Parallel>
                </s:Transition>
           </s:transitions>
      
      </s:SparkSkin>
      

       

      The track skin:

      <s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" 
                   xmlns:s="library://ns.adobe.com/flex/spark" 
                   xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
                   alpha.disabled="0.5">
           
          <fx:Metadata>
              <![CDATA[ 
              /** 
               * @copy spark.skins.spark.ApplicationSkin#hostComponent
               */
              [HostComponent("spark.components.Button")]
              ]]>
          </fx:Metadata>
      
          <!-- states -->
          <s:states>
              <s:State name="up" />
              <s:State name="over" />
              <s:State name="down" />
              <s:State name="disabled" />
          </s:states>
       
           <s:Rect bottom="2" top="2" right="0" width="2" alpha="0.84" radiusX="10" radiusY="10">
                <s:fill>
                     <s:SolidColor color="#5380D0"/>
                </s:fill>
           </s:Rect>
          
      </s:Skin>
      

       

      The thumb skin:

      <s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
                      xmlns:s="library://ns.adobe.com/flex/spark"
                      xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
                      alpha.disabled="0.5" >
           
          <fx:Metadata>
              <![CDATA[ 
              /** 
               * @copy spark.skins.spark.ApplicationSkin#hostComponent
               */
              [HostComponent("spark.components.Button")]
              ]]>
          </fx:Metadata>
      
          <!-- states -->
          <s:states>
              <s:State name="up" />
              <s:State name="over" />
              <s:State name="down" />
              <s:State name="disabled" />
          </s:states>
           
           <s:Ellipse left="0" width="15" height="15" >
                <!--<s:stroke>
                     <s:SolidColorStroke color="0x0f0f8f" weight="1"/>
                </s:stroke>-->
                <s:fill>
                     <s:SolidColor color="#232323" />
                </s:fill>
           </s:Ellipse>
      
      </s:SparkSkin>
      
        • 1. Re: custom VScrollBar skin issue
          Benoitcn Level 1

          I don't know where my skin wrong ?

          Can somebody give some suggestion ?

          • 2. Re: custom VScrollBar skin issue
            _spoboyle Level 4

            can you post the code where you actually use this ScrubBar please

            • 3. Re: custom VScrollBar skin issue
              daslicht Level 2

              http://wensauer.info/flex/SimpleVScrollBarSkin/Main.html  /(viewsource)

               

              The MouseWheel however seems not to work ? Why ?

              • 4. Re: custom VScrollBar skin issue
                Benoitcn Level 1

                This 's all my code custom the dropdownlist skin and vertical scrollbar skin.

                 

                The application.mxml

                 

                <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
                      xmlns:s="library://ns.adobe.com/flex/spark" 
                      xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
                 <fx:Style>
                  @namespace s "library://ns.adobe.com/flex/spark";
                  @namespace mx "library://ns.adobe.com/flex/mx";
                  s|Application{
                   fontFamily: "Microsoft YaHei";
                  }
                  
                  s|PopUpAnchor{
                   
                  }
                 </fx:Style>
                 <fx:Declarations>
                  <s:ArrayList id="arr">
                   <fx:String><![CDATA[English]]></fx:String>
                   <fx:String>Franch</fx:String>
                   <fx:String>Spanish</fx:String>
                   <fx:String>Russian</fx:String>
                   <fx:String>Chinese</fx:String>
                   <fx:String><![CDATA[English]]></fx:String>
                   <fx:String>Franch</fx:String>
                   <fx:String>Spanish</fx:String>
                   <fx:String>Russian</fx:String>
                   <fx:String>Chinese</fx:String>
                   <fx:String>The End</fx:String>
                  </s:ArrayList>
                  <!-- Place non-visual elements (e.g., services, value objects) here -->
                 </fx:Declarations>
                 <s:DropDownList skinClass="skin.MyDropDownListSkin" dataProvider="{arr}" width="170" borderColor="0xff1010"
                     contentBackgroundColor="0xffffff" contentBackgroundAlpha=".2" borderVisible="true"/>
                </s:Application>
                


                The DropDownList skin, I use my vertical scroll bar skin in this file :

                <s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" 
                    xmlns:fb="http://ns.adobe.com/flashbuilder/2009" alpha.disabled=".5"> 
                 
                 <!-- host component -->
                 <fx:Metadata>
                  <![CDATA[ 
                  /** 
                  * @copy spark.skins.spark.ApplicationSkin#hostComponent
                  */
                  [HostComponent("spark.components.DropDownList")]
                  ]]>
                 </fx:Metadata> 
                 
                 <fx:Script fb:purpose="styling">
                  <![CDATA[            
                   
                   /* Define the content fill items that should be colored by the "contentBackgroundColor" style. */
                   static private const contentFill:Array = ["bgFill"];
                   
                   /**
                    * @private
                    */
                   override public function get contentItems():Array {return contentFill};
                   /**
                    * @private
                    */
                   override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
                   {
                    if (getStyle("borderVisible") == false)
                    {
                     if (border)
                      border.visible = false;
                     if (background)
                     {
                      background.left = background.top = background.right = background.bottom = 0;
                     }
                     if (scroller)
                      scroller.minViewportInset = 0;
                    }
                    else
                    {
                     if (border)
                      border.visible = true;
                     if (background)
                     {
                      background.left = background.top = background.right = background.bottom = 1;
                     }
                     if (scroller)
                      scroller.minViewportInset = 1;
                    }
                    
                    if (dropShadow)
                     dropShadow.visible = getStyle("dropShadowVisible");
                    
                    openButton.setStyle("cornerRadius", getStyle("cornerRadius"));
                    
                    if (borderStroke)
                    {
                     borderStroke.color = getStyle("borderColor");
                     borderStroke.alpha = getStyle("borderAlpha");
                    }
                    super.updateDisplayList(unscaledWidth, unscaledHeight);
                   }
                  ]]>
                 </fx:Script>
                 
                 <s:states>
                  <s:State name="normal" />
                  <s:State name="open" />
                  <s:State name="disabled" />
                 </s:states>
                 
                 <!--- 
                 The PopUpAnchor control that opens the drop-down list. 
                 
                 <p>In a custom skin class that uses transitions, set the 
                 <code>itemDestructionPolicy</code> property to <code>none</code>.</p>
                 -->
                 <s:PopUpAnchor id="popUp"  displayPopUp.normal="false" displayPopUp.open="true" includeIn="open"
                       left="0" right="0" top="0" bottom="0" itemDestructionPolicy="auto" popUpHeightMatchesAnchorHeight="false" 
                       popUpPosition="below" popUpWidthMatchesAnchorWidth="true">
                  
                  <!--- 
                  This includes borders, background colors, scrollers, and filters.
                  @copy spark.components.supportClasses.DropDownListBase#dropDown
                  -->
                  <s:Group id="dropDown">
                   
                   <!--- @private -->
                   <s:RectangularDropShadow id="dropShadow" blurX="10" blurY="10" alpha="0" distance="2" 
                          angle="90" color="#000000" left="0" top="0" right="0" bottom="0"/>
                   
                   <!--- @private -->
                   <s:Rect id="border" left="0" right="0" top="0" bottom="0">
                    <s:stroke>
                     <!--- border stroke @private -->
                     <s:SolidColorStroke id="borderStroke" weight="1" color="0xff0000"/>
                    </s:stroke>
                   </s:Rect>
                   
                   <!-- fill -->
                   <!--- Defines the appearance of drop-down list's background fill. -->
                   <s:Rect id="background" left="1" right="1" top="1" bottom="1" >
                    <s:fill>
                     <!---  
                     The color of the drop down's background fill.
                     The default color is 0xFFFFFF.
                     -->
                     <s:SolidColor id="bgFill" color="0x1f1f1f" alpha="0.3"/>
                    </s:fill>
                    <s:filters>
                     <s:BlurFilter blurX="2" blurY="2" quality="2" />
                    </s:filters>
                   </s:Rect>
                   
                   <!--- @private -->
                   <s:Scroller id="scroller" left="10" top="0" right="10" bottom="0" hasFocusableChildren="false" minViewportInset="1" skinClass="skin.MyScrollerSkin">
                    <!--- @copy spark.components.SkinnableDataContainer#dataGroup-->
                    <s:DataGroup id="dataGroup" itemRenderer="spark.skins.spark.DefaultItemRenderer" top="0" bottom="0" left="0" right="0">
                     <s:layout>
                      <s:VerticalLayout gap="0" horizontalAlign="contentJustify" requestedMinRowCount="1" requestedMaxRowCount="6"/>
                     </s:layout>
                    </s:DataGroup> 
                   </s:Scroller>
                  </s:Group>
                 </s:PopUpAnchor>
                 
                 <!---  The default skin is DropDownListButtonSkin. 
                 @copy spark.components.supportClasses.DropDownListBase#openButton
                 @see spark.skins.spark.DropDownListButtonSkin -->
                 <s:Button id="openButton" left="0" right="0" top="0" bottom="0" focusEnabled="false" tabEnabled="false"
                     skinClass="skin.MyDropDownListButtonSkin" />  
                 
                 <!--- @copy spark.components.DropDownList#labelDisplay -->
                 <s:Label id="labelDisplay" verticalAlign="middle" maxDisplayedLines="1" 
                    mouseEnabled="false" mouseChildren="false" left="12" right="30" 
                    top="2" bottom="2" width="75" verticalCenter="1" /> 
                 
                </s:SparkSkin>
                

                 

                The scrollbar Skin:

                <s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" 
                xmlns:s="library://ns.adobe.com/flex/spark">
                 
                 <fx:Metadata>
                  <![CDATA[ 
                
                  /** 
                  * @copy 
                spark.skins.spark.ApplicationSkin#hostComponent
                  */
                  [HostComponent("spark.components.Scroller")]
                  ]]>
                 </fx:Metadata> 
                
                 
                 <fx:Script>
                  <![CDATA[    
                   /**
                    *  
                @private
                    */
                   override public function beginHighlightBitmapCapture() 
                : Boolean
                   {
                    var needUpdate:Boolean = 
                super.beginHighlightBitmapCapture();
                    
                    // Draw an opaque rect that 
                fill our entire skin. Our background
                    // is transparent, but we don't want 
                focus/error skins to
                    // poke through.  This is safe to do since we don't 
                have any 
                    // graphic elements as direct children.
                    /* 
                graphics.beginFill(0);
                    graphics.drawRect(0, 0, width, 
                height);
                    graphics.endFill(); */
                    
                    return 
                needUpdate;
                   }
                   
                   /**
                    *  @private
                    */
                   override 
                public function endHighlightBitmapCapture() : Boolean
                   {
                    var 
                needUpdate:Boolean = super.endHighlightBitmapCapture();
                    
                    // Clear 
                the rect we drew in 
                beginBitmapCapture();
                    graphics.clear();
                    
                    return 
                needUpdate;
                   }
                  ]]>
                 </fx:Script>
                 
                 <!---  A 
                vertical scrollbar that lets you control the portion of data that is displayed 
                
                 when there is too much data to fit vertically in a display area.
                 The 
                Scroller determines whether the vertical ScrollBar is visible. 
                -->
                 <s:VScrollBar id="verticalScrollBar" visible="false" 
                skinClass="skin.MyScrollBarSkin"/>
                 
                 <!---  A horizontal scrollbar 
                that lets you control the portion of data that is displayed 
                 when there is 
                too much data to fit horizontally in a display area.
                 The Scroller determines 
                whether the horizontal ScrollBar is visible. -->
                 <s:HScrollBar 
                id="horizontalScrollBar" visible="false" />
                 
                </s:SparkSkin>