PDA

Volledige versie bekijken : [AS 2.0] Generic Menu


Tommyfied
%Europe/Berlin %899 %2005, 22:34
Ik heb een 3tal classes gemaakt die samen een soort van standaard xml menu vormen. Hiermee kun je met behulp van een button MovieClip en een XML file een heel menu in elkaar zetten wat behoorlijk aanpasbaar is.
Het is op zich vrij simpel in het gebruik en heb dan ook niet de hele code gecomment. Mocht iemand toch problemen hebben met het gebruik ervan, post hier je vraag en ik zal kijken wat ik kan doen.
Waarschuwing: het is opzich vrij simpel maar ook weer niet zo dat iedereen die nog maar net met Actionscrip bezig is het simpel kan gebruiken, laat staan begrijpen. Houd hier dus rekening mee.

Ok daar komtie dan:

Class 1: GenericButton
Deze class zorgt ervoor dat een MovieClip als Button kan fungeren. Deze class wordt gebruikt in de GenericMenu class die hierna volgt. Je kan deze class ook op zichzelf gebruiken.

code:

class GenericButton
{
private var buttonHolder: MovieClip;

private var buttonScope: MovieClip;
private var buttonClip: String;
private var buttonDepth: Number;
private var buttonTextField: String;
private var buttonLabel: String;
private var buttonSize: Object;
private var buttonPosition: Object;
private var buttonTarget: Object;

public function GenericButton (buttonScope: MovieClip, buttonClip: String, buttonDepth: Number, buttonTextField: String, buttonLabel: String, buttonSize: Object, buttonPosition: Object, buttonTarget: Object)
{
init(buttonScope, buttonClip, buttonDepth, buttonTextField, buttonLabel, buttonSize, buttonPosition, buttonTarget);
};

private function init (buttonScope: MovieClip, buttonClip: String, buttonDepth: Number, buttonTextField: String, buttonLabel: String, buttonSize: Object, buttonPosition: Object, buttonTarget: Object): Void
{
setButtonScope(buttonScope);
setButtonClip(buttonClip);
setButtonDepth(buttonDepth);
setButtonTextField(buttonTextField);
setButtonLabel(buttonLabel);
setButtonSize(buttonSize);
setButtonPosition(buttonPosition);
setButtonTarget(buttonTarget);

displayButton();

startListeners();


};

private function displayButton (Void): Void
{
buttonHolder = getButtonScope().attachMovie(getButtonClip(), "button"+getButtonDepth(), getButtonDepth());
var buttonSize: Object = getButtonSize();
buttonHolder._width = buttonSize.w;
buttonHolder._height = buttonSize.h;

var buttonPosition: Object = getButtonPosition();
buttonHolder._x = buttonPosition.x;
buttonHolder._y = buttonPosition.y;

buttonHolder[buttonTextField].text = getButtonLabel();
};

private function startListeners (Void): Void
{
var classReference: GenericButton = this;

buttonHolder.onRelease = buttonHolder.onReleaseOutside = classReference.onClick
buttonHolder.onRollOver = buttonHolder.onDragOver = classReference.onRollOn
buttonHolder.onRollOut = buttonHolder.onDragOut = classReference.onRollOff
};

public function onClick (Void): Void
{
buttonHolder.gotoAndPlay("#click");

var buttonTarget: Object = getButtonTarget();
if (buttonTarget.linkType == "frame") eval(buttonTarget.scope).gotoAndPlay(buttonTarget. destination);
else if (buttonTarget.linkType == "url") getURL(buttonTarget.destination);
};

public function onRollOn (Void): Void
{
buttonHolder.gotoAndPlay("#rollOn");
};

public function onRollOff (Void): Void
{
buttonHolder.gotoAndPlay("#rollOff");
};

public function getButtonScope (Void): MovieClip
{
return buttonScope;
};
public function setButtonScope (buttonScope: MovieClip): Void
{
if (buttonScope) this.buttonScope = buttonScope;
};

public function getButtonClip (Void): String
{
return buttonClip;
};
public function setButtonClip (buttonClip: String): Void
{
if (buttonClip) this.buttonClip = buttonClip;
};

public function getButtonDepth (Void): Number
{
return buttonDepth;
};
public function setButtonDepth (buttonDepth: Number): Void
{
this.buttonDepth = buttonDepth;
};

public function getButtonTextField (Void): String
{
return buttonTextField;
};
public function setButtonTextField (buttonTextField: String): Void
{
if (buttonTextField) this.buttonTextField = buttonTextField;
};

public function getButtonLabel (Void): String
{
return buttonLabel;
};
public function setButtonLabel (buttonLabel: String): Void
{
if (buttonLabel) this.buttonLabel = buttonLabel;
};

public function getButtonSize (Void): Object
{
return buttonSize;
};
public function setButtonSize (buttonSize: Object): Void
{
if (buttonSize.w && buttonSize.h) this.buttonSize = buttonSize;
};

public function getButtonPosition (Void): Object
{
return buttonPosition;
};
public function setButtonPosition (buttonPosition: Object): Void
{
this.buttonPosition = buttonPosition;
};

public function getButtonTarget (Void): Object
{
return buttonTarget;
};
public function setButtonTarget (buttonTarget: Object): Void
{
if (buttonTarget) this.buttonTarget = buttonTarget;
};
}


gebruik:
In eerste instantie wordt deze gebruikt in de GenericMenu class / bijbehorende xml file en hoef je je er geen zorgen over te maken.
Als je hem los wil gebruiken is hier een voorbeeldje van hoe je hem aanroept:
var firstButton: GenericButton = new GenericButton(this, "sampleItemLinkID", 100, "labelText", "This will point to another frame", {w: 250, h: 24}, {x: 100, y: 150}, {linkType: "frame", scope: this, destination: "#after"});
Je moet dan wel een MovieClip hebben in je library met als linkage id "sampleItemLinkID" en met een dynamic textfield erin met de instancename "labeltext".

