Lomse library. API documentation
0.30.0
|
When a source document (in LDP or MusicXML format) is loaded, it is not stored as text or as an XML Document Object Model (DOM). Instead, the document is parsed and an Internal Model is built. The Internal Model is, mainly, a tree structure in memory. The root element of the Internal Model tree represents the whole document. And the children of the root element represent the basic blocks for building a document: headers, paragraphs, music scores, lists, etc. For an overview of the Internal Model see The Document API.
Once the Internal Model is created, for modifying the document your application has two options, either
Edition commands are a high level API for supporting edition. It is based on executing commands and provides undo/redo (that is, reverting the last change done to the document and to reverting the undo by re-executing the undone command). It is appropriate for applications whising to provide an interface to the user for editing documents (e.g. a music score notation editor application).
Direct internal model manipulation is a low level API. Your application directly accesses the Internal Model and modifies the internal Internal Model structures. Obviously, there are no high level related services such as undo/redo and good knowledge of the internal model and related structures is needed for maintainin consistency. This API, faster and more flexible, is appropriate for applications that programatically create and modify documents (e.g. an application for creating random music scores).
Of course, both APIs are compatible and can be used by your application for offering different services.
The rest of this page describes the high level API using edition commands. For a description of the low level API see The Document API.
All edition commands are objects derived from base abstract class DocCommand, and they work by modifying the Internal Model tree, either by inserting or removing elements or by modifying the attributes of an element. For instance, CmdInsertBlockLevelObj() is a command for inserting a block level object. This command, as well as most commands for inserting new elements, require a parameter with the source code of the element to insert. Currently the source code for all edition commands must be in LMD format.
Executing a command is just invoking Interactor::exec_command() method and passing the command to execute, for instance:
Undo/redo operations refer, respectively, to reverting the last change done to the document and to reverting the undo by re-executing the undone command.
Lomse provides full support for implementing undo/redo in your application. It maintains two queues: the history of executed commands and the list of commands that can be re-done. And Lomse provides two methods for undo/redo operations:
In addition, to facilitate that your application can enable and disable undo/redo buttons, commands and other GUI widgets related to undo/redo, Lomse provides information about the undo and redo history:
Most edition commands require a reference point in the document. For instance, a command such as delete paragraph would require a pointer to the paragraph to delete. Or a command insert note would require a pointer to the point in which the note must be inserted. For providing these references, Lomse maintains two objects: a DocCursor object and a SelectionSet object.
The DocCursor object is just a pointer to an element in the document. You can think of it as the graphic cursor in text edition applications, but in Lomse, there are two objects: the DocCursor and the Caret.
The cursor is just an internal invisible pointer; and the caret is the graphical representation of the cursor position. Lomse maintains the synchronization between the cursor and the caret, so advancing the cursor automatically forces Lomse to render the caret on the new cursor position. The cursor is always necessary, as it provides a reference point for edition commands. But the caret is just a graphical widget that your application can use or not, depending of the needs. For instance, in a batch application it would be non-sense to use a Caret! For moving the cursor to another position your application just issue specific edition commands, such as advance cursor or move cursor to start of score.
Your application can also issue edition commands for selecting and deselecting document elements, such as paragraphs, words, notes, rests, clefs, staves, etc. Object SelectionSet is just the collection of current selected elements.
The DocCursor and the SelectionSet are not parameters of the commands. These objects are maintained by Lomse and when a command is going to be executed the necessary information about target objects and context is extracted from current cursor position and/or from current set of selected objects.
And this is, basically, the document edition API. It is very simple and gives full freedom to your application for implementing the edition GUI as you'd like, or for not a having it at all!
What should be the behavior when inserting or deleting a note? For people with no previous experience with music edition software, the most intuitive behavior is one similar to what is expected from someone who comes from a pencil-and-paper background or from using a text processor: inserting/deleting a note or a rest shifts all the music that comes after it. But what about barlines? Should they be also shifted or should they remain at the same place? Each alternative has advantages and drawbacks:
To avoid problems, another possibility is to change the behavior when a note or rest is inserted or deleted. In most cases you don't need to shift music. What you need is to add notes and rests in empty measures, but in measures having content what you need is to change a few notes or rests, but always keeping measures duration and not shifting the music. Let's call this behavior replace mode (the notes are replaced and measure duration is preserved).
None of these behaviors is perfect. What should be Lomse behavior? Although the most usual behavior in music edition programs is the replace mode, the other modes can be useful in some scenarios or for some applications. As Lomse aims at not creating unnecessary constrains to your application, it was decided to support the three behaviors. For this, all edition commands related to adding or removing notes and rests require an edition mode parameter for selecting the desired behavior:
For supporting full ripple mode, instead of adding more complexity to commands related to adding or removing notes and rests, it is simpler, more flexible and causes less trouble to end users to use two specific insert/delete commands that always work in full ripple mode:
These commands accepts a parameter defining the scope: to affect only one or selected voices, one or selected staves, one or selected instruments or the whole score.
This section presents a list of available commands (but more commands need to be programmed and a couple could be removed). For more information on each command read the class documentation for the command.
Document edition commands:
Selection commands:
Cursor commands: