Skip to main content
Participating Frequently
March 10, 2009
Question

can i create custom flowelement?

  • March 10, 2009
  • 6 replies
  • 2336 views
hi development team,
I want to create a custom FlowElement which renderers table. But I'm not sure how should I start.

Can you give me some ideas?
This topic has been closed for replies.

6 replies

NakoRuruAuthor
Participating Frequently
March 26, 2009
Now I use a single inlinegraphicelement representing a table, and the source is a sprite used for rendering, each cell is another sprites, depengding on how many cells there are.

After I put all the cell sprites into the table sprite, I should use setCompositionSize() of IContainerControler inside a table cell. But if double click the cell, I will get following errors.

Error: Error #2160: The TextLine is INVALID and cannot be used to access the current state of the TextBlock.
at flash.text.engine::TextBlock/findNextWordBoundary()
at flashx.textLayout.elements::ParagraphElement/findNextWordBoundary()
at flashx.textLayout.edit::SelectionManager/mouseDoubleClickHandler()
at flashx.textLayout.container::ContainerControllerBase/processMouseDoubleClickEvent()
at flashx.textLayout.container::ContainerControllerBase/ http://ns.adobe.com/textLayout/internal/2008::mouseDoubleClickHandler()

If I remove setCompositionSize(), everything works fine except that I cannot calculate the exact width and height of the table.

I googled why it happens, and I found others met same problem with that I met. see http://bugs.adobe.com/jira/browse/SDK-17186.


Beside,

outside the table, I should listen the sprite size(an event that define by myself), in oder to update the width and height of the table inlinegraphicelement, however, I got another error

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at flashx.textLayout.edit::SelectionManager$/computeSelectionIndexInContainer()
at flashx.textLayout.edit::SelectionManager$/ http://ns.adobe.com/textLayout/internal/2008::computeSelectionIndex()
at flashx.textLayout.edit::SelectionManager/selectionPoint()
at flashx.textLayout.edit::SelectionManager/setNewSelectionPoint()
at flashx.textLayout.edit::SelectionManager/mouseMoveHandler()
at flashx.textLayout.container::ContainerControllerBase/processMouseMoveEvent()
at flashx.textLayout.container::ContainerControllerBase/ http://ns.adobe.com/textLayout/internal/2008::stageMouseMoveHandler()


March 26, 2009
One idea that crossed my mind on the errors is that if you have container controllers connected to display object containers that are nested in the display lists of the container for the 'main' text flow that has table cells in it, the mouse events might be bubbling up from the cell containers and are being handled also by the parent controller. Obviously that would cause an issue if the parent container controller attempts to look up the corresponding TextFlowLines, etc. I can't remember exactly what I had to do to work around this, but you may have to explicitly prevent some events from propagating up. Easiest way to do that (and debug the errors) if you haven't already is to extend DisplayObjectContainerController and override all of the protected process*Event methods and set breakpoints, inspect event targets, etc. And I'm not 100% sure that the errors you're seeing are related to rogue events, but it's something to look at...

Richard is right about all of the things that you will have to do if you want to add truly custom elements. It all really starts with the import/export handling. With the id and stylename properties on flow elements, which are easy to modify with the operation classes for those, you can tie objects or data into the text flow pretty easily. Then you can pre process the text flow (or a copy of it) or do reg-ex or similar post-process of XML output. E4X simplifies things a lot. If you want to do a lot of custom things, having control over what you can put in the markup is definitely key.

Once you get past import/export (and the events issues), you still have to deal with all the extra things you would have to keep an eye out for as operations are performed like copy/paste, etc. As far as intercepting clipboard stuff, you can either do it in the container controller by overriding appropriate methods, or you could extend EditManager. Then override doOperation and check for example if operation is PasteEvent or one that you need to do extra stuff with. Then you can create some of your own Operation descendents, call beginCompositeOperation(), then super.doOperation(op), then super.doOperation(extraOps), then endCompositeOperation(). By doing that way it will end up being one undo step. Anyway, that's just one example of the types of things you'll have to get into if you are doing custom objects and import/export handling, etc.