Class 2: GenericMenu
Deze class zorgt ervoor dat er een bepaald aantal GenericButton's worden aangemaakt en die op de juiste manier worden gepositioneerd en de juiste parameters meekrijgen. Deze class is afhankelijk van de class hieronder: GenericMenuXMLSource.

code:

class GenericMenu
{
private var menuHolder: MovieClip;

private var menuScope: MovieClip;
private var menuClip: String; // linkage ID to empty MovieClip
private var menuDepth: Number;
private var menuLabel: String;
private var menuSource: Object; // buttonClips, buttonDepths, buttonTextFields, buttonLabels, buttonSizes, buttonSpacing, buttonTargets (xml or manual)
private var menuPosition: Object; // w, h
private var menuDirection: String; // "horizontal" or "vertical"

public function GenericMenu (menuScope: MovieClip, menuClip: String, menuDepth: Number, menuLabel: String, menuSource: Object, menuPosition: Object, menuDirection: String)
{
init(menuScope, menuClip, menuDepth, menuLabel, menuSource, menuPosition, menuDirection);
};

public function init (menuScope: MovieClip, menuClip: String, menuDepth: Number, menuLabel: String, menuSource: Object, menuPosition: Object, menuDirection: String): Void
{
setMenuScope(menuScope);
setMenuClip(menuClip);
setMenuDepth(menuDepth);
setMenuLabel(menuLabel);
setMenuSource(menuSource);
setMenuPosition(menuPosition);
setMenuDirection(menuDirection);

displayMenu();
};

public function displayMenu (Void): Void
{
var buttonHolders: Array = new Array();

var buttonClips: Array = getMenuSource().buttonClips;
var buttonDepths: Array = getMenuSource().buttonDepths;
var buttonTextFields: Array = getMenuSource().buttonTextFields;
var buttonLabels: Array = getMenuSource().buttonLabels;
var buttonSizes: Array = getMenuSource().buttonSizes;
var buttonSpacing: Number = getMenuSource().buttonSpacing;
var buttonTargets: Array = getMenuSource().buttonTargets;

menuHolder = getMenuScope().attachMovie(getMenuClip(), getMenuLabel(), getMenuDepth());
var menuPosition: Object = getMenuPosition();
menuHolder._x = menuPosition.x;
menuHolder._y = menuPosition.y;

var buttonPositions: Array = new Array();
var menuDirection: Object = getMenuDirection();

var menuLength: Number = buttonClips.length;
for (var i: Number = 0; i < menuLength; ++i)
{
buttonPositions[i] = new Object();
if (menuDirection == "horizontal")
{
buttonPositions[i].x = i * (buttonSizes[i].w + buttonSpacing);
buttonPositions[i].y = 0;
}
else if (menuDirection == "vertical")
{
buttonPositions[i].x = 0;
buttonPositions[i].y = i * (buttonSizes[i].h + buttonSpacing);
}
buttonHolders[i] = new GenericButton (menuHolder, buttonClips[i], buttonDepths[i], buttonTextFields[i], buttonLabels[i], buttonSizes[i], buttonPositions[i], buttonTargets[i]);
};
};

public function getMenuScope (Void): MovieClip
{
return menuScope;
};
public function setMenuScope (menuScope: MovieClip): Void
{
if (menuScope) this.menuScope = menuScope;
};

public function getMenuClip (Void): String
{
return menuClip;
};
public function setMenuClip (menuClip: String): Void
{
if (menuClip) this.menuClip = menuClip;
};

public function getMenuDepth (Void): Number
{
return menuDepth;
};
public function setMenuDepth (menuDepth: Number): Void
{
this.menuDepth = menuDepth;
};

public function getMenuLabel (Void): String
{
return menuLabel;
};
public function setMenuLabel (menuLabel: String): Void
{
if (menuLabel) this.menuLabel = menuLabel;
};

public function getMenuSource (Void): Object
{
return menuSource;
};
public function setMenuSource (menuSource: Object): Void
{
if (menuSource) this.menuSource = menuSource;
};

public function getMenuPosition (Void): Object
{
return menuPosition;
};
public function setMenuPosition (menuPosition: Object): Void
{
if (menuPosition.x && menuPosition.y) this.menuPosition = menuPosition;
};

public function getMenuDirection (Voic): String
{
return menuDirection;
};
public function setMenuDirection (menuDirection: String): Void
{
if (menuDirection) this.menuDirection = menuDirection;
};
}


gebruik:
Deze class roep je aan in de .fla waar je je menu wilt hebben, op deze manier:
var myMenu: GenericMenu = new GenericMenu (_root, "menuLinkageID", 10, "myMenu", myMenuSourceObject, {x: 50, y: 50}, "vertical");
(Straks zal ik een duidelijk voorbeeld geven)

Class 3: GenericMenuXMLSource
Deze class parsed een xml bestand in een object wat gebruikt wordt door de GenericMenu class hierboven.

code:

