Saturday, 30 January 2010

Implementing the model

The model contains Collections of adornments and staff lines.

The adornments are the textual elements the author may wish to put in the score. Going to start with saying they can go anywhere on the page for now. In the next revision, I'd look to have a header collection and a footer collection which repeats on each page. At the moment, by implication we're talking about a single page being all that's supported.
Each staff line object contains two further collections, one for bar elements, such as the various different bar separators (single line, repeat bar mark, time signature, curly thing that means treble or the bass one!), and a second collection for the note elements that go on it.
That's what's decided for now. The critical piece now is how to store representations of unison markings / groupings, and regular and irregular groupings of note, e.g. a triplet.

Initial thought is somehow tagging the start and end note of a group, ie a group object with a reference to the start and end notes, and would the notes themselves somehow need to know they delimit a group? Would need to be outside the staff line concept as groups can cross bars and lines on a page. Going to park this and think it through.

So back to the collection of adornments. This is implemented as an ArrayList, as it allows positional access, i.e. by element number x, and you can iterate backwards and forwards. The thinking here is at some point we're going to need to understand which graphical widget resides at a particular screen location (e.g. when user clicks the mouse there). While managing the contents of this list we keep the order as being leftmost and highest object on the page at the beginning of the array, and the lowest and rightmost at the end of the array, and all those in between in descending order (visually).

The exception to this is element 0 in the ArrayList is always the object containing the score title. This is required for other uses in the program so we need to be able to reference it at any time, including when we've loaded the model from a file, we can easily extract the title for the rest of the programme.

Why store it in the list? My thoughts were for ease of scanning the page for graphical objects. The option would be when performing the scan (which I'm yet to confirm I need to do!), to check the title object, scan the adornments and scan the staff lines. Could easily be persuaded to abandon this approach and store it separately as it won't change much once set, and so could be a separately searchable object, and check for it last.

To layer or not?
Also toying with the idea of layers on the page, e.g. layer 1 is the adornments, layer 2 is the staff lines and bars etc, and layer 3 the notes. Concept is you select the layer you are editing, optionally hiding the clutter of the other layers contents. Leaving the "clutter" visible but dimmed may help if you are e.g. moving bar lines about. It's a level of complexity to implement but also a level of complexity for the regular user who may just expect to click on an object and manage it, not having to worry about which layer is showing.

Simple is best in my humble opinion, so we'll start with a single layer. It's going to be hard enough managing viewports and scrollable regions, zoom etc, without another level initially. Should be able to fit in a later version if it's really wanted.

Graphical Objects
An abstract class called ContentBase is now implemented. It contains the data common to all graphical objects which get stored in the model, including the get/set methods.

On top of this we have ScoreText, which is the implementation for any textual adornment, and ScoreStaff, as the object which stores bars and notes on a particular line.

So at the time of writing we have a working application, with a basic model and view, minus the code to actually paint any of the graphical widgets in the app yet ;-) writing that now!

Off to do some adornment implementing and muse over the grouping conundrum.

No comments:

Post a comment