I'm following Joe Ward's Pixel Bender basics for Flex and AIR tutorial and updating it for Flex 4.5 Flashplayer 11.
While working on the grainBlend section It Works great, if I have an "Alert" message pop up. Otherwise the shader does not refresh/update when the HSlider is changed.
In other word: The script runs IF I have an active Alert message. If I remove the Alert Message, the blendShader only works once, and never updates afterwards.
ScriptFlow:
Init() OK
create shader OK
detect HSlider Change OK
updateFilter() OK
update Shader's turbulace value OK
update image "noise" shader and redraw NOT WORKING
I believe the following excerpt from the tutorial may be the issue. "...Because a shader object is cloned when you set the blendShader property of a display object, you cannot simply change the parameter of the original Shader object. You must also reassign the updated Shade object to the blendShader property...."
shader.data.turbulence.value = [turbulence.value];
noise.blendMode = BlendMode.SHADER;
noise.blendShader = shader;
Flex code
<?xml version="1.0" encoding="utf-8"?>
<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"
contentCreationComplete="init()"
backgroundColor="0x666666">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.SliderEvent;
//Embed the Pixel Bender kernel in the output SWF
[Embed(source="kernels/grainblend.pbj", mimeType="application/octet-stream")]
private var GrainBlendKernel:Class;
//Create the Shader object
[Bindable]
private var shader:Shader = new Shader( new GrainBlendKernel() );
private function init():void
{
//Set the slider values based on the parameter metadata
turbulence.minimum = shader.data.turbulence.minValue;
turbulence.maximum = shader.data.turbulence.maxValue;
turbulence.value = shader.data.turbulence.defaultValue;
turbulence.addEventListener( SliderEvent.CHANGE, updateFilter );
//Apply the blend
noise.blendShader = shader;
}
private function updateFilter( event:Event ):void
{
trace(turbulence.value);//print slider
//Alert.show("Hit");
shader.data.turbulence.value = [turbulence.value];
trace("shader's value: "+shader.data.turbulence.value);
noise.blendMode = BlendMode.SHADER;
noise.blendShader = shader;
}
]]>
</fx:Script>
<s:VGroup width="100%">
<s:HGroup width="100%" height="100%" horizontalAlign="center" verticalAlign="top">
<s:VGroup>
<mx:Canvas width="195" height="194" backgroundColor="#663300"/>
<s:Label text="Background" textAlign="center" width="196"/>
</s:VGroup>
<s:VGroup>
<s:Image source="img/noise.jpg" width="195" height="194"/>
<s:Label text="Perlin noise" width="196" textAlign="center"/>
</s:VGroup>
<s:VGroup>
<mx:Canvas width="195" height="194" backgroundColor="#663300">
<s:Image source="img/noise.jpg" id="noise" width="195" height="194"/>
</mx:Canvas>
<s:Label text="Grain blend" width="196" textAlign="center"/>
</s:VGroup>
</s:HGroup>
<s:HGroup width="100%" horizontalAlign="center" verticalAlign="top">
<s:Label text="{turbulence.value}"/>
<s:HSlider id="turbulence" width="200"/>
</s:HGroup>
</s:VGroup>
Pixel Bender Kernel
<languageVersion: 1.0;>
kernel GrainBlend
< namespace : "com.adobe.example";
vendor : "Adobe Systems Inc.";
version : 1;
description : "Creates a wood grain or marbleing effect"; >
{
input image4 background;
input image4 noise;
output pixel4 dst;
parameter float turbulence
<
maxValue : 500.0;
minValue : 0.0;
defaultValue : 150.0;
>;
void evaluatePixel()
{
pixel4 a = sampleNearest(background, outCoord());
pixel4 b = sampleNearest(noise, outCoord());
float alpha = a.a; //save the original alpha
if( (b.a > 0.0) && (a.a > 0.0)){
float seed = outCoord().x + (((b.r + b.g + b.b)/3.0) * turbulence);
float grain = (0.7 * sin(seed) + 0.3 * sin(2.0 * seed + 0.3) + 0.2 * sin(3.0 * seed + 0.2));
dst = sampleNearest(background, outCoord()) * (grain + 0.5);
dst.a = alpha; //restore the original alpha
}
else {
//Just copy the background pixel outside the area of the noise image
dst = sampleNearest(background, outCoord());
}
}
}
I gave up on blendShader. I recreated it using filters. It works now. Also, I dynamically created the brown background and the perlin noise.
See below!
<?xml version="1.0" encoding="utf-8"?>
<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"
creationComplete="init()"
backgroundColor="0x666666">
<fx:Script>
<![CDATA[
import mx.events.SliderEvent;
import spark.filters.ShaderFilter;
//Embed the Pixel Bender kernel in the output SWF
[Embed(source="kernels/grainblend.pbj", mimeType="application/octet-stream")]
private var GrainBlendKernel:Class;
//Create the Shader object
private var shader:Shader = new Shader( new GrainBlendKernel() );
private var shaderFilter:ShaderFilter = new ShaderFilter(shader);
private var myBrown:BitmapData;
private var myPerlin:BitmapData;
private function init():void
{
myPerlin = new BitmapData(200, 200, false, 0x00CCCCCC);
myBrown = new BitmapData(200, 200, false, 0x00663300);
//Set the slider values based on the parameter metadata
turbulence.minimum = shader.data.turbulence.minValue;
turbulence.maximum = shader.data.turbulence.maxValue;
turbulence.value = shader.data.turbulence.defaultValue;
turbulence.addEventListener( SliderEvent.CHANGE, updateFilter );
myPerlin.perlinNoise(100, 80, 6, Math.floor(Math.random() * 10), false, true, 7, true, null);
//Set the displayed images to the perlinNoise
perlinNoise.source = myGrain.source =myPerlin;
//Set the background image to Brown
backGround.source = myBrown;
shader.data.background.input = myBrown;
myGrain.filters = [shaderFilter];
}
private function updateFilter( event:Event ):void
{
shader.data.turbulence.value = [turbulence.value];
myGrain.filters = [shaderFilter];
}
]]>
</fx:Script>
<s:VGroup width="100%">
<s:HGroup width="100%" height="100%" horizontalAlign="center" verticalAlign="top">
<s:VGroup>
<s:BitmapImage id="backGround" width="200" height="200"/>
<s:Label text="Background" textAlign="center" width="200"/>
</s:VGroup>
<s:VGroup>
<s:BitmapImage id="perlinNoise" width="200" height="200"/>
<s:Label text="Perlin noise" width="200" textAlign="center"/>
</s:VGroup>
<s:VGroup>
<s:BitmapImage id="myGrain" width="200" height="200" />
<s:Label text="Grain blend" width="200" textAlign="center"/>
</s:VGroup>
</s:HGroup>
<s:HGroup width="100%" horizontalAlign="center" verticalAlign="top">
<s:Label text="{turbulence.value}"/>
<s:HSlider id="turbulence" width="200"/>
</s:HGroup>
</s:VGroup>
</s:Application>`
Related
Is it possible to fill anchors in Konva.Transformer with shape? I mean, would I have to add another layer in order to make custom anchors or can I do something right in Transformer component?
return (
<>
<Rect
x={100}
y={100}
fill="red"
width={200}
height={100}
ref={rectRef}
/>
<Transformer
ref={transformerRef}
rotateEnabled
rotateAnchorOffset={48}
keepRatio={false}
anchorFill={'yellow'}
borderDash={[5,10]}
padding={10}
/>
At the current moment konva#7.2.2 doesn't have support for such functions.
As a workaround you can:
create an external canvas with the size of custom shape
Manually draw into that canvas
Manually style required anchors with that canvas to use it as patternImage.
const trRef = React.useRef();
const anchorShapeCanvas = React.useMemo(() => {
const canvas = document.createElement("canvas");
canvas.width = 12;
canvas.height = 12;
const ctx = canvas.getContext("2d");
ctx.strokeStyle = "black";
ctx.beginPath();
ctx.lineTo(0, 0);
ctx.lineTo(12, 0);
ctx.lineTo(12, 4);
ctx.lineTo(4, 4);
ctx.lineTo(4, 12);
ctx.lineTo(0, 12);
ctx.closePath();
ctx.stroke();
ctx.stroke = "2px";
return canvas;
}, []);
React.useEffect(() => {
if (isSelected) {
// we need to attach transformer manually
trRef.current.nodes([shapeRef.current]);
trRef.current.find(".top-left").fillPriority("pattern");
trRef.current.find(".top-left").fillPatternImage(anchorShapeCanvas);
trRef.current.find(".top-left").strokeEnabled(false);
trRef.current.getLayer().batchDraw();
}
}, [isSelected]);
https://codesandbox.io/s/react-konva-fill-pattern-for-transformer-anchor-45zc5?file=/src/index.js:236-1151
I have the following code in alertDialog.SetPositiveButton
alertConfirmTransfer.SetPositiveButton("ДА", delegate
{
ProgressBar progressBar = FindViewById<ProgressBar>(Resource.Id.progressBar);
alertConfirmTransfer.Cancel();
MobileSellReference.Service1 service = new
MobileSellReference.Service1();
progressBar.IncrementProgressBy(10);
service.Url = settings.Synchronization.Msellurl;
progressBar.IncrementProgressBy(10);
byte[][] resultFromService = service.ToPPC(basedataZipName, objectId);
progressBar.IncrementProgressBy(10);
byte[] basedataZipFile = resultFromService[0];
byte[] dutybasedataZipFile = resultFromService[3];
byte[] tranbasedataZipFile = resultFromService[2];
byte[] vendbasedataZipFile = resultFromService[1];
progressBar.IncrementProgressBy(10);
string basedataZipFullPath = GlobalVariables.fromserverFolderPath + "/" + basedataZipName;
string dutybasedataZipFullPath = GlobalVariables.fromserverFolderPath + "/" + dutybasedataZipName;
string tranbasedataZipFullPath = GlobalVariables.fromserverFolderPath + "/" + tranbasedataZipName;
string vendbasedataZipFullPath = GlobalVariables.fromserverFolderPath + "/" + vendbasedataZipName;
Helper.DeleteAllFromFolders(GlobalVariables.fromserverFolderPath, GlobalVariables.vendingFolderPath, GlobalVariables.tranFolderPath, GlobalVariables.debtFolderPath);
progressBar.IncrementProgressBy(10);
Helper.EmptyMobileSellDB();
progressBar.IncrementProgressBy(10);
System.IO.File.WriteAllBytes(basedataZipFullPath, basedataZipFile);
progressBar.IncrementProgressBy(10);
System.IO.File.WriteAllBytes(dutybasedataZipFullPath, dutybasedataZipFile);
progressBar.IncrementProgressBy(10);
System.IO.File.WriteAllBytes(tranbasedataZipFullPath, tranbasedataZipFile);
progressBar.IncrementProgressBy(10);
System.IO.File.WriteAllBytes(vendbasedataZipFullPath, vendbasedataZipFile);
progressBar.IncrementProgressBy(10);
}
I want the progress bar to increment in the places I specified . But when I run the app I have only progress bar circulating infinetly. I want to increase by and by. And After reaching 100 to dissapear. I've found too little information how to do that in Xamarin.Android and none of it helped me.
After the line where you findviewbyreference :
ProgressBar progressBar = FindViewById<ProgressBar>(Resource.Id.progressBar);
Set the max progress to 100 and then set the current progress to 0.
progressBar.Max = 100;
progressBar.Progress = 0;
Then incrementing the progress should work.
progressBar.IncrementProgressBy(10);
// Try adding delay after/before you set the progress.
// You can put the below code in a method and call that method after updating the progress bar.
try
{
Thread.Sleep(2000);
}
catch (Exception exception)
{
Android.Util.Log.Error("Error",exception.Message);
}
cs file
MobileSellReference.Service1 service = new MobileSellReference.Service1();
service.Url = settings.Synchronization.Msellurl;
progressBar.IncrementProgressBy(10);
Thread.Sleep(2000);
byte[][] resultFromService = service.ToPPC(basedataZipName, objectId);
progressBar.IncrementProgressBy(50);
Thread.Sleep(2000);
byte[] basedataZipFile = resultFromService[0];
byte[] dutybasedataZipFile = resultFromService[3];
byte[] tranbasedataZipFile = resultFromService[2];
byte[] vendbasedataZipFile = resultFromService[1];
string basedataZipFullPath = GlobalVariables.fromserverFolderPath + "/" + basedataZipName;
string dutybasedataZipFullPath = GlobalVariables.fromserverFolderPath + "/" + dutybasedataZipName;
string tranbasedataZipFullPath = GlobalVariables.fromserverFolderPath + "/" + tranbasedataZipName;
string vendbasedataZipFullPath = GlobalVariables.fromserverFolderPath + "/" + vendbasedataZipName;
Helper.DeleteAllFromFolders(GlobalVariables.fromserverFolderPath, GlobalVariables.vendingFolderPath, GlobalVariables.tranFolderPath, GlobalVariables.debtFolderPath);
progressBar.IncrementProgressBy(5);
Thread.Sleep(2000);
Helper.EmptyMobileSellDB();
progressBar.IncrementProgressBy(5);
Thread.Sleep(2000);
System.IO.File.WriteAllBytes(basedataZipFullPath, basedataZipFile);
progressBar.IncrementProgressBy(10);
Thread.Sleep(2000);
System.IO.File.WriteAllBytes(dutybasedataZipFullPath, dutybasedataZipFile);
progressBar.IncrementProgressBy(10);
Thread.Sleep(2000);
System.IO.File.WriteAllBytes(tranbasedataZipFullPath, tranbasedataZipFile);
progressBar.IncrementProgressBy(10);
Thread.Sleep(2000);
System.IO.File.WriteAllBytes(vendbasedataZipFullPath, vendbasedataZipFile);
The code above is in alert.SetPositiveButton("Yes" ....) method
the axml file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="25px"
android:minHeight="25px">
<LinearLayout
android:orientation="vertical"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/linearLayout1">
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/progressBar" />
<Button
android:text="Взема данни"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btnGetData" />
<Button
android:text="Предава данни"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btnTransferData" />
<Button
android:text="Пълна синхронизация"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btnFullSynchronization" />
</LinearLayout>
I overlay chrome://browser/content/browser.xul with an .xul adding a button to the main-menu. clicking it opens another ChromeWindow with a .xul-window.
var ww = Components.classes["#mozilla.org/embedcomp/window-watcher;1"].getService(Components.interfaces.nsIWindowWatcher);
var bgwin = ww.openWindow(null, 'chrome://myextension/content/myBrowser.xul', 'MyName', "chrome, resizable=yes, width=1024, height=600, minimizable, maximizable", []);
chrome://myextension/content/myBrowser.xul:
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window id="myextension-my-browser"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="mybrowser"
windowtype="mybrowser"
>
<script type="application/x-javascript" src="chrome://myextension/content/myBrowser.js" />
<browser id="browser" type="content" flex="1" src="about:blank" />
</window>
which works fine. but then, i want to hide that window. make it completely invisible, doing (in myBrowser.js). But nothing happens:
var topXulWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsIDocShellTreeItem).treeOwner
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIXULWindow);
var appShellService = Components.classes["#mozilla.org/appshell/appShellService;1"].getService(Components.interfaces.nsIAppShellService);
appShellService.unregisterTopLevelWindow(topXulWindow);
My Question
What am i doing wrong? Why doesn't the window disappear?
Prepend you code with the following snippet
var basewindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsIDocShell)
.QueryInterface(Components.interfaces.nsIDocShellTreeItem).treeOwner
.QueryInterface(Components.interfaces.nsIBaseWindow);
basewindow.visibility = false;
basewindow.enabled = false;
// now unregister
Action Script
I'm having trouble with timer function.
I want to make follow program.
First:generate random numbers and put up array.
Second:
carry out function with 3 second interval by stored array.
but When using of timer function,I can't use argument of function that shoule be carry out interval 3second.
error message:
RangeError: Error #1125: The index 7 is out of range 4.
at views::twoHomeView/onTimer()[C:\Users\Kinect\Adobe Flash Builder 4.6\yattah\src\views\twoHomeView.mxml:26]
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
<?xml version="1.0" encoding="utf-8"?>
<fx:Script>
<![CDATA[
import flash.display.Sprite;
import flash.events.TimerEvent;
import flash.utils.Timer;
private var timer:Timer;
public function Main()
{
timer = new Timer(1000, 3);
timer.addEventListener(TimerEvent.TIMER, onTimer);
timer.start();
}
var kaisu:int =0;
private function onTimer(event:TimerEvent):void
{
for(var i:int;i<n.length;i++){
kaisu += 1;
display(n[kaisu]);
}
}
public var n:Vector.<int> = new Vector.<int>(4);
public var a:int =0;
public var s:int =0;
function display(q:int):void{//show the picture(ue,migi,shita,hidari) 0=↑1=→2=↓3=←
if(q ==0)
{
ue.visible= true;
migi.visible= false;
shita.visible= false;
hidari.visible= false;
}
else if(q ==1)
{
ue.visible= false;
migi.visible= true;
shita.visible= false;
hidari.visible= false;
}
else if(q ==2)
{
ue.visible= false;
migi.visible= false;
shita.visible= true;
hidari.visible= false;
}
else
{
ue.visible= false;
migi.visible= false;
shita.visible= false;
hidari.visible= true;
}
}
protected function button1_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
display(0);
}
protected function button2_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
display(0);
}
protected function right_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
display(1);
}
function wait(time:int, handler:Function):void
{
var timeri:Timer = new Timer(time, 1);
timeri.addEventListener(TimerEvent.TIMER_COMPLETE, timerHandler);
timeri.start();
function timerHandler(event:TimerEvent):void
{
handler();
timeri.removeEventListener(TimerEvent.TIMER_COMPLETE, timerHandler);
}
}
function lv1():void{
}
function showMC():void//put random number in array
{
for(var i:int;i<n.length;i++)
{ var r:int = Math.floor(Math.random() * 4);
n[i]=r;
}
point.text = n[0]+""+" "+n[1]+" "+n[2]+" "+n[3];
}
]]>
</fx:Script>
<fx:Declarations>
</fx:Declarations>
<s:Image x="-31" y="-40" width="383" height="486" source="assets/yattah.jpg"/>
<s:Button id="left" x="13" y="304" width="50" height="50" label="←"
click="button1_clickHandler(event)"/>
<s:Label id ="point" x="19" y="7" text="点"/>
<s:Button id="up" x="60" y="257" width="50" height="50" label="↑"
click="button2_clickHandler(event)"/>
<s:Button id="right" x="107" y="304" width="50" height="50" label="→"
click="right_clickHandler(event)"/>
<s:Button id="down" x="59" y="352" width="50" height="50" label="↓"
/>
<s:Button x="260" y="309" width="50" height="50" label="A" click="Main()"/>
<s:Button x="207" y="359" width="50" label="B" click="showMC()"/>
<s:Image id="ue" x="75" y="33" visible="false" smooth="true" source="assets/ue.png"/>
<s:Image id="shita" x="80" y="49" smooth="true" source="assets/shita.png"/>
<s:Image id="hidari" x="75" y="55" smooth="true" source="assets/hidari.png"/>
<s:Image id="migi" x="80" y="49" smooth="true" source="assets/migi.png"/>
<s:Image id="good" x="-21" y="84" width="363" height="103" visible="false" source="assets/good.png"/>
Well, you are creating a Vector that has 4 elements in it:
public var n:Vector.<int> = new Vector.<int>(4)
Then in your timer event handler, you are iterating from 0 to 5 ... so you are getting the out of bounds error:
for(var i:int;i<5;i++) {
kaisu += kaisu+1;
display(n[kaisu]);
}
This is further complicated by your member variable kaisu which you are incrementing in a funny way. I believe this is causing the error to happen before reaching the end of that for loop. You should probably make this variable a local variable (declare it in the onTimer() function, rather than outside of the function) ... and increment it like this:
kaisu += 1; // or kaisu++;
Finally, if you look at your wait() method, you are declaring a local Timer object. That timer can be garbage collected when the wait() function finishes, and it's possible that you never get any events from that timer object. To fix that, just move the declaration for timeri outside of the wait() function (make it a member variable). This is unrelated to the error but may become a problem later.
i have a TitleWindow popup which opens a videoDisplay to play a video when i click on a thumb.What i want is my popup to resize and the video inside it but to maintain its original aspect ratio and not stretch...
any ideas?
Thanks a lot! Here is my popUp:
<?xml version="1.0" encoding="utf-8"?>
<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
close="CloseWindow(event)" >
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.events.CloseEvent;
import mx.events.ResizeEvent;
import mx.managers.PopUpManager;
[Bindable]public var mediaServerUrl:String;
[Bindable]public var videoFolder:String;
[Bindable]public var filename:String;
[Bindable]public var comments:String;
private var ns:NetStream;
private var nc:NetConnection;
private var video:Video;
private var meta:Object;
private function ns_onMetaData(item:Object):void {
trace("meta");
meta = item;
// Resize Video object to same size as meta data.
video.width = item.width;
video.height = item.height;
// Resize UIComponent to same size as Video object.
myVid.width = video.width;
myVid.height = video.height;
}
private function fetch_rec():void {
var nsClient:Object = {};
nsClient.onMetaData = ns_onMetaData;
nc = new NetConnection();
nc.connect(null);
ns = new NetStream(nc);
ns.client = nsClient;
video = new Video(myVid.width,myVid.height);
video.attachNetStream(ns);
video.smoothing=true;
myVid.addChild(video);
ns.play(mediaServerUrl+"/"+videoFolder+"/"+filename+".flv");
}
protected function CloseWindow(event:CloseEvent):void
{
ns.close();
nc.close();
PopUpManager.removePopUp(this);
}
]]>
</fx:Script>
<mx:VideoDisplay id="myVid" visible="true" x="0" bottom="50" width="100%" height="100%"
maintainAspectRatio="true"
autoPlay="true"
creationComplete="fetch_rec()"
playheadUpdate="progBar.setProgress(myVid.playheadTime,myVid.totalTime)"/>
<mx:ProgressBar id="progBar" left="10" right="10" bottom="60" height="10" label="" mode="manual"/>
<s:Label x="10" bottom="30" text="Σχόλια:"/>
<s:Label x="10" bottom="10" text="{comments}"/></s:TitleWindow>
to call this popup i do:
protected function launchPopUp(event:MouseEvent):void
{
if(list.selectedItem){
win = new ViewVideoPopUp();
win.width = this.width;
win.height = this.height;
//give what is needed to play the video selected
win.videoFolder = videoFolder; // the video's folder name
win.mediaServerUrl = mediaServerUrl; // the media server url
win.filename = list.selectedItem.filename; // the file to be played
win.comments = list.selectedItem.comments; // the comments left for that
win.title = list.selectedItem.name+" στις "+list.selectedItem.date; //title of the window
this.addEventListener(ResizeEvent.RESIZE, window_resize);
PopUpManager.addPopUp(win,this,true);
PopUpManager.centerPopUp(win);
}
}
EDIT (12/15):
OK, I tried your code and added a method to force the aspect ratio of the video based on the aspect ratio of the parent container. I put a HGroup around the VideoDisplay component, and used that to figure out how the video should be sized. It also centers the video in the popup if the window and video are different sizes.
<?xml version="1.0" encoding="utf-8"?>
<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
close="CloseWindow(event)" autoLayout="true">
<fx:Script>
<![CDATA[
import mx.events.CloseEvent;
import mx.events.ResizeEvent;
import mx.managers.PopUpManager;
[Bindable]public var mediaServerUrl:String;
[Bindable]public var videoFolder:String;
[Bindable]public var filename:String;
[Bindable]public var comments:String;
private var ns:NetStream;
private var nc:NetConnection;
private var video:Video;
private var meta:Object;
private function ns_onMetaData(item:Object):void {
trace("meta");
meta = item;
var vidAspectRatio:Number = item.width / item.height;
var titleWindowAspectRatio:Number = vidContainer.width / vidContainer.height;
// Resize Video object to same size as meta data.
if ( vidAspectRatio < titleWindowAspectRatio ) // TitleWindow too wide
{
video.height = vidContainer.height;
video.width = video.height * vidAspectRatio;
}
else if ( vidAspectRatio > titleWindowAspectRatio ) // TitleWindow too tall
{
video.width = vidContainer.width;
video.height = video.width / vidAspectRatio;
}
else // TitleWindow and Video have same aspect ratio and fits just right
{
video.width = vidContainer.width;
video.height = vidContainer.height;
}
// Resize UIComponent to same size as Video object.
myVid.width = video.width;
myVid.height = video.height;
}
private function fetch_rec():void {
var nsClient:Object = {};
nsClient.onMetaData = ns_onMetaData;
nc = new NetConnection();
nc.connect(null);
ns = new NetStream(nc);
ns.client = nsClient;
video = new Video(myVid.width,myVid.height);
video.attachNetStream(ns);
video.smoothing=true;
myVid.addChild(video);
ns.play("../swf/barsandtone.flv");
}
protected function CloseWindow(event:CloseEvent):void
{
ns.close();
nc.close();
PopUpManager.removePopUp(this);
}
]]>
</fx:Script>
<s:HGroup id="vidContainer" verticalAlign="middle" horizontalAlign="center" height="100%" width="100%" bottom="50" >
<mx:VideoDisplay id="myVid" visible="true"
autoPlay="true"
creationComplete="fetch_rec()"
playheadUpdate="progBar.setProgress(myVid.playheadTime,myVid.totalTime)"/>
</s:HGroup>
<mx:ProgressBar id="progBar" left="10" right="10" bottom="60" height="10" label="" mode="manual"/>
<s:Label x="10" bottom="30" text="Σχόλια:"/>
<s:Label x="10" bottom="10" text="{comments}"/>
</s:TitleWindow>