class GenericMenuXMLSource
{
private var XMLObject: XML;
private var XMLSource: String;
private var menuSource: Object;

public function GenericMenuXMLSource (XMLSource: String)
{
init(XMLSource);
};

public function init (XMLSource: String): Void
{
setXMLSource(XMLSource);
loadXML();
};

public function loadXML (Void): Void
{
var classReference: GenericMenuXMLSource = this;

XMLObject = new XML();
XMLObject.ignoreWhite = true;
XMLObject.onLoad = function (success: Boolean)
{
if (success) classReference.processXML();
};
XMLObject.load(getXMLSource());
};

public function processXML (Void): Void
{
menuSource = new Object();
menuSource.buttonClips = new Array();
menuSource.buttonDepths = new Array();
menuSource.buttonTextFields = new Array();
menuSource.buttonLabels = new Array();
menuSource.buttonSizes = new Array();
menuSource.buttonSpacing = new Number;
menuSource.buttonTargets = new Array();

var xmlRoot: XMLNode = XMLobject.firstChild
var menuLength: Number = xmlRoot.childNodes.length;
for (var i: Number = 0; i < menuLength; ++i)
{
menuSource.buttonClips[i] = xmlRoot.childNodes[i].attributes.buttonClip;
menuSource.buttonDepths[i] = Number(xmlRoot.childNodes[i].attributes.buttonDepth);
menuSource.buttonTextFields[i] = xmlRoot.childNodes[i].attributes.buttonTextField;
menuSource.buttonLabels[i] = xmlRoot.childNodes[i].attributes.buttonLabel;
menuSource.buttonSizes[i] = {w: Number(xmlRoot.childNodes[i].attributes.buttonSizeW), h: Number(xmlRoot.childNodes[i].attributes.buttonSizeH)};
menuSource.buttonSpacing = Number(xmlRoot.attributes.buttonSpacing);
menuSource.buttonTargets[i] = {linkType: xmlRoot.childNodes[i].attributes.buttonTargetLinkType, destination: xmlRoot.childNodes[i].attributes.buttonTargetDestination, scope: xmlRoot.childNodes[i].attributes.buttonTargetScope};
};
};

public function setXMLSource (XMLSource: String): Void
{
if (XMLSource) this.XMLSource = XMLSource;
};
public function getXMLSource (Void): String
{
return XMLSource;
};

public function getMenuSource (Void): Object
{
return menuSource;
};
}


gebruik:
Deze class roep je aan voor de GenericMenu class, dit gaat als volgt:

var myMenuSource: GenericMenuXMLSource = new GenericMenuXMLSource("MenuSource.xml");

var myMenuSourceObject: Object = new Object();
myMenuSourceObject = myMenuSource.getMenuSource();


Mini-tutorial:
Zie volgende post .. .dit wordt veel te lang

Waar blijft Actionscript 2.0 ondersteuning op FlashFocus beste mensen?

Tommyfied
%Europe/Berlin %917 %2005, 23:01
Ok komtie:

Mini tutorial over gebruik GenericMenu

Open een lege .fla.

Maak daarin een MovieClip, teken er een mooie button in.
Maak in die MovieClip framelabels aan met de namen:
#rollOn
#rollOff
#click
(gebruik de nodige stop acties)
Maak in die MovieClip een dynamic TextField en geef deze een instance name
Zet deze MovieClip in je library en geef hem een linkageID

Ga terug naar je main timeline

Maak een nieuwe lege MovieClip en geef deze een instance name en plaats deze in je library (hierin wordt het menu, de buttons, geladen)

Maak een aantal framelabels aan met bijvoorbeeld de namen:
#home
#page1
#page2
#page3
(gebruik de nodige stop acties)

Zet de volgende code neer op frame 1:

var myMenuSource: GenericMenuXMLSource = new GenericMenuXMLSource("MenuSource.xml");

var myMenuSourceObject: Object = new Object();
var intID: Number = setInterval(functionName = function ()
{
myMenuSourceObject = myMenuSource.getMenuSource();
var myMenu: GenericMenu = new GenericMenu (_root, "menuLinkageID", 10, "myMenu", myMenuSourceObject, {x: 50, y: 50}, "vertical");
clearInterval(intID);
}, 1000);

De setInterval staat eromheen omdat het even duurt voor het object gemaakt is. Laat je dit weg dan roep je het object te snel aan en is het nog undefined, met als gevolg dat er geen menu zichtbaar is. Mocht je het echt gaan gebruiken op een site dan is dit niet nodig aangezien je die site als het goed is toch preload. ;)

Maak nu een XML bestand aan met de naam MenuSource.xml
Zet daarin zoiets als dit:

<?xml version="1.0" encoding="iso-8859-1"?>
<menuSource buttonSpacing="10">

<menuItem buttonClip="buttonLinkID" buttonDepth="100" buttonTextField="labelText" buttonLabel=".01 Home" buttonSizeW="250" buttonSizeH="25" buttonTargetLinkType="frame" buttonTargetDestination="#home" buttonTargetScope="_level0"></menuItem>
<menuItem buttonClip="buttonLinkID" buttonDepth="101" buttonTextField="labelText" buttonLabel=".02 Page" buttonSizeW="250" buttonSizeH="25" buttonTargetLinkType="frame" buttonTargetDestination="#page1" buttonTargetScope="_level0"></menuItem>
<menuItem buttonClip="buttonLinkID" buttonDepth="102" buttonTextField="labelText" buttonLabel=".03 Page" buttonSizeW="250" buttonSizeH="25" buttonTargetLinkType="frame" buttonTargetDestination="#page2" buttonTargetScope="_level0"></menuItem>
<menuItem buttonClip="buttonLinkID" buttonDepth="103" buttonTextField="labelText" buttonLabel=".04 Page" buttonSizeW="250" buttonSizeH="25" buttonTargetLinkType="frame" buttonTargetDestination="#page3" buttonTargetScope="_level0"></menuItem>
<menuItem buttonClip="buttonLinkID" buttonDepth="104" buttonTextField="labelText" buttonLabel="www.google.com" buttonSizeW="250" buttonSizeH="25" buttonTargetLinkType="url" buttonTargetDestination="http://www.google.com"></menuItem>

</menuSource>

(verander de parameters afhankelijk van je eigen instellingen)

Publish je .fla en alles zou moeten werken!
Mochten deze instructies te kort door de bocht zijn:

Voorbeeld files:
Generic Menu Classes:
GenericButton (http://home.planet.nl/~polma288/flashfreaks/Tommyfied/GenericButton.as)
GenericMenu (http://home.planet.nl/~polma288/flashfreaks/Tommyfied/GenericMenu.as)
GenericMenuXMLSource (http://home.planet.nl/~polma288/flashfreaks/Tommyfied/GenericMenuXMLSource.as)

Ondersteunende bestanden:
GenericMenu.fla (http://home.planet.nl/~polma288/flashfreaks/Tommyfied/GenericMenu.fla)
GenericMenu.swf (http://home.planet.nl/~polma288/flashfreaks/Tommyfied/GenericMenu.swf)
GenericMenu.html (http://home.planet.nl/~polma288/flashfreaks/Tommyfied/GenericMenu.html)
MenuSource.xml (http://home.planet.nl/~polma288/flashfreaks/Tommyfied/MenuSource.xml)

Met dank aan Roenes

Veel succes ermee! :D

Roenes
%Europe/Berlin %919 %2005, 23:03
Ik meldde via msn al dat ik em tof vond! Ik zal later even uitgebreid door je code knallen en op en aanmerkingen geven.

ff kijken of ik al die programmeer regels die we op school kregen nog weet ;)

Tha Narie
%Europe/Berlin %923 %2005, 23:10
Lekkere code man! Heb hem nog niet getest, maar zal vast goed werken ;)

Ik heb wel een paar vraagjes/opmerkingen over je code:


- Ik neem aan dat je de constructor altijd als wrapper gebruikt voor je init-functie?
Dan zou je deze regel ook zo kunnen doen:
init(buttonScope, buttonClip, buttonDepth, buttonTextField, buttonLabel, buttonSize, buttonPosition, buttonTarget);
init(arguments);
Typechecking wordt toch gedaan in de constructor, dus de types zijn altijd goed.

- Is er een reden dat je geen getter/setters gebruikt "public function set funcName(){};" ?
Lijkt mij makkelijker in gebruik.

- Dit kan ook zo volgens mij:
buttonHolder.onRollOut = buttonHolder.onDragOut = function () { classReference.onRollOff(); };
buttonHolder.onRollOut = buttonHolder.onDragOut = classReference.onRollOff;

---

Leuke tutorial, nu geen tijd om hem te volgen, SWF zag er leuk uit, maar zoals ik al zei klopt de rollOut na een onRelease niet helemaal ;)

Wat ik ook nog zou willen hebben is een callBack-functie, waarmee ik zelf dingen kan afhandelen, die natuurlijk de button-data mee krijgt als argument.

Verder top!

Tommyfied
%Europe/Berlin %928 %2005, 23:17
Ok ... op volgorde mijn reacties:

1.
Top idee, scheelt weer een copy-paste actie :D en staat netter ... had ik zelf aan moeten denken.

2.
Ik hou er niet van om direct properties aan te spreken ... is persoonlijke voorkeur.

3.
Heb ik geloof ik geprobeerd maar dat ging niet ...

4.
Ja dat klopt ... dat ligt deels aan de animatie die ik voor de rollover gebruik en deels aan het feit dat hij na de click nog een rollout event herkent.
Oplossing(en): andere animatie gebruiken, of beter: op een of andere manier die rollout disabelen na een click tot de gebruiker weer van de button af is. Dat wordt alleen heel erg gecompliceerd if'jes / hitTest werk waar ik geen zin in had. Ik kan wel leven met die verschieting naar roze maar als iemand dat niet kan moet die maar even in de code duiken. :P

5.
Ik wil ook wel callBack's :P
Nee dat is misschien wel iets wat ik er later nog inbouw, dat maakt het wel een stuk ingewikkelder altijd ...

Tha Narie
%Europe/Berlin %932 %2005, 23:23
2.
Is niet 'direct' aanspreken, ze lopen wel via die 2 functies, alleen je gebruikt ze alsof het properties zijn :)

3.
Moet toch werken lijkt me, zelfde als dit wat altijd werkt:
XML.onLoad = myOnLoadCallback;
myOnLoadCallback = function(){...};

5.
Simpel toch. Gewoon aan addListener aanmaken, een _listener-array intern bijhouden, en in de onClick functie daar doorheen loopen en _listener[i].onClick aanroepen. :)

Tommyfied
%Europe/Berlin %936 %2005, 23:28
2.
Je spreekt ze in zoverre direct aan dat je dit doet buiten de class: myMenu.menuSource ipv myMenu.getMenuSource / myMenu.setMenuSource en dat vind ik niet fijn . :)

3.
Ik heb het geprobeerd:

**Error** *censored* Line 113: Type mismatch in assignment statement: found Void where Function is required.
buttonHolder.onRelease = buttonHolder.onReleaseOutside = classReference.onClick();

Tada Actionscript 2.0, in Actionscript 1.0 zal het wel gaan denk ik ...

5.
Mjah het is relatief "simpel" ja ... maar ik vind dat listener gedoe toch altijd vervelender dan het op het eerste gezicht lijkt ... ik heb altijd het idee dat ik er meer werk in steek dan ik ervoor terug krijg. :)

Tha Narie
%Europe/Berlin %938 %2005, 23:31
2.
Waarom vind je dat niet fijn? Omdat het makkelijker in gebruik is? :P

3. je moet onClick; doen, niet onClick();

5.
Tijd om het een keertje te doen, dan kan je het in de toekomst hergebruiken ;)

Tommyfied
%Europe/Berlin %939 %2005, 23:32
2.

Grr :P Welles en nietes is leuk he ...

3. is aangepast in de post
5. jij wint, ik zal er maar een keertje aan beginnen (morgen of volgende week :P)

Roenes
%Europe/Berlin %510 %2005, 13:15
Hier ben ik dan eindelijk. :D

Ik zal eerst even op en aanmerkingen geven op de code en daarna nog wat vragen/reacties geven op jouw en narie's gesprek ;)

GenericButton
In de functie displayButton zet je dit:

buttonHolder._width = getButtonSize().w;
buttonHolder._height = getButtonSize().h;
Zoals ik al aangaf op msn is het netter om het object maar 1x op te vragen en deze op te slaan in een tijdelijke var. Nu vraag je 2x hetzelfde object op. Das natuurlijk niet zo netjes:

var buttonSize:Object = getButtonSize();
buttonHolder._width = buttonSize.w;
buttonHolder._height = buttonSize.h;
Hetzelfde natuurlijk bij getButtonPosition() ;) Alle andere varianten van dit wat ik nog tegenkom meld ik nie meer ;)

In de onClick functie eigenlijk hetzelfde principe. Je roept meerdere malen getButtonTarget() aan. Dat kan vertragend werken.

