Jump to content


Photo

access layers and elements in a symbol script


  • Please log in to reply
15 replies to this topic

#1 nielswijers

nielswijers

    FireworksCommander

  • Members
  • Pip
  • 8 posts

Posted 30 July 2009 - 12:55 PM

heya people,

is there a way to access the layers or elements in a symbol.
i like to loop trough them to see which elements/layers there are

thx in advance

#2 SiamJai

SiamJai

    Fireworks Ninja

  • Members
  • PipPipPipPipPip
  • 205 posts

Posted 30 July 2009 - 05:40 PM

Right-click >> Symbol >> Edit Symbol may be what you are looking for.

Good luck and welcome to the forum! :)

#3 nielswijers

nielswijers

    FireworksCommander

  • Members
  • Pip
  • 8 posts

Posted 30 July 2009 - 10:51 PM

Heya SiamJai,

thx for your quick reply. but thats not what im looking for :D

in trying to build a symbol + a symbol script. with the jsf script in want to loop trough alle the layers to see which there are and then set some on the property panel to show/hide them or something. i want to make everything dynamic instead of hardcoding all the names.

i'm quite an experienced programmer, i dont find any good documentation on the language and the document object model

i hope someone can help me

thx,
Niels

#4 Mikko

Mikko

    Fireworks Ninja

  • Members
  • PipPipPipPipPip
  • 152 posts
  • Location:Helsinki, Finland
  • Interests:Bacon

Posted 31 July 2009 - 12:11 AM

in trying to build a symbol + a symbol script. with the jsf script in want to loop trough alle the layers to see which there are and then set some on the property panel to show/hide them or something. i want to make everything dynamic instead of hardcoding all the names.

i'm quite an experienced programmer, i dont find any good documentation on the language and the document object model

If i remember right, there was something about this subject in book "Foundation Fireworks CS4".

#5 nielswijers

nielswijers

    FireworksCommander

  • Members
  • Pip
  • 8 posts

Posted 31 July 2009 - 12:34 AM

Great im going to look for that!!

someone got a solution?
*edit* I just want the dom of the widget.

grz Niels

#6 SiamJai

SiamJai

    Fireworks Ninja

  • Members
  • PipPipPipPipPip
  • 205 posts

Posted 31 July 2009 - 01:54 AM

i'm quite an experienced programmer, i dont find any good documentation on the language and the document object model

i hope someone can help me

thx,
Niels


Sorry, Niels - I see now what you mean. :)

Have you read Adobe's "Extending Fireworks CS4" manual yet? It covers the Fireworks Object Model and API among other things. Maybe that will help.

Also, the particular book chapter that Mikko mentioned above can be downloaded for free, here on the Adobe Developer Center.

Good luck! :)

#7 nielswijers

nielswijers

    FireworksCommander

  • Members
  • Pip
  • 8 posts

Posted 31 July 2009 - 03:38 AM

no problem and thx SiamJai

ive look to the manual but it only gets met to getDocumentDOM or Widget.getObjectByName()

getDocumentDOM gives me the path to te current doc and not the widget

and

