Re-arrange objects in a VGroup by Drag&Drop (Flex Spark)

Adding drag and drop support for Group components, as well as swapping of children or reorder.
This might seem like a straightforward issue and an easy solution, but as I found out… only list based views have the ability to re-arrange their children via dragging and droping. But there is one hidden gem, all the Group based components have build-in support for drag and drop operations, and whilst the user cannot enable directly the dropEnabled option (which allows the re-arrange like operation), it is fairly easy to create a custom functionality to imitate it.
Continue reading

Flex Spark VideoPlayer FullScreen bug workaround

VideoPlayer has a native bug which causes it, to loose its width and height attributes when the user cancels FullScreen mode.

A workaround is to capture the event and re-enter the player attributes as follows:

Listening to the FULL_SCREEN event at the systemManager

systemManager.stage.addEventListener(FullScreenEvent.FULL_SCREEN,funct ion(e)
{
var event = e.fullScreen;
if(event==false)
{
player.percentHeight=100;
player.percentWidth=100;
player.invalidateDisplayList();
}trace(e);
});

and if it is about to close I re-enter the percentages for the player height and width, and it again works as expected.

I hope this helps someone….

Add Stop Button in spark VideoPlayer

I have searched all around for how to add the Stop button in a Flex spark VideoPlayer.
Here is how:

You’ll need to create two Skins one for the whole VideoPlayer where you declare the stop Button, and one more for the actual stop button

VideoPlayer 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.disabledStates=”0.5″
chromeColor.fullScreenStates=”0xCCCCCC”>
<!– A chrome color of 0xCCCCCC in the fullScreenStates means we ignore the chromeColor property
all together as 0xCCCCCC is essentially just a no-op color transform –>

<!– host component –>
<fx:Metadata>
/**
* @copy spark.skins.spark.ApplicationSkin#hostComponent
*/
[HostComponent(“spark.components.VideoPlayer”)]
</fx:Metadata>

<fx:Script fb:purpose=”styling”>
<![CDATA[
/* Define the skin elements that should not be colorized. */
static private const exclusions:Array = [“videoDisplay”, “playPauseButton”, “scrubBar”,
“currentTimeDisplay”, “timeDivider”, “durationDisplay”,
“volumeBar”, “fullScreenButton”];

/**
* @private
*/
override protected function initializationComplete():void
{
useChromeColor = true;
super.initializationComplete();
}

/**
* @private
*/
override public function get colorizeExclusions():Array
{
return exclusions;
}

/**
* @private
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
dropShadow.visible = getStyle(“dropShadowVisible”);

super.updateDisplayList(unscaledWidth, unscaledHeight);
}
]]>

</fx:Script>

<!– states –>
<s:states>
<s:State name=”uninitialized” stateGroups=”uninitializedStates, normalStates” />
<s:State name=”loading” stateGroups=”loadingStates, normalStates” />
<s:State name=”ready” stateGroups=”readyStates, normalStates” />
<s:State name=”playing” stateGroups=”playingStates, normalStates” />
<s:State name=”paused” stateGroups=”pausedStates, normalStates” />
<s:State name=”stoped” stateGroups=”pausedStates, normalStates” />
<s:State name=”buffering” stateGroups=”bufferingStates, normalStates” />
<s:State name=”playbackError” stateGroups=”playbackErrorStates, normalStates” />
<s:State name=”disabled” stateGroups=”disabledStates, normalStates”/>
<s:State name=”uninitializedAndFullScreen” stateGroups=”uninitializedStates, fullScreenStates” />
<s:State name=”loadingAndFullScreen” stateGroups=”loadingStates, fullScreenStates” />
<s:State name=”readyAndFullScreen” stateGroups=”readyStates, fullScreenStates” />
<s:State name=”playingAndFullScreen” stateGroups=”playingStates, fullScreenStates” />
<s:State name=”pausedAndFullScreen” stateGroups=”pausedStates, fullScreenStates” />
<s:State name=”bufferingAndFullScreen” stateGroups=”bufferingStates, fullScreenStates” />
<s:State name=”playbackErrorAndFullScreen” stateGroups=”playbackErrorStates, fullScreenStates” />
<s:State name=”disabledAndFullScreen” stateGroups=”disabledStates, fullScreenStates”/>
</s:states>

<!– drop shadow –>
<!— @private –>
<s:RectangularDropShadow id=”dropShadow” blurX=”17″ blurY=”17″ alpha=”0.32″ distance=”4″
angle=”90″ color=”#131313″ left=”0″ top=”0″ right=”0″ bottom=”0″
excludeFrom=”fullScreenStates”/>

<!— Video and player controls are clipped if they exceed the size of the
component, but the drop shadow above is not clipped and sizes to the component.
We also set verticalScrollPosition so that when we do clip, rather than clipping
off the bottom first, we clip off the top fist. This is so the player controls
are still visible when we start clipping. –>
<s:Group id=”clippedGroup” clipAndEnableScrolling=”true” left=”0″ top=”0″ right=”0″ bottom=”0″
verticalScrollPosition=”{Math.max(0, 184-clippedGroup.height)}”>

<!– There’s a minimum size for the video and controls. If we go below that
we are clipped. –>
<s:Group minWidth=”263″ minHeight=”184″ left=”0″ right=”0″ top=”0″ bottom=”0″>

<!– background when the videoDisplay doesn’t fill its whole spot –>
<s:Rect bottom=”1″ left=”1″ right=”1″ top=”1″
bottom.fullScreenStates=”0″ left.fullScreenStates=”0″
right.fullScreenStates=”0″ top.fullScreenStates=”0″>
<s:fill>
<s:SolidColor color=”0x000000″ />
</s:fill>
</s:Rect>

<!— @copy spark.components.VideoPlayer#videoDisplay –>
<s:VideoDisplay id=”videoDisplay” bottom=”24″ left=”1″ right=”1″ top=”1″
bottom.fullScreenStates=”0″ left.fullScreenStates=”0″
right.fullScreenStates=”0″ top.fullScreenStates=”0″ />

<!– video player controls –>
<s:Group left=”0″ right=”0″ height=”24″ bottom=”0″ bottom.fullScreenStates=”150″>

<!– actual controls with a maxWidth in non-fullScreen mode –>
<!— @copy spark.components.VideoPlayer#playerControls –>
<s:Group bottom=”0″ horizontalCenter=”0″ left=”0″ right=”0″ maxWidth.fullScreenStates=”755″ id=”playerControls”>

<!— @copy spark.components.VideoPlayer#playPauseButton –>
<s:ToggleButton id=”playPauseButton” left=”0″ bottom=”0″
skinClass=”spark.skins.spark.mediaClasses.normal.PlayPauseButtonSkin”
skinClass.fullScreenStates=”spark.skins.spark.mediaClasses.fullScreen.PlayPauseButtonSkin”
layoutDirection=”ltr”
focusIn=”event.target.depth=1″ focusOut=”event.target.depth=0″ />
<s:ButtonBase id=”stopButton” left=”38″ bottom=”0″ skinClass=”stopSkin” layoutDirection=”ltr” focusIn=”event.target.depth=1″ focusOut=”event.target.depth=0″/>

<!– scrubbar + the currentTime/duration labels –>
<s:Group left=”66″ right=”75″ top=”0″ bottom=”0″>

<!– background for scrubbar + the currentTime/duration –>
<s:Rect left=”0″ right=”0″ top=”0″ bottom=”0″>
<s:fill>
<s:LinearGradient rotation=”90″>
<s:GradientEntry color=”0xFFFFFF” color.fullScreenStates=”0x585858″ alpha.fullScreenStates=”0.55″/>
<s:GradientEntry color=”0xDCDCDC” color.fullScreenStates=”0x1E1E1E” alpha.fullScreenStates=”0.55″/>
</s:LinearGradient>
</s:fill>
</s:Rect>

<!– fill highlight (exclude in fullScreen) –>
<s:Rect left=”1″ right=”1″ top=”1″ height=”11″ excludeFrom=”fullScreenStates”>
<s:fill>
<s:SolidColor color=”0xFFFFFF” alpha=”0.3″ />
</s:fill>
</s:Rect>

<!– one pixel border –>
<s:Rect left=”1″ right=”1″ top=”1″ bottom=”1″>
<s:stroke>
<s:LinearGradientStroke weight=”1″ rotation=”90″>
<s:GradientEntry color=”0xFEFEFE” color.fullScreenStates=”0xFFFFFF” alpha.fullScreenStates=”0.12″ />
<s:GradientEntry color=”0xEAEAEA” color.fullScreenStates=”0xFFFFFF” alpha.fullScreenStates=”0.09″ />
</s:LinearGradientStroke>
</s:stroke>
</s:Rect>

<!– border for the scrubbar/time label controls –>
<s:Rect left=”-1″ right=”0″ top=”0″ bottom=”0″>
<s:stroke>
<s:SolidColorStroke color=”0x131313″ color.fullScreenStates=”0x222222″ alpha.fullScreenStates=”0.66″ />
</s:stroke>
</s:Rect>

<!– scrub bar + currentTime/duration in a HorizontalLayout –>
<s:Group left=”0″ right=”0″ height=”23″ bottom=”0″>
<s:layout>
<s:HorizontalLayout verticalAlign=”middle” gap=”1″ />
</s:layout>

<!– spacer –>
<s:Rect width=”7″ height=”1″ />

<!— @copy spark.components.VideoPlayer#scrubBar –>
<s:ScrubBar id=”scrubBar” width=”100%” liveDragging=”true”
skinClass=”spark.skins.spark.mediaClasses.normal.ScrubBarSkin”
skinClass.fullScreenStates=”spark.skins.spark.mediaClasses.fullScreen.ScrubBarSkin” />

<!– spacer –>
<s:Rect width=”8″ height=”1″ />

<!— @copy spark.components.VideoPlayer#currentTimeDisplay –>
<s:Label id=”currentTimeDisplay” color.fullScreenStates=”0xFFFFFF” />

<!— @private –>
<s:Label id=”timeDivider” text=”/” color.fullScreenStates=”0xFFFFFF” />

<!— @copy spark.components.VideoPlayer#durationDisplay –>
<s:Label id=”durationDisplay” color.fullScreenStates=”0xFFFFFF” />

<!– spacer –>
<s:Rect width=”8″ height=”1″ />
</s:Group>

</s:Group>

<!— @copy spark.components.VideoPlayer#volumeBar –>
<s:VolumeBar id=”volumeBar” snapInterval=”.01″ stepSize=”.01″ liveDragging=”true”
right=”37″ bottom=”0″
layoutDirection=”ltr”
skinClass=”spark.skins.spark.mediaClasses.normal.VolumeBarSkin”
skinClass.fullScreenStates=”spark.skins.spark.mediaClasses.fullScreen.VolumeBarSkin”
focusIn=”event.target.depth=1″ focusOut=”event.target.depth=0″ />

<!— @copy spark.components.VideoPlayer#fullScreenButton –>
<s:Button id=”fullScreenButton” right=”0″ bottom=”0″ label=”Fullscreen”
skinClass=”spark.skins.spark.mediaClasses.normal.FullScreenButtonSkin”
skinClass.fullScreenStates=”spark.skins.spark.mediaClasses.fullScreen.FullScreenButtonSkin”
focusIn=”event.target.depth=1″ focusOut=”event.target.depth=0″ />

</s:Group>

</s:Group>

<!– border –>
<s:Rect left=”0″ right=”0″ top=”0″ bottom=”0″ excludeFrom=”fullScreenStates”>
<s:stroke>
<s:SolidColorStroke color=”0x131313″ />
</s:stroke>
</s:Rect>

</s:Group>
</s:Group>
</s:SparkSkin>

————————————————————————-
::: Stop Button 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″ >

<!– host component –>
<fx:Metadata>
[HostComponent(“spark.components.supportClasses.ButtonBase”)]
</fx:Metadata>

<fx:Script fb:purpose=”styling”>
/* Define the skin elements that should not be colorized. */
static private const exclusions:Array = [“stopSymbol”];

/**
* @private
*/
override public function get colorizeExclusions():Array {return exclusions;}

/* Define the symbol fill items that should be colored by the “symbolColor” style.*/
static private const symbols:Array = [“stopSymbolFill1_1”, “stopSymbolFill1_2”,
“stopSymbolFill1_3”, “stopSymbolFill1_4”, “stopSymbolFill1_5”];

/**
* @private
*/
override public function get symbolItems():Array {return symbols};

/**
* @private
*/
override protected function initializationComplete():void
{
useChromeColor = true;
super.initializationComplete();
}
</fx:Script>

<!– states –>
<s:states>
<s:State name=”up” />
<s:State name=”over” stateGroups=”overStates” />
<s:State name=”down” stateGroups=”downStates” />
<s:State name=”disabled” stateGroups=”disabledStates” />
</s:states>

<!– layer 1: fill –>
<s:Rect left=”1″ right=”1″ top=”1″ bottom=”1″>
<s:fill>
<s:LinearGradient rotation=”90″>
<s:GradientEntry color=”0xFFFFFF”
color.overStates=”0xCACACA”
color.downStates=”0xA8A8A8″ />
<s:GradientEntry color=”0xDCDCDC”
color.overStates=”0x8D8D8D”
color.downStates=”0x6B6B6B”/>
</s:LinearGradient>
</s:fill>
</s:Rect>

<!– layer 2: One pixel stroke inside border (exclude in downStates) –>
<s:Rect left=”1″ right=”1″ top=”1″ bottom=”1″ excludeFrom=”downStates”>
<s:stroke>
<s:LinearGradientStroke weight=”1″ rotation=”90″>
<s:GradientEntry color=”0xFEFEFE” alpha.overStates=”0.22″ />
<s:GradientEntry color=”0xEAEAEA” alpha.overStates=”0.22″ />
</s:LinearGradientStroke>
</s:stroke>
</s:Rect>

<!– layer 3: fill highlight (exclude in downStates) –>
<s:Rect left=”1″ right=”1″ top=”1″ height=”11″ excludeFrom=”downStates”>
<s:fill>
<s:SolidColor color=”0xFFFFFF”
alpha=”0.3″
alpha.overStates=”0.12″ />
</s:fill>
</s:Rect>

<!– layer 4: downstate inset border (include only in downStates) –>
<s:Rect left=”1″ top=”1″ right=”1″ height=”1″ includeIn=”downStates”>
<s:fill>
<s:SolidColor color=”0x000000″ alpha=”0.4″ />
</s:fill>
</s:Rect>
<s:Rect left=”1″ top=”2″ right=”1″ height=”1″ includeIn=”downStates”>
<s:fill>
<s:SolidColor color=”0x000000″ alpha=”0.12″ />
</s:fill>
</s:Rect>
<s:Rect left=”1″ top=”1″ bottom=”1″ width=”1″ includeIn=”downStates”>
<s:fill>
<s:SolidColor color=”0x000000″ alpha=”0.12″ />
</s:fill>
</s:Rect>
<s:Rect right=”1″ top=”1″ bottom=”1″ width=”1″ includeIn=”downStates”>
<s:fill>
<s:SolidColor color=”0x000000″ alpha=”0.12″ />
</s:fill>
</s:Rect>

<!– layer 5: border – put on top of the fill so it doesn’t disappear when scale is less than 1 –>
<s:Rect left=”0″ right=”0″ top=”0″ bottom=”0″ width=”28″ height=”24″>
<s:stroke>
<s:SolidColorStroke color=”0x131313″ />
</s:stroke>
</s:Rect>

<!— Defines the Stop symbol. –>
<s:Group horizontalCenter=”0″ verticalCenter=”0″ id=”stopSymbol”>

<!– triangle –>
<s:Rect left=”0″ top=”0″ height=”11″ width=”10″>
<s:fill>
<s:LinearGradient rotation=”90″>
<!— @private –>
<s:GradientEntry color=”0x252525″ alpha=”0.75″ ratio=”0.1″ id=”stopSymbolFill1_1″/>
<!— @private –>
<s:GradientEntry color=”0x404040″ alpha=”0.75″ ratio=”0.2″ id=”stopSymbolFill1_2″/>
<!— @private –>
<s:GradientEntry color=”0x4B4B4B” alpha=”0.75″ ratio=”0.55″ id=”stopSymbolFill1_3″/>
<!— @private –>
<s:GradientEntry color=”0x424242″ alpha=”0.75″ ratio=”0.9″ id=”stopSymbolFill1_4″/>
<!— @private –>
<s:GradientEntry color=”0xC4C4C4″ alpha=”0.75″ ratio=”1.0″ id=”stopSymbolFill1_5″/>
</s:LinearGradient>
</s:fill>
</s:Rect>
</s:Group>

</s:SparkSkin>

————————————————————-
::: SAMPLE Video Player :::

<s:VideoPlayer
source=”{customURL2}”
width=”100%” height=”100%”
loop=”true” skinClass=”VCPlayer”
complete=”vpCompleteHandler(event);”
mediaPlayerStateChange=”vpMediaPlayerStateChangeHandler(event);” autoPlay=”true” autoRewind=”true” id=”flayer” pauseWhenHidden=”true” dropShadowVisible=”false”/>