GenericMenu
Eigenlijk niks op aan te melden :)

GenericMenuXMLSource
In processXML() sla alsjeblieft even een path op naar de huidige node. Deze manier maakt het wat onduidelijk. ;)

Voor de rest geen aanmerkingen meer op je code. Voor sommige komt dit misschien zeikend over maar het was de bedoeling dat ik deze kleine dingen ging zoeken ;)


- Ik neem aan dat je de constructor altijd als wrapper gebruikt voor je init-functie?
Dan zou je deze regel ook zo kunnen doen:
init(arguments);
Vraagje, als je dit doet, dan geef je de argumenten mee in een array van arguments. Dan komt dat toch niet overeen met de functiebeschrijving van init? En kun je in de init dan nog gewoon met buttonScope en buttonDepth enz enz werken of moet je dan die dingen gaan benaderen vanuit de array? Want dat zou het onnodig lastig maken :)

En over dat getter en setter gebeuren:
Ik vind het altijd twijfelachtig wat je het best kan doen. Steeds myMenu.setX(150); doen ipv myMenu.x = 150; vind ik idd lastig. Maar als je er getter en setters van maakt dan is het toch niet meer duidelijk voor andere welke prop's je "direct" kan benaderen en welke je via een get of set moet opvragen? Zelf gebruik ik tot nu toe Tommyfied's manier maar Narie's manier is dan weer makkelijker.

Maar even 1 ding voor de duidelijkheid. Stel je hebt dit:

public function set xpos(x:Number):Void
{
if(x > 0 && x < 200) this.xpos = x;
}

myMenu.xpos = 150;
nu wordt xpos toch aangeroepen en wordt de check uitgevoerd he? Dus het enige voordeel tov het public maken van de prop is dat je er op deze manier checks op los kan laten. :)

En tjah, dit was het wel zo'n beetje. Ik moet zeggen dat het duidelijke code is en op zich erg handige classes! :)

Tommyfied
%Europe/Berlin %520 %2005, 13:30
GenericButton

Ok vooruit, ik zal je blij maken en dat aanpassen. Hoewel het naar mijn mening met dit kleine objectje vrij weinig tot niets uitmaakt :p Maar toch zal het even aanpassen.

GenericMenu

:)

GenericMenuXMLSource

Je wil dus dat ik dit buiten de for-loop zet:
var xmlRoot: XMLNode = XMLObject.firstChild;
En dan binnen de for-loop zo doe:
for (var i: Number = 0; i < menuLength; ++i)
{
menuSource.buttonClips = xmlRoot.childNodes[i].attributes.buttonClip;
menuSource.buttonDepths[i] = Number(xmlRoot.childNodes[i].attributes.buttonDepth);
menuSource.buttonTextFields[i] = xmlRoot.childNodes[i].attributes.buttonTextField;
menuSource.buttonLabels[i] = xmlRoot.childNodes[i].attributes.buttonLabel;
menuSource.buttonSizes[i] = {w: Number(xmlRoot.childNodes[i].attributes.buttonSizeW), h: Number(xmlRoot.childNodes[i].attributes.buttonSizeH)};
menuSource.buttonSpacing = Number(xmlRoot.attributes.buttonSpaci ng);
menuSource.buttonTargets[i] = {linkType: xmlRoot.childNodes[i].attributes.buttonTargetLinkType, destination: xmlRoot.childNodes[i].attributes.buttonTargetDestination, scope: xmlRoot.childNodes[i].attributes.buttonTargetScope};
};
Vind dat zelf niet echt een verbetering qua leesbaarheid ... maar misschien is het wel wat sneller omdat ik dan maar een keer het zooitje opvraag, ik zal het aanpassen.

Vraagje, als je dit doet, dan geef je de argumenten mee in een array van arguments. Dan komt dat toch niet overeen met de functiebeschrijving van init? En kun je in de init dan nog gewoon met buttonScope en buttonDepth enz enz werken of moet je dan die dingen gaan benaderen vanuit de array? Want dat zou het onnodig lastig maken
Daar zit wel wat in ja ... ik denk dat ik het gewoon zo laat staan. Vind ik ook duidelijker omdat je dan goed ziet dat ik puur argumenten wil overhevelen.

nu wordt xpos toch aangeroepen en wordt de check uitgevoerd he? Dus het enige voordeel tov het public maken van de prop is dat je er op deze manier checks op los kan laten.
Het is sowieso "bad-practise" om properties public te maken en ze dan direct aan te spreken. Daarvoor zijn getters/setters in het leven geroepen (en om zo checks te zetten voor een bepaalde propertie als in je voorbeeldje).
Of je dan getters/setters gebruikt om de Macromedia manier (met get en set) of in de vorm van pure functies maakt volgens mij niet veel uit qua werking / snelheid / oid. Ik vind het fijn om functies te gebruiken dus doe ik dat. :p

"Zeikerig" zijn mag altijd he :)

Roenes
%Europe/Berlin %525 %2005, 13:36
Bij die xml zou ik het zo doen:

for (var i: Number = 0; i < menuLength; ++i)
{
var currentNode:XMLNode = XMLObject.firstChild.childNodes[i];
menuSource.buttonClips = currentNode.attributes.buttonClip;
menuSource.buttonDepths[i] = Number(currentNode.attributes.buttonDepth);
menuSource.buttonTextFields[i] = currentNode.attributes.buttonTextField;
menuSource.buttonLabels[i] = currentNode.attributes.buttonLabel;
menuSource.buttonSizes[i] = {w: Number(currentNode.attributes.buttonSizeW), h: Number(currentNode.attributes.buttonSizeH)};
menuSource.buttonSpacing = Number(currentNode.attributes.buttonSpaci ng);
menuSource.buttonTargets[i] = {linkType: currentNode.attributes.buttonTargetLinkType, destination: currentNode.attributes.buttonTargetDestination, scope: currentNode.attributes.buttonTargetScope};
};
Maar dit is volgens mij ook meer eigen smaak als regel :)

