Flex: move dynamic child or element - apache-flex

It's possible to move a dynamic ctreated element or child?
Example:
Create childs:
public function createChilds():void {
for(var i:int=0; i < 10; i++) {
newImage = new Image();
newImage.source = myImages[i];
mybox.addChild(newImage);
}
}
Move childs:
public function moveChilds():void {
for(var i:int=0; i < 10; i++) {
mybox.getChildAt(i).move((mybox.getChildAt(i).x - 1), 0);
}
}
But I get an error message :(

Use the x and y properties of the child to move them to the required coordinates.
For example,
mybox.getChildAt(i).x = mybox.getChildAt(i).x - 1;
mybox.getChildAt(i).y = 0;

Related

google.maps.LatLngBounds () issue

I am trying to find if a latitude and longitude exists in a rectangle or not. I used following code but its having some issue i donno what.
function test(boxes) {
for (var i = 0; i < boxes.length; i++) {
var bounds = new google.maps.LatLngBounds (box[i]);
if (bounds.contains(new google.maps.LatLng(22.7287, 75.8654))) {
alert("i am here");
// marker is within bounds
}
else {
alert("out of box");
}
}
}
if i pass constructor value as 0.0,0.0, it works while if i use boxes[i] its not executing while boxes[i] having the boundaries e.g (17.788,72.828),(21.2620,73.4602)
Based on your comments (you really should update the question), this should work:
function test(boxes) {
for (var i = 0; i < boxes.length; i++) {
if (boxes[i].contains(new google.maps.LatLng(22.7287, 75.8654))) {
alert("i am here");
// marker is within bounds
}
else {
alert("out of box");
}
}
}

What's wrong with this piece of code?

I'm trying to make a image editor in Flex 4.5.
However, there's one little thing that doesn't work as appropriate. Here's my code:
private function returnCropIndicatorBmpDataForTopLeft():BitmapData{
var topLeftX:int = 0;
var topLeftY:int = 0;
var topRightX:int = _bmpData.width;
var topRightY:int = 0;
var bottomRightX:int = _bmpData.width;
var bottomRightY:int = _bmpData.height;
var bottomLeftX:int = 0;
var bottomLeftY:int = _bmpData.height;
var cropIconX:int = _mouseX;
var cropIconY:int = _mouseY;
var temporaryBitmapData:BitmapData = _bmpData;
var originalColor:uint;
var dimmedColor:uint = 0x202020;
for (var i:int = 0; i < _bmpData.width; i++)
{
for (var j:int = 0; j < _bmpData.height; j++)
{
originalColor = _bmpData.getPixel(i,j);
if(i>cropIconX && j>cropIconY){
temporaryBitmapData.setPixel(i,j,originalColor);
}else{
temporaryBitmapData.setPixel(i,j,dimmedColor);
}
}
}
/*
*by the end of this loop, we have, in the temporaryBitmapData variable, a version of the _bmpData,
*the area to be cropped out dimmed a little bit.
*/
return temporaryBitmapData;
}
if you look carefully inside the first if statement in the innermost for loop,
temporaryBitmapData.setPixel(i,j,originalColor);
that bit of code should do the following:
If this (i,j) pixel is outside of the "to-be-cropped-out area", then repaint it with the original pixel color.
It just can't seem to get that to work!!!!
I've substituted that line with some hardcoded value (say, 0xFFFFFF for white) and it did work, so the problem is not there....
Hope you guys can help me out I've spent more than 4 hours on this already trying many different approaches!!
P.S.> I debugged this code in FB 4.5 and placed a breakpoint in that very if statement. For some reason, the _bmpData variable, which is where I want to get the original pixel color from , shows a small red square next to it.... Perhaps that is indicative of something.. perhaps it's somehow thread-'locked'?? I don't know, hope someone can figure out!
EDIT the problem I'm having is the following: the dimming of the image works fine, but if I then move the mouse cursor back to an area that got dimmed out, then the original image doesn't get repainted, as expected.
There must be something else going on there... I just tested your code and it worked fine for me.
package {
import flash.display.MovieClip;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.net.*;
import flash.display.Loader;
import flash.events.Event;
public class ImageCropper extends MovieClip {
protected var _bmpData:BitmapData;
protected var _mouseX:int;
protected var _mouseY:int;
var imageLoader:Loader;
public function ImageCropper() {
_mouseX = 80;
_mouseY = 50;
imageLoader = new Loader();
var image:URLRequest = new URLRequest("http://www.travelooce.com/pics/bear_picnic_table.jpg");
imageLoader.load(image);
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, _imageLoaded);
imageLoader.x = 0;
imageLoader.y = 0;
}
public function _imageLoaded($evt:Event):void {
_bmpData = new BitmapData(imageLoader.width, imageLoader.height, false);
_bmpData.draw(imageLoader);
var bmp2:BitmapData = returnCropIndicatorBmpDataForTopLeft();
var bmp:Bitmap = new Bitmap(bmp2);
addChild(bmp);
}
private function returnCropIndicatorBmpDataForTopLeft():BitmapData{
var topLeftX:int = 0;
var topLeftY:int = 0;
var topRightX:int = _bmpData.width;
var topRightY:int = 0;
var bottomRightX:int = _bmpData.width;
var bottomRightY:int = _bmpData.height;
var bottomLeftX:int = 0;
var bottomLeftY:int = _bmpData.height;
var cropIconX:int = _mouseX;
var cropIconY:int = _mouseY;
// This is the important line to change.
var temporaryBitmapData:BitmapData = _bmpData.clone();
var originalColor:uint;
var dimmedColor:uint = 0x202020;
for (var i:int = 0; i < _bmpData.width; i++)
{
for (var j:int = 0; j < _bmpData.height; j++)
{
originalColor = _bmpData.getPixel(i,j);
if(i>cropIconX && j>cropIconY){
temporaryBitmapData.setPixel(i,j,originalColor);
}else{
temporaryBitmapData.setPixel(i,j,dimmedColor);
}
}
}
/*
*by the end of this loop, we have, in the temporaryBitmapData variable, a version of the _bmpData,
*the area to be cropped out dimmed a little bit.
*/
return temporaryBitmapData;
}
}
}
Output:
http://cl.ly/3d0h023C1p392O270I2L

