Jump to content


Photo

Smart Shape Edited method


  • Please log in to reply
4 replies to this topic

#1 mitya777

mitya777

    FireStarter

  • Members
  • PipPip
  • 28 posts

Posted 21 March 2011 - 08:33 AM

Hi guys, back again with more auto shape issues!

I am trying to run some code from the SmartShapeEdited event, and the functions are not running.

Relevant Code:

var data = smartShape.elem.customData;
var operation = new Object();

operation.SmartShapeEdited = function(){
data.labelText = "default text";
DrawLabel();
}

/*RUN*/
if (operation[smartShape.operation])
operation[smartShape.operation]();

If, however I put the same calls in another event, say the EndDragControlPoint event everything gets called and works as it should. Is there something that I am missing? Is there some wrinkle regarding SmartShapeEdited that I am unaware of?

#2 jdunning

jdunning

    Fireworks Ninja

  • Members
  • PipPipPipPipPip
  • 173 posts

Posted 21 March 2011 - 05:17 PM

Hi guys, back again with more auto shape issues!

I am trying to run some code from the SmartShapeEdited event, and the functions are not running.

How do you know they're not running? One limitation with the SmartShapeEdited event is that changes to the shape often don't seem to actually get applied. In my Lorem Ipsum shape, I wanted to relayout the text if the user select the text element and changed its size in the Properties panel, which involves updating the textRuns to add or remove words. But editing the text element directly didn't produce any visible change, even though the code seemed to execute.

So instead, I had to find the edited shape in the current selection, change the selection to just the shape, then use the dom.setTextRuns() methods to reapply the text changes, then restore the selection. Here's the relevant handler:

onSmartShapeEdited: function()
{
		// this is our text before we've updated it to take into account
		// whatever edits the user's made.  we'll use it to identify our
		// shape among the selected elements below.
	var originalText = this.getText();

	if (this.smartShape.elem.elements[this.k.TextBlockIndex].textRuns.textRuns.length > 1) {
		alert("Styling or editing individual words in the Lorem Ipsum text is not supported. Any edits you make on words will be lost.");
	}

		// the user presumably changed the font formatting, which may have
		// changed the size of the text, so refit it to the shape bounds
	this.redraw(this.getBounds());

	var originalSelection = [].concat(fw.selection);

	for (var i = 0, len = originalSelection.length; i < len; i++) {
		var element = originalSelection[i];

			// look for a text element that contains exactly the text
			// that we started out with before redrawing the shape.  we
			// assume this is our shape, which might not be true if there
			// are duplicated LoremIpsum shapes with the identical text
			// that are also in the selection.  but since each shape
			// will get an onSmartShapeEdited event, all the shapes'
			// text elements should get updated.
		if (element.textRuns && element.textRuns.textRuns[0].characters == originalText) {
				// changing the textRuns directly while in an
				// onSmartShapeEdited event doesn't seem to update the
				// text element on screen, but using the dom function to
				// set the textRuns of the selected on-screen element
				// to the existing ones in the smart shape does seem to
				// force an update.  we want to change just our text,
				// not that of any other LoremIpsum shapes selected, so
				// set the selection to just the one text element.
			fw.selection = [element];
			this.dom.setTextRuns(this.smartShape.elem.elements[this.k.TextBlockIndex].textRuns);

				// refresh the reference in originalSelection, since
				// calling dom.setTextRuns broke it
			originalSelection[i] = fw.selection[0];

				// we want to update just our own text, not that of any
				// other LoremIpsum shapes with the same text that might
				// be selected, so break
			break;
		}
	}

		// restore the original selection
	fw.selection = originalSelection;
},

You'll note that after calling the shape's redraw() method, I loop through the selected elements looking for the original *unchanged* text. This means the elements on the canvas don't seem to have been updated by this point, even though the text has changed if you look at smartShape.elem.elements. So then I use the dom method to reapply the change, which seems to work.

Is there some wrinkle regarding SmartShapeEdited that I am unaware of?

Yes, it's buggy as hell. :| In his smart shape tutorial, Senocular says the SmartShapeEdited event can't really be used to modify the shape (http://senocular.com...oshapes/?page=4):

Limitation: when an Auto Shape script is called by means of a SmartShapeEdited event, contours within your paths cannot be edited. You can create new path elements and you can modify contour nodes, but you cannot create new contours or add nodes to existing contours. This can be very frustrating if you want to think that you can redraw and fix an Auto Shape within that event as a result of the user deleting nodes or paths. It just isn't going to happen. This is also the reason you haven't seen it been used in any of the prior examples.


I suspect it may actually be possible to add new contours, but only by using the dom methods to edit the selected elements, not by editing the smartShape.elem reference directly.

Bottom line: Expect to have your brain turned inside out if you fall down the SmartShapeEdited rabbit hole.

#3 mitya777

mitya777

    FireStarter

  • Members
  • PipPip
  • 28 posts

Posted 21 March 2011 - 05:38 PM

Hey John, yeah, you're right, it wasn't that they weren't running, it was that the changes just weren't being applied. It's crazy that auto shapes are implemented so poorly, I never know for sure whether problems are occurring because I am doing something wrong or it's a fireworks problem. I'm trudging through this, but I imagine that many people would just get fed up and not deal with it.

I ended up updating in the EndDragControlPoint event. Which is not ideal since I have to wait for a user action to update, but good enough.

#4 jdunning

jdunning

    Fireworks Ninja

  • Members
  • PipPipPipPipPip
  • 173 posts

Posted 21 March 2011 - 07:10 PM

Hey John, yeah, you're right, it wasn't that they weren't running, it was that the changes just weren't being applied. It's crazy that auto shapes are implemented so poorly, I never know for sure whether problems are occurring because I am doing something wrong or it's a fireworks problem. I'm trudging through this, but I imagine that many people would just get fed up and not deal with it.

Yeah, you have to be willing to bang your head against the API until you break through, which is painful. It feels like auto shapes were implemented in a sort of quick and dirty way, and were targeted mainly at making things like spirals and stars. But the more interesting and useful functionality, like updating a shape in response to a user's edit, wasn't really considered. The few shapes I've written feel like they're on the ragged edge of what's possible, and may blow up at any time.

I ended up updating in the EndDragControlPoint event. Which is not ideal since I have to wait for a user action to update, but good enough.

Yeah, I had to do that with the Greeked Text shape. If you have two or more Greeked Text shapes selected and drag a resize control point on one of them, they all get resized by the same amount. But trying to update the contours in all of them completely broke the undo history. So you have to click a control point on the shapes you didn't drag to cause them to update.

#5 TimRocker

TimRocker

    Fireworks Sparkle

  • Members
  • Pip
  • 1 posts

Posted 03 October 2011 - 02:19 AM

Thanks for sharing, i got lots of new script here, and really helpfull for me