Tha Narie
%Europe/Berlin %532 %2005, 13:46
@ init(argumenets)
Stom van me, was laat gisteravond, werkt natuurlijk niet.

@ xml currentNode.
Heb je zeker gelijk in! Viel me de 1e x ook al op, maar was ik vergeten.
Je zou zelfs '.attributes' nog erbij kunnen nemen, omdat je die ook constant herhaalt.

@ public set
Ik snap niet precies wat je daar mee wilt zeggen.
Props die je buiten je class wilt gebruiken moet je public maken dmv een getter/setter als er een kans op checks is, anders maakt het weinig uit, de rest lekker private laten. Naar mijn mening zijn getters/setters > property juist heel handig, wel om de volgende vergelijking tussen Flash5 en FlashMX:

// Flash5 manier
setProperty("_root.MC", "_x", getProperty("_root.MC", "_x") + 20);
// FlashMX manier (getter/setter > property)
_root.MC._x += 20;
// Jouw manier
_root.MC.setX(_root.MC.getX()+20);

Ik heb m'n keuze snel gemaakt :)

Tommyfied
%Europe/Berlin %533 %2005, 13:47
Klein debatje over xml schortcuts:

Thomas™ zegt:
maar ik vraag me af of het wel waardis om te doen
Thomas™ zegt:
je bereikt er niets mee behalve leesbaarheid ...
Thomas™ zegt:
ik zou mijn oplossing doen
Thomas™ zegt:
:)
Roenes zegt:
ehmz.. of het iets waard is weet ik niet.. maar het is leesbaarder dus gebruiksvriendelijker voor een andere programmeur
Thomas™ zegt:
je vind mijn ding onleesbaar (na verbetering?)
Roenes zegt:
neej.. maar het kan dus nog een stapje leesbaarder omdat ik die childNodes[i] uit het path haal die jij meerdere keren nog neerzet..
Roenes zegt:
maar volgens mij is dit meer smaak als regel
Thomas™ zegt:
ja (klein dingetje daarover: Number(currentNode.attributes.buttonSpacing); is natuurlijk fout he)
Thomas™ zegt:
buttonSpacing is een attribute van firstChild
Thomas™ zegt:
(geld voor heel het menu)
Roenes zegt:
was me niet opgevallen
Thomas™ zegt:
dus dan zou je daar weer een hele verwijzing moeten maken
Thomas™ zegt:
dan wordt het wel verwarrend he :p
Roenes zegt:
:)
Thomas™ zegt:
ik blijf bij mijn ding
Roenes zegt:
:) ok

Hier wil ik het bij laten wat betreft het xml gedeelte. :p

Verder, die init / arguments kwestie lijkt me ook duidelijk.

Dan wat betreft het aanspreken van properties:

Properties die je buiten je class wil aanspreken moet je public maken.
Dat is niet waar, kijk maar naar de property menuSource. Die is private maar spreek ik buiten de property aan d.m.v. mijn getter getMenuSource()
Dat is het hele idee van getters/setters ... gebruikers forceren om via functies properties aan te spreken zodat men niet direct bij de properties kan en de waardes die aan de properties worden toegevoegd gechecked kunnen worden op geldigheid (zie het voorbeeldje van Roenes).
Naar mijn mening zijn getters/setters > property juist heel handig, wel om de volgende vergelijking tussen Flash5 en FlashMX ... etc.
In jou voorbeeld zou ik ook geneigd zijn om get en set te gebruiken. Maar bij variabelen die niet incrementeel hoeven te veranderen maar gewoon compleet andere waardes krijgen vind ik het gebruik van functies netter. Je ziet dan duidelijker of je een property opvraagt of veranderd. Maar dit is een lastig onderwerp ... ik gebruik zelf al heel lang functies en dat bevalt me goed maar nu neig ik toch wel meer naar get en set.
Conclusie van het geheel is dat het in ieder geval niks uitmaakt qua performance maar alleen afhangt van persoonlijke voorkeur. Beide methodes hebben hun eigen voordelen denk ik.

Roenes
%Europe/Berlin %539 %2005, 13:56
@ public set
Ik snap niet precies wat je daar mee wilt zeggen.
Props die je buiten je class wilt gebruiken moet je public maken, de rest lekker private laten. Wat ik wilde zeggen is dat als je getters en setters maakt dat je dan je prop gewoon private kan laten. en je kunt er extra checks op los laten. Dit is een voordeel tov het gewoon public maken van een prop. Dat wilde ik aangeven.

En met je voorbeeld heb je wle gelijk. Getters en setters zijn dan een stuk handiger. :)

En over dat xml: daar laten we het idd bij. Is genoeg over gezegd wat mij betreft :)

Tha Narie
%Europe/Berlin %543 %2005, 14:02
Thomas™ zegt:
maar ik vraag me af of het wel waardis om te doen
Thomas™ zegt:
je bereikt er niets mee behalve leesbaarheid ...


weer kleine vergelijking:

_root.holder.createEmptyMovieClip("mc_" + i, i);
_root.holder["mc_" + i]._x = i*10;
_root.holder["mc_" + i]._y = 100;
_root.holder["mc_" + i]._alpha = Math.random()*100;
// vs
var mc = _root.holder.createEmptyMovieClip("mc_" + i, i);
mc._x = i*10;
mc._y = 100;
mc._alpha = Math.random()*100;

Duidelijk welke ik zou kiezen. Bovendien is hij (olgens mij) ook sneller, want net als bij die childNodes moet je de hele tijd een waarde uit een array uitlezen, en daar weer verder mee gaan. Als je een variable gebruikt heb je deze referentie al opgeslagen.

Punt. ;)