I was headed down the same path of wanting to create my own flow elements at one point, and I hit much of the same roadblocks that you guys are running into now. Six months later, I've discovered that although I can't create my own types flow elements, TLF provides a rock foundation for building on. Once you really understand how it all fits together, it's not so difficult to integrate with. Doing so does require a fairly substantial commitment up front, but the end results are well worth it.

Good luck!

--Brent
Adobe Employee
March 26, 2009
Non-final classes is out of scope. There are a slew of difficult issues to figure out - how the editor will work - how cut/copy/paste will work and how import/export will work, exactly how to define a custom element and how to get it to have custom behavior and how to support those behaviors. It's a long list of things to do.

The more information you can give about why you need custom elements and how they should behave the better. We do have intermediate classes that are non-final although as you can tell they are not well documented and it is non-obvious how to make use of them.

We do support setStyle/getStyle of user defined styles on any element. Combine that with the composition events and the ability to write operations and you should be able to make some progress.

Sorry I don't have better news on this.

Regards,
Richard
NakoRuruAuthor
Participating Frequently
March 22, 2009
can you developement team make such final classes non-final?
If I want to customize my own elements, I have to do a lot things outside tableelement, which violates OO and is hard for me to maintain the code.

btw, I think you approach cannot handle multi-row or multi-column cells.

thanks,
March 23, 2009
yeah, make it non-final will be good. also an example of how to write custom flowelement will be very helpful
Adobe Employee
March 12, 2009
I was thinking about measuring the entire content of the container. Measuinng the paragraph would require accessing the lines from the flowComposer and summing the sizes of the lines from the specific paragraph.
Adobe Employee
March 11, 2009
This approach in general sounds good.

I don't think you should have to copy the text into another TextFlow. Why not ask the cell sprite's controllers what their calculated size is? The composePosition API can be used to force all text to compose.

Richard
March 12, 2009
thanks for quick reply. The fact i need to copy to another flow is because if the container size can not fit the text (main flow) , the text will flow to next cell. Maybe i can apply your idea to have each cell individual flow for measurement then compose mainflow after adjustment.
the problem is when i mix text + table together. how can you measure para with ENTER chars inside ?

Thanks
Adobe Employee
March 10, 2009
The creatable FlowElements are all marked final at this time. TLF does support user defined styles on any FlowElement.

Its going to take a fair amount of work to make a first class tables representation. Internally we've talked about tables quite a bit and have done some prototyping but don't have anything for you at this time.

I think you could do something interesting with the current APIs like this:

Make a DivElement that represents the table.
Make each paragraph the equivalent of a row.
Each paragraph has an InlineGraphicElement per column.
Set the graphic in each InlineGraphicElement to a Sprite managed by a DisplayObjectContainerController that has a TextFlow with just the cell's content.
On each cell TextFlow listen for compositionComplete events and then update the graphic size to the contentWidth/contentHeight and make other adjustments as necessary. Then recompose the outer TextFlow.

As noted this hasn't been tried. I believe the necessary APIs are public for this approach and you could get something reasonable to work. It would also have some limitations. I'm sure there will be challenging problems along the way.

Good luck if you try this - it'd be interesting to know how it works out. Please post any questions - we'll try to help.

Best Regards,
Richard
March 11, 2009
i have created a table by combining many sprites as DisplayObjectContainer. Each sprite size is calculated and readjusted but this has performance issue. to calculate size i added the text which is a para to another textflow (for measurement) and calculate bounds of this para. It gives somewhat near to precise result. I wonder if there is any way to measure para height/length easily and less overhead ?
My method has some problem when i need to recalculate table starting point if text outside above is updated. Seems when i hit ENTER returned calculated size is not correct.

Do you any idea ?
Thanks