In AS3/Flex, how can I get from flat data to hierarchical data?

I have some data that gets pulled out of a database and mapped to an arraycollection. This data has a field called parentid, and I would like to map the data into a new arraycollection with hierarchical information to then feed to an advanced data grid.
I think I'm basically trying to take the parent object, add a new property/field/variable of type ArrayCollection called children and then remove the child object from the original list and clone it into the children array? Any help would be greatly appreciated, and I apologize ahead of time for this code:
private function PutChildrenWithParents(accountData : ArrayCollection) : ArrayCollection{
var pos_inner:int = 0;
var pos_outer:int = 0;
while(pos_outer < accountData.length){
if (accountData[pos_outer].ParentId != null){
pos_inner = 0;
while(pos_inner < accountData.length){
if (accountData[pos_inner].Id == accountData[pos_outer].ParentId){
accountData.addItemAt(
accountData[pos_inner] + {children:new ArrayCollection(accountData[pos_outer])},
pos_inner
);
accountData.removeItemAt(pos_outer);
accountData.removeItemAt(pos_inner+1);
}
pos_inner++;
}
}
pos_outer++;
}
return accountData;
}
I had a similar problem with a hierarchical task set which was slightly different as it has many root elements, this is what i did, seems good to me:
public static function convertFlatTasks(tasks:Array):Array
{
var rootItems:Array = [];
var task:TaskData;
// hashify tasks on id and clear all pre existing children
var taskIdHash:Array = [];
for each (task in tasks){
taskIdHash[task.id] = task;
task.children = [];
task.originalChildren = [];
}
// loop through all tasks and push items into their parent
for each (task in tasks){
var parent:TaskData = taskIdHash[task.parentId];
// if no parent then root element, i.e push into the return Array
if (parent == null){
rootItems.push(task);
}
// if has parent push into children and originalChildren
else {
parent.children.push(task);
parent.originalChildren.push(task);
}
}
return rootItems;
}
Try this:
AccountData:
public class AccountData
{
public var Id:int;
public var ParentId:int;
public var children:/*AccountData*/Array;
public function AccountData(id:int, parentId:int)
{
children = [];
this.Id = id;
this.ParentId = parentId;
}
}
Code:
private function PutChildrenWithParents(accountData:ArrayCollection):AccountData
{
// dummy data for testing
//var arr:/*AccountData*/Array = [new AccountData(2, 1),
// new AccountData(1, 0), // root
// new AccountData(4, 2),
// new AccountData(3, 1)
// ];
var arr:/*AccountData*/Array = accountData.source;
var dict:Object = { };
var i:int;
// generate a lookup dictionary
for (i = 0; i < arr.length; i++)
{
dict[arr[i].Id] = arr[i];
}
// root element
dict[0] = new AccountData(0, 0);
// generate the tree
for (i = 0; i < arr.length; i++)
{
dict[arr[i].ParentId].children.push(arr[i]);
}
return dict[0];
}
dict[0] holds now your root element.
Maybe it's doesn't have the best possible performance but it does what you want.
PS: This code supposes that there are no invalid ParentId's.
Here's what I ended up doing, apparently you can dynamically add new properties to an object with
object['new_prop'] = whatever
From there, I used a recursive function to iterate through any children so you could have n levels of the hierarchy and if it found anything it would pass up through the chain by reference until the original function found it and acted on it.
private function PutChildrenWithParents(accountData : ArrayCollection) : ArrayCollection{
var pos_inner:int = 0;
var pos_outer:int = 0;
var result:Object = new Object();
while(pos_outer < accountData.length){
if (accountData[pos_outer].ParentId != null){
pos_inner = 0;
while(pos_inner < accountData.length){
result = CheckForParent(accountData[pos_inner],
accountData[pos_outer].ParentId);
if ( result != null ){
if(result.hasOwnProperty('children') == false){
result['children'] = new ArrayCollection();
}
result.children.addItem(accountData[pos_outer]);
accountData.removeItemAt(pos_outer);
pos_inner--;
}
pos_inner++;
}
}
pos_outer++;
}
return accountData;
}
private function CheckForParent(suspectedParent:Object, parentId:String) : Object{
var parentObj:Object;
var counter:int = 0;
if ( suspectedParent.hasOwnProperty('children') == true ){
while (counter < suspectedParent.children.length){
parentObj = CheckForParent(suspectedParent.children[counter], parentId);
if (parentObj != null){
return parentObj;
}
counter++;
}
}
if ( suspectedParent.Id == parentId ){
return suspectedParent;
}
return null;
}