Tommyfied
%Europe/Berlin %551 %2005, 14:13
In jouw voorbeeld is geen sprake van een Array volgens mij, dat even terzijde.
In childNodes is daar wel sprake van ... ik denk dat de methode van Roenes wat dat betreft de minste "redundancy" heeft aangezien hij maar 1 keer per for loop een referentie opslaat naar de huidige childNode (en dus maar 1 keer iets uit die array hoeft te halen). Echter wordt het bij hem wel verwarrend aangezien je niet overal de currentNode variabele kunt gebruiken, je meot bij buttonSpacing dan weer het hele pad gebruiken.
Wat je nog zou kunnen doen is de oplossing van mij en Roenes en Narie combineren:

var xmlRoot: XMLNode = XMLObject.firstChild;
var menuLength: Number = xmlRoot.childNodes.length;
for (var i: Number = 0; i < menuLength; ++i)
{
var currentNodeAttributes: XMLNode = xmlRoot.childNodes[i].attributes
menuSource.buttonClips = currentNodeAttributes.buttonClip;
menuSource.buttonDepths[i] = Number(currentNodeAttributes.buttonDepth);
menuSource.buttonTextFields[i] = currentNodeAttributes.buttonTextField;
menuSource.buttonLabels[i] = currentNodeAttributes.buttonLabel;
menuSource.buttonSizes[i] = {w: Number(currentNodeAttributes.buttonSizeW), h: Number(currentNodeAttributes.buttonSizeH)};
menuSource.buttonSpacing = Number(xmlRoot.attributes.buttonSpacing);
menuSource.buttonTargets[i] = {linkType: currentNodeAttributes.buttonTargetLinkType, destination: currentNodeAttributes.buttonTargetDestination, scope: currentNodeAttributes.buttonTargetScope};
};

Dat is dan denk ik de "snelste" maar of het er nou leesbaarder op wordt ...

*Voor de duidelijkheid, in het voorbeeld van Narie is het tweede gedeelte sneller en makkelijker.*

Tha Narie
%Europe/Berlin %558 %2005, 14:24
Dat is opzich ook een array hoor. Elke timeline bevat een array van objecten en variables. Of eigenlijk meer een Object, maar het principe is hetzelfde.

Eigenlijk is die hele XML 'fout' qua gebruik. Arguments moet je eigenlijk niet gebruiken om data in op te slaan, maar meer om een ID ofzo mee te geven. Data zouden in childNodes moeten staan.

Maar je zou het nog leuker kunnen maken:

for(var a in currentNodeAttributes) menuSource[currentNodeAttributes[a]][i] = currentNodeAttributes[a];
// werkt aleen in deze situatie niet lekker, aangezien je heel veel custon shit doet


Overschrijf je trouwens in deze regel niet elke keer die property?:
menuSource.buttonClips = currentNodeAttributes.buttonClip;

Roenes
%Europe/Berlin %559 %2005, 14:26
In jouw voorbeeld is geen sprake van een Array volgens mij, dat even terzijde.Zeker wel. Alle mc's, buttons enz enz staan in een (assiociatieve (Schrijf je dat zo? :D)) array vandaar dat de array notatie werkt. :)

Tommyfied
%Europe/Berlin %561 %2005, 14:28
Hmm ok dat verhaaltje over de timeline klopt wel, laten we het daar maar bij laten. :I :p

Ik heb alles in attributes omdat ik altijd moet stoeien met die vervelende nodeValue dingen zodra ik speciale tekens gebruik.

Ik snap niet echt hoe dat trucje opgaat in mijn situatie (zo te zien niet zoals je al zei maar toch).

Je hebt gelijk dat zal wel een overneem / typfoutje zijn geweest. Staat goed in de voorbeeld files in ieder geval (anders werkt het ook niet :)).

Dauntless
%Europe/Berlin %573 %2005, 14:45
Haai,

Ik wou gewoon nog ff zeggen dat het heel nice is! Over de code zelf weet ik ook niets te zeggen dat nog niet gezegd is... Maar mooi gedaan! :)

Greets,
me

Roenes
%Europe/Berlin %582 %2005, 14:58
Ik heb alles in attributes omdat ik altijd moet stoeien met die vervelende nodeValue dingen zodra ik speciale tekens gebruik.
Daar bestaat <![CDATA[Hier je tekst :)]]> voor he ;)

Tommyfied
%Europe/Berlin %643 %2005, 16:27
Dat valt zeer heel erg veel tegen altijd bij mij. Probeer maar eens zoiets als dit via XML in te laden en in een dynamisch tekstveld weer te geven:

Op curaçao is het vaak héél mooi weer, hè?

Tha Narie
%Europe/Berlin %650 %2005, 16:36
<![CDATA[ is eigenlijk voor HTML-tekst, als je <>&#%-dingen wilt gebruiken
Als je speciale tekens zoals éüà wilt gebruiken, moet je gewoon zorgen dat ze utf-8 encoded zijn :)

Tommyfied
%Europe/Berlin %656 %2005, 16:45
Dus ipv:
<?xml version="1.0" encoding="iso-8859-1"?>
Moet ik
<?xml version="1.0" encoding="utf-8"?>
Boven mijnXML file zetten?

Roenes
%Europe/Berlin %663 %2005, 16:54
Jah maar volgens mij moet je ook nog aangeven bij het opslaan van je bestand dat de encoding UTF8 is. Want je kunt het in het xml wel aangeven, maar dat is volgens mij alleen extra info en niet de echte encoding :)

Maar narie, alles wat in de cdata staat wordt toch genegeerd? Dus dan zou je daar toch ook die speciale karakters kunnen zetten want daar wordt toch niet naar gekeken :)

Tommyfied
%Europe/Berlin %664 %2005, 16:56
Vanavond op mijn eigen laptop maar eens even uit proberen dan met Dreamweaver :)

Dauntless
%Europe/Berlin %664 %2005, 16:57
Ohja, ik heb voor het 3de gestemd, maar dat betekend dus niet dat ik het niet leuk + goed vind! Ik gebruik gewoon liever m'n eigen dingen :D.

Roenes
%Europe/Berlin %681 %2005, 17:20
Even offtopic over de enquete:
Voordat ik gestemd heb kan ik precies zien wie waarop heeft gestemd maar nadat ik zelf gestemd heb, staan er geen namen meer bij. Terwijl het wel een publieke enquete is. Hoe zit dit? :)

