0
votes

This question relates to strategy rather than specific code. I'm struggling to think of a viable approach and I'm hoping somebody may have encountered a similar challenge.

I'm building an Animate program that will:

  1. Enable the user to draw a line on the stage (by means of a series of mouse clicks).

  2. Capture the coordinates of each mouse click in an array, and add them to a table that is displayed and updated in the UI.

  3. Display the resulting line.

  4. Enable the user to edit any of the coordinates, and update all of (1) (2) and (3) accordingly.

The first three steps are working OK, but darn ... how should I make that data editable? I've put a listener on the textfield that holds the set of coordinates, but I think that's a dead end. It's just a string with line breaks, so it would be hard to edit a particular few characters and have AS3 / Animate detect what had changed.

Is there a good technique for this?

Background: was comfortable with AS1, skipped AS2 completely, and now (12 years later), I'm grappling with AS3. It's been frustrating, but ... I've built a package and it's working.

1

1 Answers

0
votes

The most important concept you need is the Model-View-Controller design pattern.

model

Start with defining your model which represents the data in your application. Do so according to your requirements. The minimum requirement for an object to work as the model is that it notifies others when it got changed, because MVC is based heavily on the observer pattern and you want to observe when your data changes. In As3, using the built in EventDispatcher makes sense.

In your case, a nested model makes sense, that is, you have a model for each individual point and then another model that acts as a collection of all points.

Add methods to your model classes to modify the data. You want to add and remove points to the collection of points and you want to modify the coordinates of each individual point.

view

Each view receives a reference to the model object that represents the collection of points. One view might draw them into a coordinate system and connect them with lines, another might be a tabular representation.

controller

The controller knows about the model and reacts to user input on the view. For example, when somebody clicks on the view, a new point is inserted.

Given the simplicity of your application, it might makes sense to combine view and controller, so that each view directly manipulates the model.

how should I make that data editable?

By creating methods on the model that allow you to do exactly that.

Say for example the LineView class receives the PointListModel which includes all points and stores it in a private variable

public LineView (pointList:PointListModel)
{
    list = pointList;

Now it will create graphical assets to represent the points, based on the list (this should be executed whenever the PointListModel object signals a change:

private onListChanged(event:Event):void
{
    for each(var point:PointModel in list)
    {
        // draw circle or whatever

As the creation of each visual asset in the view is based on the model, it should be possible to connect them. When the user now modifies the visual asset, the made modifications can be applied to the PointModel object. Remember: any modifications made to a model will cause it to dispatch an event that it was modified. This will inform all other views that this point was modified.

This is how dragging & dropping the circle representing a point in one view will make the coordinates of that point displayed in another view update as if they are linked together, because they are: via the shared model object.

I am still a bit hazy about how I would associate the displayed table with underlying array data. Should I make each row of the table a separate textfield with an associated listener?

This is up to you.

  • You could make the entire table only listen to the change event of the model that represents all points. This would cause the entire table to be updated.

  • Or you could make the table observe the point list model to add or remove table entries and each entry in the table observe a point in that list. This allows you to only update a single entry in the table if only one point got updated.

Keep in mind that the components of flash do a lot of this for you. Flex has even more sophisticated components. The way each entry is rendered can be defined with a custom itemrenderer.