highlight matching text?

I have flex 4 and writing my own autocomplete component (based on the popupanchor) to search for different books. In the dropdown box, how can I highlight the text that matches? For instance, a user types in "ema" and the search returns "Pet Sematary"....I want to highlight the letters "ema" within "Pet Sematary"
Wrote auto-complete a week ago :) You need to use Spark text components and pass custom TextFlow to them:
private function init():void
{
var textFlow:TextFlow = new TextFlow();
var paragraph:ParagraphElement = new ParagraphElement();
textFlow.addChild(paragraph);
var elements:Vector.<FlowElement> = highlight("Pet Sematary", "Se");
var n:int = elements.length;
for (var i:int = 0; i < n; i++)
{
paragraph.addChild(elements[i]);
}
label.textFlow = textFlow;
}
private function highlight(text:String, query:String):Vector.<FlowElement>
{
var result:Vector.<FlowElement> = new Vector.<FlowElement>();
// since we need to compare ignore-case we can not use split()
// and have to collect indexes of "query" matches in "text"
var indexes:Vector.<int> = new Vector.<int>();
var index:int = 0;
var textLowerCase:String = text.toLocaleLowerCase();
var queryLowerCase:String = query.toLocaleLowerCase();
var queryLength:int = query.length;
while (true)
{
index = textLowerCase.indexOf(queryLowerCase, index);
if (index == -1)
break;
indexes.push(index);
index += queryLength;
}
// now add SpanElement for each part of text. E.g. if we have
// text="aBc" and query is "b" then we add "a" and "c" as simple
// span and "B" as highlighted span.
var backgroundColor:uint = 0xFFCC00;
var n:int = indexes.length;
if (n == 0) // no matches
{
addSpan(result, text);
}
else
{
var startIndex:int = 0;
for (var i:int = 0; i < n; i++)
{
if (startIndex != indexes[i])
addSpan(result, text.substring(startIndex, indexes[i]));
addSpan(result, text.substr(indexes[i], queryLength),
backgroundColor);
startIndex = indexes[i] + queryLength;
}
if (startIndex != text.length)
addSpan(result, text.substr(startIndex));
}
return result;
}
private function addSpan(vector:Vector.<FlowElement>, text:String,
backgroundColor:* = "transparent"):void
{
var span:SpanElement = new SpanElement();
span.text = text;
span.backgroundColor = backgroundColor;
vector.push(span);
}
MXML code:
<s:RichEditableText editable="false" multiline="false"
selectable="false" id="label"
horizontalCenter="0" verticalCenter="0"/>
P.S: If you will have troubles with popup taking focus - add it manually to the toolTipChildren:
systemManager.toolTipChildren.addChildAt(child, 0);

Cannot add an entity that already exists

Code:
public ActionResult Create(Group group)
{
if (ModelState.IsValid)
{
group.int_CreatedBy = 1;
group.dtm_CreatedDate = DateTime.Now;
var Groups = Request["Groups"];
int GroupId = 0;
GroupFeature GroupFeature=new GroupFeature();
foreach (var GroupIdd in Groups)
{
// GroupId = int.Parse(GroupIdd.ToString());
}
var Features = Request["Features"];
int FeatureId = 0;
int t = 0;
int ids=0;
string[] Feature = Features.Split(',').ToArray();
//foreach (var FeatureIdd in Features)
for(int i=0; i<Feature.Length; i++)
{
if (int.TryParse(Feature[i].ToString(), out ids))
{
GroupFeature.int_GroupId = 35;
GroupFeature.int_FeaturesId = ids;
if (ids != 0)
{
GroupFeatureRepository.Add(GroupFeature);
GroupFeatureRepository.Save();
}
}
}
return RedirectToAction("Details", new { id = group.int_GroupId });
}
return View();
}
I am getting an error here Cannot add an entity that already exists. at this line GroupFeatureRepository.Add(GroupFeature);
GroupFeatureRepository.Save();
This line:
GroupFeature GroupFeature=new GroupFeature();
needs to be inside your for loop, like this:
for(int i=0; i<Feature.Length; i++)
{
if (int.TryParse(Feature[i].ToString(), out ids))
{
GroupFeature GroupFeature=new GroupFeature();
You need to add a new GroupFeature each time(e.g. one not in that collection, which your re-used object already is after the first loop). You can't re-use the same GroupFeature object like that for adding, but moving it inside the loop so you generate a distinct GroupFeature each time will resolve this.

Resources