Dauntless
%Europe/Berlin %686 %2005, 17:28
Even offtopic over de enquete:
Voordat ik gestemd heb kan ik precies zien wie waarop heeft gestemd maar nadat ik zelf gestemd heb, staan er geen namen meer bij. Terwijl het wel een publieke enquete is. Hoe zit dit? :)
'k Was ook juist aan het zoeken. Oplossing: klik op het aantal stemmers. Dus als 3 man voor optie 1 gestemd heeft, moet je op de '3' klikken. Dat zou wel duidelijker mogen... Jooriiim...

Tha Narie
%Europe/Berlin %716 %2005, 18:11
Maar narie, alles wat in de cdata staat wordt toch genegeerd? Dus dan zou je daar toch ook die speciale karakters kunnen zetten want daar wordt toch niet naar gekeken :)
Kan wel, maar heeft geen meerwaarde.
CDATA is voor tekens die problemen geven tijdens het XML-parsen, zoals hoofdzakelijk de <html>-tags, omdat de parser dan denkt dat het childNodes zijn, terwijl het gewoon HTMLtekst is. That's it :) Dit staat los van é-tekens.

Daarvoor moet je idd:
- in je xml-header de encoding op utf8 zetten
- je xml-file echt als utf8 (8bit) opslaan

De Kale
%Europe/Berlin %389 %2005, 10:20
ja, en ook je xml file opslaan als unicode (save as..)
de xml standaard zegt dat xml data default een utf-8 encoding heeft tenzij anders gespecificeerd

Tha Narie
%Europe/Berlin %439 %2005, 11:32
@ init(argumenets)
Stom van me, was laat gisteravond, werkt natuurlijk niet.


Beetje late reactie, maar ik liep net ergens tegenaan wat ik allang wist, maar helemaal was vergeten:


function doInit(a1, a2, a3, a4)
{
init.apply(this, arguments);
}

function init(b1, b2, b3, b4, b5)
{
trace(b1);
trace(b2);
trace(b3);
trace(b4);
trace(b5);
}

doInit(1, 2, 3, 4, 5);


Werkt dus wel op deze manier ;)

Tommyfied
%Europe/Berlin %451 %2005, 11:49
Beter laat dan nooit. Bedankt ... dat scheelt weer :)

H3lpd3sk
%Europe/Berlin %654 %2005, 15:42
Hmmmm vraagje van een AS n00b.
Buttons worden nu met een kleine setinterval in 1 keer gemaakt.
Hoe kan ik tussen het verschijnen van iedere button een setinterval krijgen.

Iemand een idee?

Tof script trouwens!

Ea.Z
%Europe/Berlin %076 %2005, 01:50
Dus ipv:
<?xml version="1.0" encoding="iso-8859-1"?>
Moet ik
<?xml version="1.0" encoding="utf-8"?>
Boven mijnXML file zetten?

zo is het...
voor de rest: nicely done... Kan er niets op zeggen dat nog niet verschenen is..
weer een lekker 'Hey, tof!'-dingje op FF meer om in de flashfocus-package te knallen... :D (of niet?)

Tommyfied
%Europe/Berlin %466 %2005, 11:11
Dat lijkt me een strak plan. Hoe staat het daar eigenlijk mee?

[m]
%Europe/Berlin %732 %2005, 17:34
zo is het...
voor de rest: nicely done... Kan er niets op zeggen dat nog niet verschenen is..
weer een lekker 'Hey, tof!'-dingje op FF meer om in de flashfocus-package te knallen... :D (of niet?)

Voor flash maakt het niet echt uit. :) Eigenlijk maar het voor geen enkele xml parser uit, want het is meer om te zeggen "DIT IS ECHT EEN XML JONGENS, ECHT WAAR 100%" dan echt nodig.

Tommyfied
%Europe/Berlin %738 %2005, 17:43
Nou dat maakt in Flash dus wel een wereld van verschil aangezien ik dan dus wel ineens speciale tekens kan inladen ... :)

Ea.Z
%Europe/Berlin %950 %2005, 22:48
Nou dat maakt in Flash dus wel een wereld van verschil aangezien ik dan dus wel ineens speciale tekens kan inladen ... :)
hierover moet duidelijkheid geschept worden.. ik werk met utf-8 omdat ik het zo de eerste keer gedaan heb, en het werkte meteen... "een winnend team verander je niet" wel, ik laat het dus bij utf-8
toch gaat er nu iemand mij uitleggen of het er wel of niet toe doet, en zoja, waarom?
er zijn al heel wat topics gepasseerd met zulke problemen, maar heb er nooit op blijven doordenken, maar nu wil ik het weten... ;) iemand?

H3lpd3sk
%Europe/Berlin %443 %2005, 10:38
Hmmmm vraagje van een AS n00b.
Buttons worden nu met een kleine setinterval in 1 keer gemaakt.
Hoe kan ik tussen het verschijnen van iedere button een setinterval krijgen.

Iemand een idee?

Tof script trouwens!

Hallo,

Had deze vraag al een tijdje geleden gesteld, is er misschien nog iemand die me hiermee zou kunnen helpen?

Folkert
%Europe/Berlin %651 %2005, 15:38
@h3lpd3sk stel je vraag even in een nieuw onderwerp ipv in een lopend onderwerp ;), de kans op antwoord is dan ook vele malen groter en ik alleen al zal je dankbaar zijn ;)

Dauntless
%Europe/Berlin %663 %2005, 15:55
Ohja, tommyfied, ik had voor het 2de gestemt, maar dat is gewoon omdat ik het zelf niet zou gebruiken en omdat er niet echt iets nieuws in zat (voor mij) ;). Maar dat wil nie tzeggen dat het een leuk script is natuurlijk!

Laiverd
%Europe/Berlin %949 %2005, 22:47
Nee, opslaan met UTF-8 encoding.

John