I use a fileReference.browse() to select an image file from the harddrive.
How can I check the Width and Height of the selected image file please?
Thank you!
Load the fileReference.data into a Loader using loadBytes(). Then you'll have: sourceBMP:Bitmap = loader.content as Bitmap;
Here is a sample code:
MXML part:
<fx:Declarations>
<net:FileReference id="fileReference"
select="fileReference_select(event);"
complete="fileReference_complete(event);" />
</fx:Declarations>
<s:Button id="uplaodImageBtn"
label="Upload Image"
click="uplaodImageBtn_clickHandler()"/>
AS3 part:
private function uplaodImageBtn_clickHandler() : void {
var arr:Array = [];
arr.push(new FileFilter("Images", ".gif;*.jpeg;*.jpg;*.png"));
fileReference.browse(arr);
}
private function fileReference_select(evt:Event):void {
fileReference.load();
}
private function fileReference_complete(event:Event):void {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loader_complete);
loader.loadBytes(fileReference.data);
}
public function loader_complete (event:Event) : void {
var sourceBMP:Bitmap = event.currentTarget.loader.content as Bitmap;
Alert.show(sourceBMP.width + ', ' +sourceBMP.height);
}
From the context of Flex, I'm pretty sure that onc you get the results back from a browserr, it is only a byteArray. In theory if you use that byteArray as the source for an image tag you'll be able to get the height and width that way, once you add that image to a container.
Otherwise, I do not believe there is an easy way to get such metadata info from local files using Flex.
You should be able to read the image.sourceWidth and image.sourceHeight if you wait for the image source property to update. This will give you the unscaled original values.
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
private function browseImage(event:MouseEvent):void {
var arr:Array = [];
arr.push(new FileFilter("Images", ".gif;*.jpeg;*.jpg;*.png"));
imageFileReference.browse(arr);
}
private function imageSelect(evt:Event):void {
imageFileReference.load();
}
private function imageComplete(evt:Event):void {
image.source = smallImageFileReference.data;
image.addEventListener(FlexEvent.UPDATE_COMPLETE, getImageSize);
}
private function getImageSize(evt:FlexEvent):void {
image.removeEventListener(FlexEvent.UPDATE_COMPLETE, getImageSize);
imageWidth.text = image.sourceWidth + "px";
imageHeight.text = image.sourceHeight + "px";
}
]]>
</fx:Script>
<fx:Declarations>
<net:FileReference id="imageFileReference"
select="imageSelect(event)"
complete="imageComplete(event)"/>
</fx:Declarations>
<s:VGroup width="100%" height="100%">
<s:HGroup width="100%" verticalAlign="middle">
<s:Label fontWeight="bold" text="Width:" />
<mx:Text id="imageWidth" />
</s:HGroup>
<s:HGroup width="100%" verticalAlign="middle">
<s:Label fontWeight="bold" text="Height:" />
<mx:Text id="imageHeight" />
</s:HGroup>
<s:Image id="image" maxHeight="200" maxWidth="200" />
<s:Button label="Browse for Image" click="browseImage(event)" />
</s:VGroup>
Related
I create an AdvancedDataGrid with a HierarchicalData as DataProvider.
Add my own itemEditor for the #value field in the DataProvider.
All works fine, if no value is set the background is set to red and the value to n/a
but the replacement of the comma does not work. I'll be very happy if someone can help me with that problem.
Here is my MyItemEditor.as class:
import mx.controls.dataGridClasses.DataGridListData;
import mx.controls.TextInput;
public class MyItemEditor extends TextInput {
override public function set data(value : Object) : void {
if (value == null || value[DataGridListData(listData).dataField] == null)
return;
super.data = value;
if (String(value[DataGridListData(listData).dataField]).length == 0) {
setStyle("backgroundColor", "#FF0000");
value[DataGridListData(listData).dataField] = "n/a";
} else if (String(value[DataGridListData(listData).dataField]).indexOf(',') > -1) {
/** worked */
setStyle("backgroundColor", "#FFFF00");
/** does not work */
//value[DataGridListData(listData).dataField].replace(',', '.');
//String(value[DataGridListData(listData).dataField]).replace(',', '.');
//value[DataGridListData(listData).dataField].replace(/,/, '.');
String(value[DataGridListData(listData).dataField]).replace(/,/, '.');
} else {
setStyle("backgroundColor", "#FFFFFF");
}
}
}
And my Test.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init_data()">
<mx:Script>
<![CDATA[
import mx.collections.HierarchicalData;
[Bindable] private var xmlData : XMLList;
[Bindable] private var xmlDP : HierarchicalData;
private function init_data() : void {
xmlData =<>
<item name="Project 1">
<valuetype name="Spannung" value="5" unit="V" />
<valuetype name="Widerstand" value="500" unit="Ohm" />
<valuetype name="Stromstaerke" value="0,01" unit="A" />
</item></>;
xmlDP = new HierarchicalData(xmlData);
}
]]>
</mx:Script>
<mx:HBox width="100%" height="100%">
<mx:AdvancedDataGrid
id="dataGrid"
height="100%"
width="75%"
rowHeight="25"
dataProvider="{xmlDP}"
folderClosedIcon="{null}"
folderOpenIcon="{null}"
defaultLeafIcon="{null}"
editable="true"
draggableColumns="false">
<mx:groupedColumns>
<mx:AdvancedDataGridColumn
editable="false"
headerText="Name"
dataField="#name"
minWidth="500"/>
<mx:AdvancedDataGridColumn
editable="true"
headerText="Wert"
dataField="#value"
minWidth="125"
rendererIsEditor="true"/>
<mx:AdvancedDataGridColumn
editable="false"
headerText="Einheit"
dataField="#unit"
minWidth="125"/>
</mx:groupedColumns>
<mx:rendererProviders>
<mx:AdvancedDataGridRendererProvider
depth="2"
columnIndex="1"
columnSpan="1"
renderer="MyItemEditor"/>
</mx:rendererProviders>
</mx:AdvancedDataGrid>
<mx:Tree id="dataTree" defaultLeafIcon="{null}"
dataProvider="{XML(xmlData).children()}"
labelField="#value" height="100%" width="25%"/>
</mx:HBox>
The tree is to check if the values was set.
Some times the value will not be set the first time. Ist also a little strange.
In Flex (as in most of the modern languages), the strings are immutable. The replace() method does not alter the string on which it is applied, but it creates a new String that holds the result.
result = original.replace(',', '.');
I know this questions is going to have an easy obvious answer but i have spent over two days now trying to do it with no luck (I am a Flex newbie)
Basically i am trying to open a webView that will open google maps to the location in an array
The location comes from data in an array taken from facebook events (that works fine and will display the data) but i am struggling with passing this information to the webView.loadURL string
The data i want in the array is 'data.location' (the code i am having issues with is in the itemrenderer towards the bottom of the code snippet)
I have tried so many different options i am now stuck
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
title="Home" creationComplete="onLoad()">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable] private var facebookEvents:ArrayCollection;
import com.facebook.graph.FacebookMobile;
private function onLoad():void
{
if(FacebookMobile.getSession() != null) {
getEvents()
} else {
eventsDataGrid.visible=false
NotLogin.visible=true
}
}
private function getEvents():void {
var fql:String = "select name, location, pic, start_time from event where creator = 148839887036 and eid in (select eid from event_member where uid=148839887036)";
FacebookMobile.fqlQuery(fql, handleGetEventsResponse);
}
private function handleGetEventsResponse(events:Object, fail:Object):void {
if (events != null)
facebookEvents = new ArrayCollection(events as Array);
//else
//status = "Error";
}
]]>
</fx:Script>
<s:List id="eventsDataGrid" width="100%" height="100%" dataProvider="{facebookEvents}">
<s:itemRenderer>
<fx:Component>
<s:ItemRenderer>
<fx:Script>
<![CDATA[
import com.facebook.graph.utils.FacebookDataUtils;
var webView:StageWebView = new StageWebView
var mapURL:String = ('http://maps.google.com/maps?f=d&hl=en&saddr='+ "{data.location}")
private function time2DateStr(time:String):String {
return FacebookDataUtils.stringToDate(time).toLocaleString();
}
protected function getDirections_clickHandler(event:MouseEvent):void
{
webView.stage = this.stage;
webView.viewPort = new Rectangle(0, 100, stage.stageWidth, stage.stageHeight);
webView.loadURL(mapURL);
}
]]>
</fx:Script>
<s:HGroup paddingBottom="10" paddingTop="10">
<s:Image source="{data.pic}"/>
<s:VGroup width="100%">
<s:Label text="{data.name}" fontWeight="bold" width="100%"/>
<s:Label text="Where: {data.location}"/>
<s:Label text="When: {time2DateStr(data.start_time)}"/>
<s:Label text="Get Directions" click="getDirections_clickHandler(event)" id="getDirections"/>
</s:VGroup>
</s:HGroup>
</s:ItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:List>
<s:Label visible="false" x="6" id="NotLogin" width="463" height="78" styleName="text"
text="Sorry You Need To Be Logged In Via Facebook, Please Go Back and Log In, THANK YOU"/>
all i needed to do was to add the data into the brackets (dont know the offical name) here it is
protected function directions_click (location:String):void
{
navigateToURL(new URLRequest('http://maps.google.co.uk/maps?q=' + location));
}
and for the button/ label
<s:Label text="Get Directions" fontFamily="lucida grande" fontSize="14" color="#3b5998" click="directions_click(data.location)"/>
Suppose, I have a tabbed application. Can I make Popup window to appear in a given tab only? So, if I change a tab, the related popup(-s) hides. So far, I haven't found any solution for this. So any idea would be greatly appreciated :)
You will have to handle different sets of popups by yourself : Flex can only add and remove given popups which will be displayed at the topmost level of your app.
EDIT : Here's a little sample.
<?xml version="1.0"?>
<!-- containers\navigators\TNSimple.mxml -->
<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"
creationComplete="onCreationComplete()"
>
<fx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import spark.components.TitleWindow;
import mx.events.IndexChangedEvent;
private var popups:Array = [];
private function onCreationComplete():void
{
popups = [[],[],[]];
}
private function createPopup():void
{
var foo:TitleWindow = new TitleWindow();
PopUpManager.addPopUp(foo, this);
PopUpManager.centerPopUp(foo);
popups[nav.selectedIndex].push(foo);
}
private function onTabChange(event:IndexChangedEvent):void
{
var i:int;
var oldArray:Array = popups[event.oldIndex];
for (i = 0; i < oldArray.length; i++) {
PopUpManager.removePopUp(oldArray[i]);
}
var newArray:Array = popups[event.newIndex];
for (i = 0; i < newArray.length; i++) {
PopUpManager.addPopUp(newArray[i], this);
}
}
]]>
</fx:Script>
<mx:TabNavigator id="nav" borderStyle="solid" x="50" y="50" change="onTabChange(event)">
<mx:VBox label="Accounts"
width="300"
height="150">
<mx:Button label="pop" click="createPopup()"/>
</mx:VBox>
<mx:VBox label="Stocks"
width="300"
height="150">
<mx:Button label="pop" click="createPopup()"/>
</mx:VBox>
<mx:VBox label="Futures"
width="300"
height="150">
<mx:Button label="pop" click="createPopup()"/>
</mx:VBox>
</mx:TabNavigator>
</s:Application>
Is there any way to detect whether a list is scrolling or not,likelist.isScrolling
So, #Khaled showed a way to do it with the MX component. If you are using the Spark component, that event doesn't work. Instead, you can listen to changes on myList.scroller.viewport.verticalScrollPosition or horizontalScrollPosition.
<fx:Declarations>
<fx:int id="scrollingCount" />
</fx:Declarations>
<s:initialize>
BindingUtils.bindSetter(function(x:*):void { scrollingCount++; }, myList.scroller.viewport, "verticalScrollPosition");
</s:initialize>
<s:VGroup>
<s:Label text="Scrolling: {scrollingCount}" />
<s:List id="myList" height="200" dataProvider="{myData}" />
</s:VGroup>
In neither of these cases do you get to know when the list stops getting scrolled (I'm not sure if you want it or not). You might have to set a timer and any time the timer goes off without any scrolling events, you are no longer scrolling?
Unfortunately, you haven't explained what you are trying to accomplish, wo we can't adequately answer your question.
Or you can do somme thing like this in a list itemrenderer :
import spark.components.List;
[Bindable]
private var calcWidth:Number=195;
private var listVerticalScroll:Boolean;
private var listHorizontalScroll:Boolean;
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
var ownerVerticalScroll:Boolean=List(owner).scroller.verticalScrollBar.visible;
var ownerHorizontalScroll:Boolean=List(owner).scroller.horizontalScrollBar.visible;
if(ownerVerticalScroll!=listVerticalScroll){
listVerticalScroll=ownerVerticalScroll;
scrollBarChange()
}
super.updateDisplayList(unscaledWidth,unscaledHeight);
}
private function scrollBarChange():void {
if(listVerticalScroll){
var newWidth:Number=195-(listVerticalScroll?15:0);
calcWidth=newWidth;
}
}
you can use the ScrollEvent.SCROLL :
import mx.events.ScrollEvent
myList.addEventListener(ScrollEvent.SCROLL, scrollHandler);
function scrollHandler(e:ScrollEvent):void
{
//myList is scrolling
}
Or you can do it like this for spark component!
http://blog.flexexamples.com/2009/05/31/detecting-when-the-vertical-scroll-bar-is-scrolled-on-a-spark-list-control-in-flex-4/ -->
<fx:Script>
<![CDATA[
import spark.components.VScrollBar;
private function init():void {
list.scroller.verticalScrollBar.addEventListener(Event.CHANGE, list_verticalScrollBar_change);
}
private function list_verticalScrollBar_change(evt:Event):void {
var vsb:VScrollBar = evt.currentTarget as VScrollBar;
var obj:Object = {};
obj.type = evt.type;
obj.val = vsb.value;
obj.max = vsb.maximum;
arrColl.addItem(obj);
callLater(dgScroll);
}
private function dgScroll():void {
dataGrid.verticalScrollPosition = dataGrid.maxVerticalScrollPosition;
}
]]>
</fx:Script>
<fx:Declarations>
<mx:ArrayCollection id="arrColl" />
</fx:Declarations>
<s:HGroup horizontalCenter="0" verticalCenter="0">
<s:List id="list"
creationComplete="init();">
<s:layout>
<s:VerticalLayout gap="0"
horizontalAlign="contentJustify"
requestedRowCount="4" />
</s:layout>
<s:dataProvider>
<s:ArrayList>
<fx:String>The</fx:String>
<fx:String>Quick</fx:String>
<fx:String>Brown</fx:String>
<fx:String>Fox</fx:String>
<fx:String>Jumps</fx:String>
<fx:String>Over</fx:String>
<fx:String>The</fx:String>
<fx:String>Lazy</fx:String>
<fx:String>Dog</fx:String>
</s:ArrayList>
</s:dataProvider>
</s:List>
<mx:DataGrid id="dataGrid"
dataProvider="{arrColl}"
width="200"
verticalScrollPolicy="on">
<mx:columns>
<mx:DataGridColumn dataField="type" />
<mx:DataGridColumn dataField="val" />
<mx:DataGridColumn dataField="max" />
</mx:columns>
</mx:DataGrid>
</s:HGroup>
</s:Application>
How to attach symbols from an .swf file in the Actionscript part of the Flex3 file?
I've prepared a simple test case demonstrating my problem. Everything works (there are icons at the 4 buttons, there is a red circle) - except the getDefinitionByName() part.
My target is to attach a symbol from library "dynamically" - i.e. depending at the value of the suit variable at the runtime.
Symbols.as:
package {
public class Symbols {
[Embed('../assets/symbols.swf', symbol='spades')]
public static const SPADES:Class;
[Embed('../assets/symbols.swf', symbol='clubs')]
public static const CLUBS:Class;
[Embed('../assets/symbols.swf', symbol='diamonds')]
public static const DIAMONDS:Class;
[Embed('../assets/symbols.swf', symbol='hearts')]
public static const HEARTS:Class;
}
}
TestCase.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
creationComplete="onCreationComplete();">
<mx:Script>
<![CDATA[
private function onCreationComplete():void
{
var sprite:Sprite = new Sprite();
var g:Graphics = sprite.graphics;
g.lineStyle(1, 0xFF0000);
g.beginFill(0xFF0000);
g.drawCircle(100, 100, 20);
g.endFill();
spriteHolder.addChild(sprite);
// XXX stuff below not working, can it be fixed?
var suit:String = "SPADES";
var mc:MovieClip = new (getDefinitionByName("Symbols.SPADES") as Class);
spriteHolder.addChild(mc);
}
]]>
</mx:Script>
<mx:VBox width="100%">
<mx:Button label="1" icon="{Symbols.SPADES}" />
<mx:Button label="2" icon="{Symbols.CLUBS}" />
<mx:Button label="3" icon="{Symbols.DIAMONDS}" />
<mx:Button label="4" icon="{Symbols.HEARTS}" />
<mx:UIComponent id="spriteHolder" width="200" height="200"/>
</mx:VBox>
</mx:Application>
just go with Symbols[suit]. object[expression] is equivalent to object.ident if String(expression) evaluates to "ident".