Andy Hulstkamp

about creating online experiences

19. September 2008

Gumbo Mixer Slider

Today I had a closer look at the new skinning architecture of Gumbo. Here’s a little example that uses a couple of custom slider components. This custom component extends the standard gumbo VSlider by composition and integrates custom skins.

Gumbo Mixer Slider

Demo. Needs flash player 10 (beta rc1).

The Gumbo VSlider expects 2 skin parts: thumb for the thumb and track for - guess what - track. So skinning VSlider comes down to something like this:

VSlider
    Skin for VSlider
        Button for skin part thumb, reference to
            Skin for that Button (->Slider thumb)
        Button for skin part track
            Skin for that Button (->Slider track)

The skin for the Slider introduces the two parts:

<?xml version="1.0" encoding="utf-8"?>
<Skin xmlns="http://ns.adobe.com/mxml/2009"
    height="100" width="15">

    <Metadata>
      [HostComponent("flex.component.VSlider")]
    </Metadata> 

    <Button id="track" left="2" right="2" top="0" bottom="0" 
            skinZZ="com.hulstkamp.lab.gumbo.skins.buttons.OscSliderTrackSkin" />
    <Button id="thumb" horizontalCenter="0" width="21" height="15" top="-5" 
            skinZZ="com.hulstkamp.lab.gumbo.skins.buttons.OscSliderThumbSkin" />
</Skin>

Both the thumb and the track get a custom skin. The skin for the track could be something like this:

<?xml version="1.0" encoding="utf-8"?>
<Skin xmlns="http://ns.adobe.com/mxml/2009">
    <Metadata>
      [HostComponent("flex.component.Button")]
    </Metadata> 

    <states>
        <State name="up" />
        <State name="down" />
        <State name="over" />
        <State name="disabled" />
    </states>
    <!-- draw track path. this will be easier with thermo integration ;-) -->
    <Group top="0" right="0" bottom="0" left="0">
      <Path top="8" right="0" bottom="8" left="0" 
          data="M 0 0   h 10 
                  M 0 50  h 10 
                  M 0 100 h 10
                  M 5 0   v 100
                  M 3 10  h 5
                  M 3 20  h 5
                  M 3 30  h 5
                  M 3 40  h 5
                  M 3 60  h 5
                  M 3 70  h 5
                  M 3 80  h 5
                  M 3 90  h 5
                  ">
          <stroke>
              <SolidColorStroke weight="1" color="#707070" alpha="1" />
          </stroke>
      </Path>
  </Group>
</Skin>

The skin for the thumb simply introduces some BitmapGraphic to serve as a thumb.

To get some additional GUI elements we could wrap up the skinned slider in a custom component and introduce the desired elements. The following example adds several GUI Elements to the Slider. To do this within the custom component is in fact bad practice since it breaks the clean separation between View and Model/Controller. A better approach would be to extend VSlider and add these elements as skin-parts. It is less work however and if this is a ‘use it once’ component then I guess it is a valid approach.

<?xml version="1.0" encoding="utf-8"?>
<Group xmlns="http://ns.adobe.com/mxml/2009">
<Script>
  /*... custom behaviour ...*/
</Script>

  <!--Here several GUI Elements are added to the Slider. To do this here is in fact
    bad practice since it breaks the clean separation between View and Model/Controller.
    A better approach would be to extend VSlider and add these elements as skin-parts.
    ...but this is less work;-) -->
  <!-- Background of the component -->
  <Rect width="80" height="200" radiusX="10" radiusY="10">
    <fill>
      <LinearGradient rotation="90">
                <GradientEntry color="0x606060" alpha="1" ratio="0" /> 
                <GradientEntry color="0x303030" alpha="1" ratio="1" /> 
          </LinearGradient>
    </fill>
  </Rect>

  <!-- led display -->
  <Rect width="50" height="20" top="35" horizontalCenter="0">
  <stroke>
    <SolidColorStroke weight="1" color="0xffffff" alpha="0.5"/>
  </stroke>
    <fill>
      <LinearGradient rotation="90">
                <GradientEntry color="0xa0e020" alpha="1" ratio="0" /> 
                <GradientEntry color="0x70bb00" alpha="1" ratio="1" /> 
          </LinearGradient>
    </fill>
  </Rect>

  <!-- 
  TextBox for simple Text. If more advanced TextLayout is needed, 
  then TextGraphic or TextView have more options. Draws Slider Header 
  -->
  <TextBox id="sliderLabel" text="Slider Label" 
    color="{headerLabelColor}"  
    fontFamily="Verdana" 
    fontSize="10"
    textAlign="center" 
    horizontalCenter="0"
    top="15">
  </TextBox>

  <!-- Display for (transformed value) -->
  <TextBox id="sliderValue" text="value" 
    color="0x000000"  
    fontFamily="Verdana" 
    fontSize="9"
    textAlign="center" 
    horizontalCenter="0"
    top="42">
  </TextBox>

  <!-- Group with the Slider -->
  <Group id="sliderComposition" top="70" horizontalCenter="0" height="120">
    <TextBox id="upperRangeLabel" text="max Label" 
      color="0xffffff"  
      fontFamily="Verdana" 
      fontSize="10"
      textAlign="center" 
      horizontalCenter="0"
      top="0">
    </TextBox>
    <!-- use a VSlider with custom skin -->
    <VSlider id="oscSlider" value="500" horizontalCenter="0" verticalCenter="0"
      valueCommit="sliderValueChanged(event);"
      liveDragging="true"
      top="10"
      minimum="0" 
      maximum="1000" 
      width="15" height="100" stepSize="1"
      skinZZ="com.hulstkamp.lab.gumbo.skins.sliders.OscSliderSkin"
      >
    </VSlider>

    <TextBox id="lowerRangeLabel" text="min Label"
      color="0xffffff"  
      fontFamily="Verdana" 
      fontSize="10"
      textAlign="center" 
      horizontalCenter="0"
      bottom="0">
    </TextBox>
  </Group>
</Group>

The component adds some custom behaviour by introducing a callback function to transform the sliders model value.

Get the full code here. Code based on sdk 4.0.0.3135 .

further reading

Working with huge amount of data in Flex 4 (Gumbo)

Findings in how to work with huge amounts of data in Flex 4.

Customize the Spark TextInput Component in Flex 4 (Gumbo). Adding focus and Transitions.

A custom Flex Spark Text-Input.