Monday, 14 January 2013

So what next?

Looking back at what I said needed fixing before it was midly usable (Aug 2012):

  • create capability to change point size in use on the notes
  • create separate capability to change point size in use on text objects
  • Fix printing logic so it scales appropriately and doesn't do crazy things with landscape mode 
  • Rests - large omission, as most scores have a rest in them!
  • Cut, Copy & Paste
  • Undo
  • Fixing file open so it doesn't pop a new window
  • Fixing the exit without saving logic
  • Toolbar buttons to make entering widgets easier
Seems I thought then that having CCP was more important that Undo. Reading up about Undo it uses a Command pattern, which is roughly what I've used, so hacking that in might not be as painful as CCP. Only measuring pain, as pain usually equals time, and there's only a couple of weeks before the first version goes to proof of concept testers.

Other enhancements I've thought would be useful while using it:

  • make backspace delete the note immediately before it, or if none, reposition cursor immediately after the preceeding note such that another backspace would delete it. Makes it feel more like a word processor when entering notes using the keyboard
  • allow selections to be made in block mode ie, draw a rectangle and select everything in the rectangle, rather than everything between the first note in the rectangle and the last
  • fix where text annotations get positioned after load from file
  • fix such that text annotations always float in front of manuscripts
  • implement a bar line with two thin vertical bars
  • make ties terminate above the note head rather than directly on them
  • fix where the group factor (eg the 3 in a triplet) is drawn within the tie
  • make the tie more of an arc with pointed ends and thicker middle, ie improve the look of it
  • create an option to use parallelograms for note heads rather than ovals (let's call it the Heppy look lol)
  • flams seem to float a long way from the note head, bring them in
  • tails on non-beamed quavers (and smaller) could be better looking, ie more of a swirl to them
  • implement treble clef, bass clef signs
  • use double slashes through the stem of a note to show rolls rather than one slash
  • improve look of semibreve and minim notes
  • improve look of crotchet rest
  • fix drum note widths as sometimes unison overlaps or leaves spaces, especially when zooming
  • make the unison highlighting go all the way to the bottom of a note stem, ie deeper box
  • figure out what to do when it get's crowded above a note, tie, accent flam
  • implement actions to half a notes duration or double it, preserving grace notes and other attributes
  • implement action to align all bar lines to top line, and/or space bar lines equally on a line
  • make some use of the variables captured, ie author, title, band etc
  • implement pictures for band logos etc
  • implement handling of whitespace when reading xml scores in, so they can be formatted to be more human friendly when saved
  • fix the bug in ligature drawing where the cut note, or shorter note extra tail doesn't get rendered when beamed both ways

Squashed the tie bug

A couple of other issues were uncovered and fixed while looking into the tie depth counter not working correctly when saving scores. Turns out on reading the xml in, I wasn't checking for more than one tie on a note, which confused me when I thought I'd corrected the code that saves scores!

So a Collections.sort with a custom comparator did the trick. In the comparator I make sure that we write tie elements that close a tie out before any that start a tie, which in turn keeps the depth counter accurate when we then work through the array.

Code is below, the eagle eyed will spot that I simply say equals when the note is the end of two or more ties, and similarly if it's the start of two ties. Put simply we don't support stacked ties until I fix that!

Collections.sort(tieList, new Comparator() { 
 public int compare(JTie arg0, JTie arg1) {
  // we want to return -1 if arg0 is before arg1
  // before is defined as meaning it's primarily a closure tie for JDrumNote dn
  // ie closes before opens
  if (arg0.isTail(dn)) {
   if (arg1.isTail(dn)) {
    // then this note has multiple ties terminating on it, the tie closest to it
    // is the one we want to process first in the following for loop
    //    so we decrement the group level therein appropriately
    
    // code here
    
   } else {
    // arg1 must be a start tie and therefore is greater in the sort order than arg0
    // so we tell sort arg0 < arg1
    return -1;
   }
  } else {
   // it must be a start tie, so check if the other is a close
   if (arg1.isTail(dn)) {
    // then we want to process this before arg0 so we say arg0 > arg1
    return 1;
   } else {
    // both are start ties, we want to open the furthest tie first so it becomes last to close
    
    // code here to figure out which has the highest y,x co-ords
    
   }
  }
  
  // then if they are both closes, we return -1 if arg0 is before arg1 in y,x co-ord terms
  
  // there can be no arg0==arg1 in the sort unless there are two identical ties starting 
  // or ending on this note - user could do that if they really really wanted!
  return 0;
 }

});

Sunday, 13 January 2013

Going for it, oops - nasty bug

Having completed the artwork and refactoring of the code for rests, it was time to force the issue, so went public on facebook with DrumScore, looking for friendly fire feedback for the first iteration.

There's so many different things I could work on next I really want the opinion of those who might use it as to what's most important to work on.

Then I find nasty bug. Nasty because it impact the ability to load a saved score back in, and worse still the issue is in the way the score was saved, so it's not a case of just fixing load code.

Turns out the way that ties are implemented, ie a list of JTie objects on each note that is at the head or tail of a tie works really well to support moving the tie end with the note, the primary objective, but when I come to iterate the list on each note, the list of JTie's order is indeterminate. This means my implementation of a depth counter for ties in the XML that represents the saved notes doesn't work.

In order for it to work, if a note is at the end of one tie, and is at the start of another, we would have to process the JTie which represents the close of the first tie, and thus decrementing the depth counter, before processing the JTie which represents the start of the second tie, and thus increments the counter.

In short, we risk bumping up the counter before down, meaning instead of closing tie 1 in the xml we start tie 2, and then process the close which is stored as closing tie 2, as that's where the counter was at.

Going to need to sort the JTie list with a custom comparator before storing it. More to come on this!