Widget.getObjectByName() doesnt give me the ability to read the layers :(

i want the dom of my widget to explorer the layers by code.
im clueless atm

#8 nielswijers

nielswijers

    FireworksCommander

  • Members
  • Pip
  • 8 posts

Posted 31 July 2009 - 06:41 AM

BAH :(

i think its impossible to get the dom tree of a symbol. tried everything with the commandline tool and FWAPIinspector. but really can't find it :'(

#9 Alan

Alan

    FireworksGuru

  • Root Admin
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 1,507 posts
  • Location:San Francisco, California USA
  • Interests:Longboarding, art and video games

Posted 31 July 2009 - 09:33 AM

I'm pretty sure you can only get the widgetbyname, I'll ask others local and see if there's a better option. (just saw your post) welcome to fwguru niel!

#10 nielswijers

nielswijers

    FireworksCommander

  • Members
  • Pip
  • 8 posts

Posted 31 July 2009 - 11:27 AM

I'm pretty sure you can only get the widgetbyname, I'll ask others local and see if there's a better option. (just saw your post) welcome to fwguru niel!


thx Alan,

Yeah thats what im thinking too. im curious if someone knows over there. for know i have another solution.

i wanted to make an advanced symbol where i can mix several states of the labels, sublabels, backgrounds and icons.
i have made an advanced component which goes up to 10 states for each (maybe im going to make this configurable due performance reasons, but it works right well over here)

this is an example out of the box. but its general purpose is for creating better elements for interaction designs and visual designs.

*edit*
If you want to start a new one, by deleting all the layers and then add you own.

for example:
add
- label1
- label2
- bg1
- bg2
- bg3

this wil result in a button with 2 label states and 3 background states

u can go up to 10 states each

*/edit*

i hope you guys like it. any advice is welcome

grz Niels

Attached Images

  • AdvancedComponent.png


#11 Alan

Alan

    FireworksGuru

  • Root Admin
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 1,507 posts
  • Location:San Francisco, California USA
  • Interests:Longboarding, art and video games

Posted 02 August 2009 - 06:28 PM

Nice man! I love the icon designs and your using 9 slice scaling in symbols, cool. :)

You also could make the icons switch using a combo box instead of the user entering a value.

#12 nielswijers

nielswijers

    FireworksCommander

  • Members
  • Pip
  • 8 posts

Posted 03 August 2009 - 01:21 AM

That's true. i could have used a combobox for the states. the original idea was to scan the layers of the symbol and generate lists for the comboboxes of the states. but too bad it isnt possible to loop trough the layers.

using input fields instead of comboboxes is maybe less friendly and less intuitive but atm it works faster for me :)

#13 jdunning

jdunning

    Fireworks Ninja

  • Members
  • PipPipPipPipPip
  • 173 posts

Posted 05 August 2009 - 11:33 AM

i wanted to make an advanced symbol where i can mix several states of the labels, sublabels, backgrounds and icons.
i have made an advanced component which goes up to 10 states for each (maybe im going to make this configurable due performance reasons, but it works right well over here)

One thing you might do is use a script to create the symbol and write out the symbol's .jsf file. For example, the user could create several icons, labels and backgrounds, select them, and then run a "Make Symbol" command. The advantage to this is that before the elements are turned into a symbol, the command has access to their names and layers. So the command could scan the selection, pick out the names of the elements, and then write out a .jsf that included the names in a combo box. Finally, it could prompt the user for a name and then call dom.convertToSymbol to turn the selection into a symbol. The user would then have to select it in the Document Library and select Save to Common Library to save it as a rich symbol, since there's no API for doing that, AFAIK.

#14 nielswijers

nielswijers

    FireworksCommander

  • Members
  • Pip
  • 8 posts

Posted 05 August 2009 - 11:35 PM

Hey thats sound like a pretty cool solution, didnt think about ik that way. this wil even make your scripts for the symbols more lightweight. i only see a problem when you want to change the symbol and add an icon or something that you need to run the script over a group of objects again instead of just changing the symbol.

maybe there is a function to break the symbol and run the script again.

but thx very good tip, im definitly going to try this out, im really curious about it

cheers!

#15 jdunning

jdunning

    Fireworks Ninja

  • Members
  • PipPipPipPipPip
  • 173 posts

Posted 06 August 2009 - 07:05 AM

i only see a problem when you want to change the symbol and add an icon or something that you need to run the script over a group of objects again instead of just changing the symbol.

The user could enter symbol editing mode and then run the command again. In that mode, the script should have access to the elements in the symbol, allowing you to then recreate the symbol script. I'm not sure if you'd know what the name of the symbol is in that mode, though.

#16 jdunning

jdunning

    Fireworks Ninja

  • Members
  • PipPipPipPipPip
  • 173 posts

Posted 27 August 2011 - 11:10 PM

ive look to the manual but it only gets met to getDocumentDOM or Widget.getObjectByName()

getDocumentDOM gives me the path to te current doc and not the widget

and

Widget.getObjectByName() doesnt give me the ability to read the layers :(

i want the dom of my widget to explorer the layers by code.

Sorry to revive a two-year-old thread, but it seemed like it would be useful to document the solution.

It turns out that there *is* a way to access the symbol's DOM, with some limitations. Although it's not documented, you can pass the symobl's ID to fw.getDocumentDOM() to get a reference to the symbol's DOM. So if a symbol is selected, fw.getDocumentDOM(fw.selection[0].symbolID) will return a reference to the symbol DOM. You can then inspect the DOM's layers array to get to the elements that make up the symbol.

However, you can't use this technique to make any changes to the symbol, which sucks. Being able to script changes to a symbol would be quite useful. Still, getting the names of elements in the symbol is enough to accomplish the original goal of making a dynamic symbol script. Once you have the element names, you can use Widget.GetObjectByName() to access it and change its properties.

Below is a rich symbol script that lets you show just one top-level element in a symbol. It scans the elements in the symbol and displays a combobox control containing the names of each top-level element. Selecting an item in the combobox will then show just that element and hide the rest. You can add or remove elements in the symbol without having to update the script, since each time the symbol is edited, the script is run again, which will update the combobox.

(function(){
	({
		"1": function() // setDefaultValues
		{
			// this is a noop, since when it's called as a symbol is first
			// added to the doc, calling fw.getDocumentDOM(Widget.elem.symbolID)
			// doesn't return anything, and without the list of elements in
			// the symbol, we can't do anything.  applyCurrentValues will
			// set up the currentValues array in customData.
		},

		"2": function() // applyCurrentValues
		{
			var customData = Widget.elem.customData,
				currentState = "",
				states = [],
				foundCurrentState = false;

				// our customData should have been set when the symbol was
				// initially created by the script, but check just to make sure
			if (customData.currentValues && customData.currentValues.length) {
				currentState = customData.currentValues[0].value.split(",")[0];
			}

			if (fw.getDocumentDOM().isSymbolDocument || !fw.getDocumentDOM(Widget.elem.symbolID)) {
				if (!customData.currentValues) {
						// we're in another symbol or we can't get the DOM
						// and our customData is empty for some reason, so
						// we have to bail
					return;
				}

					// since we can't access the symbol's DOM right now, we
					// have to use the state names that are stored in our
					// customData and hope they're still right
				states = customData.currentValues[0].value.split(",").slice(1);
			} else {
					// store the names of all the state groups on the first
					// layer in the symbol, so that our states list is in
					// sync with the current contents of the symbol
				var elems = fw.getDocumentDOM(Widget.elem.symbolID).layers[0].frames[0].elements;

				for (var i = 0; i < elems.length; i++) {
					if (elems[i].name) {
							// only push the state if it has a name
						states.push(elems[i].name);
					}
				}
			}

				// go through each element on the first layer and set its
				// visibility appropriately
			for (var i = 0; i < states.length; i++) {
					// we have to use Widget.GetObjectByName to access the
					// element, rather than going through the elems array,
					// because, otherwise, changes to the visible state don't
					// get reflected in the canvas 
				var element = Widget.GetObjectByName(states[i]);

				if (element.name == currentState) {
					element.visible = true;
					foundCurrentState = true;
				} else {
					element.visible = false;
				}
			}

			if (!foundCurrentState) {
					// the user must have deleted the currently selected
					// state group, which means the loop above hid all the
					// sub-groups.  so default the currentState to the
					// first state and show that group, so the symbol
					// doesn't go blank.
				currentState = states[0];
				Widget.GetObjectByName(currentState).visible = true;
			}

				// set the combobox in customData, since the setDefaultValues
				// opCode is now a noop.  this ensures that the combobox
				// doesn't get set until we know what elements are in the symbol.
			Widget.elem.customData.currentValues = [{
				name: "State",
				type: "combobox",
				value: [currentState].concat(states).join(",")
			}];
		}
	})[Widget.opCode]();
})();

Hope that helps.