Positioning different length text boxes right next to each other.
im trying to get a tree made from words users type in but am lost at the part where the text boxes have to be right next to each other even if different length words are typed in. If anyone can explain how i can do this i will be extremely grateful.
I think you're going to have to be a bit more specific, but maybe you could giving them all an autoSize property and then run a for loop on them and slide them over to the last text boxes position plus it's width?
The 'Boose':
ASUS Sabertooth P67 TUF
Intel Core i7-2600K Quad-Core Sandy Bridge 3.4GHz Overclocked to 4.2GHz
8GB G.Skill Ripjaws 1600 DDR3
ASUS ENGTX550 TI DC/DI/1GD5 GeForce GTX 550 Ti (Fermi) 1GB 1GDDR5 (Overclocked to 1.1GHz)
New addition: OCZ Vertex 240GB SATA III SSD WEI Score: 7.6
var xloc:Number = 0;
var paddingBetweenTextFields:Number = 10;
for (var i:int = 0; i < guestList.length(); i++)
{
var nameElement:XML = guestList[i];
var myTextField:TextField = new TextField();
addChild(myTextField);
myTextField.text = nameElement;
myTextField.x = xloc;
myTextField.selectable = false;
myTextField.border = true;
myTextField.autoSize = TextFieldAutoSize.LEFT;
var myFormat:TextFormat = new TextFormat();
myFormat.color = 0xAA0000;
myFormat.size = 24;
myFormat.italic = true;
myTextField.setTextFormat(myFormat);
xloc += myTextField.width + paddingBetweenTextFields; // remove padding if you don't want gaps between textfields.
}
The 'Boose':
ASUS Sabertooth P67 TUF
Intel Core i7-2600K Quad-Core Sandy Bridge 3.4GHz Overclocked to 4.2GHz
8GB G.Skill Ripjaws 1600 DDR3
ASUS ENGTX550 TI DC/DI/1GD5 GeForce GTX 550 Ti (Fermi) 1GB 1GDDR5 (Overclocked to 1.1GHz)
New addition: OCZ Vertex 240GB SATA III SSD WEI Score: 7.6
Ur an absolute legend ImprisonedPride, couldnt get round that in my head, not almost - exactly. Though now i think my idea has to be made solely in flash, xml is too hard.
If you can imagine a path, that is made from words, going from left to right. Each user can either add a word to the path OR split the path by putting an alternative word instead of the last word. That is the whole concept, i've put a jpg to demonstrate what it would look like.
Any idea on how I would do this in flash? maybe with arrays?
Oh well, for every string( sentence or word), store it as an object which has two properties in the least....the string itself, and the parent id (array slot) of its parent. (you can also do dynamic nested arrays I guess, but that would get too complex at length). and store these objects in a 1d array.
Next loop through the array, for each object, draw the first object string, check its children count using the parent ids, and draw them and rotate them however you want, though make sure the rotation is relative to the parent. It would be easier if you know how many max branches are possible.
For the current object, if you know the angle you rotated it (let's say parent.rotation+(60/maxbranch)), you can find the next child's position with something like
childx = (parent_tb.width+15)*Math.cos(parent_tb.rotation*M ath.PI/180);
childy = (parent_tb.width+15)*Math.sin(parent_tb.rotation*M ath.PI/180);
If you like me, add me to your friends list .
PS: looking for spriters and graphics artists for a RPG and an Arcade fighting project. If you can help out, please pm me!
Ur an absolute legend ImprisonedPride, couldnt get round that in my head, not almost - exactly. Though now i think my idea has to be made solely in flash, xml is too hard.
If you can imagine a path, that is made from words, going from left to right. Each user can either add a word to the path OR split the path by putting an alternative word instead of the last word. That is the whole concept, i've put a jpg to demonstrate what it would look like.
Any idea on how I would do this in flash? maybe with arrays?
Why!? XML makes this so much easier...
Code:
var xml:XML = new XML(<xml>
<starter>
<value>There once was a</value>
<right>
<value>dog that had no owner.</value>
</right>
<left>
<value>man called</value>
<left>
<value>Bob</value>
<left>
<value>who thought a lot.</value>
</left>
</left>
<right>
<value>tom who liked actionscript.</value>
</right>
</left>
</starter>
</xml>);
var sx:int = 0;
var sy:int = 200;
traverse(xml.starter, sx, sy);
function traverse(node:XMLList, sx:int, sy:int) {
var o:* = drawNode(node.value, sx, sy);
sx = o.x;
var paths:int = 0;
var d:MovieClip = new dot();
d.x = sx+2;
sx += 4 + d.width;
d.y = sy+8;
stage.addChild(d);
if (node.left.length() == 1) {
trace("Going left");
traverse(node.left, sx, sy-15);
paths++;
}
if (node.right.length() == 1) {
trace("Going right");
traverse(node.right, sx, sy+15);
paths++;
}
if (paths>0) {
d.gotoAndStop(1);
} else {
d.gotoAndStop(2);
}
}
function drawNode(t:String, x:int, y:int):* {
var txt:TextField = new TextField();
addChild(txt);
txt.text = t;
txt.y = y;
txt.x = x;
txt.selectable = false;
txt.autoSize = TextFieldAutoSize.LEFT;
var myFormat:TextFormat = new TextFormat();
myFormat.color = 0x000000;
myFormat.size = 8;
txt.setTextFormat(myFormat);
return {x:x+txt.width};
}
Just needs a little rotation put in there, and you probably need to compare the longest child (right or left) and make the start (sx) that width so they don't overlap. I'd do it but I gotta run to class. This should get you started though.
Last edited by ImprisonedPride; 11-10-2009 at 03:42 PM.
The 'Boose':
ASUS Sabertooth P67 TUF
Intel Core i7-2600K Quad-Core Sandy Bridge 3.4GHz Overclocked to 4.2GHz
8GB G.Skill Ripjaws 1600 DDR3
ASUS ENGTX550 TI DC/DI/1GD5 GeForce GTX 550 Ti (Fermi) 1GB 1GDDR5 (Overclocked to 1.1GHz)
New addition: OCZ Vertex 240GB SATA III SSD WEI Score: 7.6
sry about the paranoid posting.. got a close deadline at hand, will try this out after my lecture, seems like u really know ur stuff. thx so much
my cs4 is wayyy to slow cant handle it so reinstalling cs3...
could you possibly explain whats going on in that code? is the xml being created within the flash file and stored in the same directory?
Also throws up an error.. 1180: Call to a possibly undefined method dot.. im really not sure where this code goes and how it works
replaced dot with MovieClip and seems to work, however don't know where to go from here.. need to make rotation, also input boxes at the end of each line for the actual words.. it also has to be never ending =0 . ImprisonedPride whats goin on?
var xml:XML = new XML(<xml>
<starter value="There once was a">
<right value="dog that">
<right value="bit the mailman">
<right value="that he">
<right value="ran away"/>
<left value="cried"/>
</right>
</right>
<left value="had no owner"></left>
</right>
<left value="man called">
<left value="Bob">
<left value="who thought a lot"/>
</left>
<right value="tom who liked">
<right value="actionscript"/>
<left value="to flirt with">
<right value="loose women"/>
<left value="complete strangers"/>
</left>
</right>
</left>
</starter>
</xml>);
var sx:int = 0;
var sy:int = 200;
traverse(xml.starter, sx, sy, 0);
function traverse(node:XMLList, sx:int, sy:int, ri:int) {
var o:* = drawNode(node.@value, sx, sy, ri);
sx = o.x;
sy = o.y;
var paths:int = 0;
if (node.left.length() == 1) {
traverse(node.left, sx, sy-7, ri-22.5);
paths++;
}
if (node.right.length() == 1) {
traverse(node.right, sx, sy+7, ri+22.5);
paths++;
}
}
function drawNode(t:String, x:int, y:int, r:int):* {
var font:Verdana8pt = new Verdana8pt();
var format:TextFormat = new TextFormat();
format.font = font.fontName;
format.color = 0x000000;
format.size = 8;
var label:TextField = new TextField();
label.embedFonts = true;
label.autoSize = TextFieldAutoSize.LEFT;
label.antiAliasType = AntiAliasType.ADVANCED;
label.defaultTextFormat = format;
label.text = t;
var nr:Number = (r+label.rotation) * (Math.PI/180);
var nx:Number = x + ((label.width + 5) * Math.cos(nr) );
var ny:Number = y + 7 + ((label.width + 5)* Math.sin(nr) );
label.rotation += r;
label.x = x;
label.y = y;
addChild(label);
return {x:nx, y:ny, r:nr};
}
This should be really self-explanatory... I had to load a custom xml in since you didn't supply yours. It should also be obvious that since you aren't looking to make micro adjustments to the code to lay out your own xml in a similar way. Keep your XML loading the way you had it... but like I did with this line:
Code:
traverse(xml.starter, sx, sy, 0);
you'll need to send the first string node of the sentence to the traverse function when the xml finishes loading. Also, Verdana8pt is the name of a libary-font object. Embedding fonts is essential to retaining the text post-rotation. You'll need to embed the font you want in the library, and replace "Verdana8pt" with the linkage class ID of that font object.
Example output:
Last edited by ImprisonedPride; 11-11-2009 at 01:11 PM.
The 'Boose':
ASUS Sabertooth P67 TUF
Intel Core i7-2600K Quad-Core Sandy Bridge 3.4GHz Overclocked to 4.2GHz
8GB G.Skill Ripjaws 1600 DDR3
ASUS ENGTX550 TI DC/DI/1GD5 GeForce GTX 550 Ti (Fermi) 1GB 1GDDR5 (Overclocked to 1.1GHz)
New addition: OCZ Vertex 240GB SATA III SSD WEI Score: 7.6
This is great, i got it all working but have accross an even more difficult issue.. basically, im trying to put a textbox at the end of each extra xml path and allow that to input data into the right place inside the xml?
Last edited by ImprisonedPride; 11-12-2009 at 09:54 AM.
The 'Boose':
ASUS Sabertooth P67 TUF
Intel Core i7-2600K Quad-Core Sandy Bridge 3.4GHz Overclocked to 4.2GHz
8GB G.Skill Ripjaws 1600 DDR3
ASUS ENGTX550 TI DC/DI/1GD5 GeForce GTX 550 Ti (Fermi) 1GB 1GDDR5 (Overclocked to 1.1GHz)
New addition: OCZ Vertex 240GB SATA III SSD WEI Score: 7.6
var loader:URLLoader = new URLLoader(); loader.addEventListener(Event.COMPLETE, loadXML); loader.load(new URLRequest("data.xml?cachebuster=" + new Date().getTime()));
function loadXML(e:Event):void { var xml:XML = new XML(e.target.data);
ParseBooks(xml); }
function ParseBooks(Myguests:XML):void {
var guestList:XMLList = Myguests.guest.name; var xloc:Number = 0; var paddingBetweenTextFields:Number = 1;
}
var sx:int = 0; var sy:int = 200;
traverse(xml.starter, sx, sy, 0);
function traverse(node:XMLList, sx:int, sy:int, ri:int) {
var o:* = drawNode(node.@value, sx, sy, ri); sx = o.x; sy = o.y; var paths:int = 0;
function drawNode(t:String, x:int, y:int, r:int):* { var font:Verdana8pt = new Verdana8pt(); var format:TextFormat = new TextFormat(); format.font = font.fontName; format.color = 0x000000; format.size = 8;
var label:TextField = new TextField(); label.embedFonts = true; label.autoSize = TextFieldAutoSize.LEFT; label.antiAliasType = AntiAliasType.ADVANCED; label.defaultTextFormat = format; label.text = t; var nr:Number = (r+label.rotation) * (Math.PI/180); var nx:Number = x + ((label.width + 5) * Math.cos(nr) ); var ny:Number = y + 7 + ((label.width + 5)* Math.sin(nr) ); label.rotation += r; label.x = x; label.y = y; addChild(label);
return {x:nx, y:ny, r:nr}; }
trying to load that same xml from above in an external file.. it comes up with undefined property xml
The way you have it now, the xml var only exists within the scope of the loadXML function. Move it outside the function as a public variable.
The 'Boose':
ASUS Sabertooth P67 TUF
Intel Core i7-2600K Quad-Core Sandy Bridge 3.4GHz Overclocked to 4.2GHz
8GB G.Skill Ripjaws 1600 DDR3
ASUS ENGTX550 TI DC/DI/1GD5 GeForce GTX 550 Ti (Fermi) 1GB 1GDDR5 (Overclocked to 1.1GHz)
New addition: OCZ Vertex 240GB SATA III SSD WEI Score: 7.6