mpogue2 / SquareDesk

Fully-featured music player and sequence designer, designed for square dance callers
10 stars 4 forks source link

Epic: Simple Sequence Designer using SD + File/Clipboard Import from CSDS Online or Taminations #752

Open mpogue2 opened 1 year ago

mpogue2 commented 1 year ago

I need a sequence playback thing of SOME kind, since I'm calling C1 for the first time in August. I've evaluated CSDS, CSDS Online, Callerama, Taminations, and SD. I won't repeat all of that analysis here, but my conclusion is that the best approach is probably hybrid: "Design: use CSDS Online or Taminations or SquareDesk's internal SD; Playback (while calling a C1 dance): use SquareDesk's SD".

I do like the "resolver" in CSDS Online (https://www.ceder.net/ws/) a LOT. But, the UI is very weak for designing (especially if you make a typo mistake), and it's really unusable for playback (during a dance). CSDS seems really good for playback, but it's Windows X86 only (and it's $200).

I think it's possible to make a minimally usable Design/Playback tab, using SD. This ticket describes some thoughts about what I think I need for August C1 calling:

Design in CSDS Online, Convert CSDS sequences to SD, use SD sequences or converted CSDS sequences: PROS: Nice resolution in CSDS Online Can still design in SquareDesk/SD SquareDesk has better music support CONS: have to write code:

                - NEW FEATURES IN SD TAB (or a new tab?):
                    - Fixed list of Frames to start (Unknown, Easy, Medium, Hard, Asymmetric, Used, etc)
                        - standard list created at startup in SD folder
                        - user can make more folders, if desired, and can move using Finder
                    - Save current sequence to Frame (folder)
                    - Import CSDS sequence (and convert to SD format) to Frame (NOTE: Export not needed now)
                    - Import SD sequence from text file to Frame
                    - Export SD sequence to text file (much better than "Save As HTML")
                    - Select frame (Keys: 1,2,3,4,5 = assigned to frames in Preferences, or maybe just alphabetical?
                            should these just be tabs, auto populated from the SD folder?)
                    - forward/back within frame (Keys: LEFT/RIGHT)
                    - USED key (move current to Used frame, Key: U, or should this just set a flag that this was used?
                        or maybe just add a file "Sequence.1.meta" containing "USED")
                    - REMOVE key (remove current sequence from current frame, Key: R, or just set a flag?)
                        (should flags be in the file system, or in the SQLite DB?)
                    - first sequence of frame (or "last viewed sequence in frame"?) is auto-loaded into SD
                    - first call is highlighted in the sequence
                    - scrub with UP/DOWN arrows in Current Sequence pane, changes the picture as keys are pressed
                    - TIME IN TIP needs to be somewhere on the page, maybe CLOCK, too?
                    - Mini playback controls (Keys: Stop, Play/Pause)?
                    - for Playback mode, we can lose the "Options, ? Completion, and Additional" tabs (replace with frame controls)
                        also the SD Output tab can go
                        also the little pictures in the Current Sequence tab can go, and the height of the rows reduced to be able
                            to see more calls at one time
                    - Right Click Menu in Current Sequence tab > Problem HERE
                    - Difficulty level can be selected, and that will mark USED AND will move to the other folder
                    - CANONICAL FORMAT FOR ALL SEQUENCES, AND PUBLISH THIS?
                        Canonical: BOYS Swing Thru while the GIRLS Trade
                        SD: BOYS (while the others) <NL> Swing Thru <NL> Trade
                        CSDS Online: Boys Swing Thru Girls Partner Trade
                        Taminations: BOYS Swing Thru while the GIRLS Trade
                    - MUST be able to assign names to each dancer, in place of numbers
                    - Zebra stripe the current sequence (perhaps every 3)

UPDATE

Here's what's implemented from the above list, as of 2023/03/12:

mpogue2 commented 1 year ago

Commit 5dfa9ba0be4e844818287d595386dab89da01a36: I think I've figured out a better model for editing and playback, after prototyping some UX alternatives. It's different from the "Sequence Designer vs Dance Arranger" model that I have in there now. Instead, it's a lot more like the "Lyrics Editor vs Lyrics Viewer" model that we have for cuesheets. That is, initially we can VIEW a sequence. Clicking on EDIT/UNLOCK allows us to edit that sequence, and also MOVE/COPY TO , which then takes us back to VIEW mode.

If this works out, I'll get rid of the Sequence Designer/Dance Arranger distinction, and there will be only a single SD window that looks like the current Dance Arranger. Bouncing back and forth between them will now be done within the Dance Arranger, just by entering and exiting EDIT mode. The Menu options will still be there, to allow viewing/hiding various of the UX widgets.

It's slightly different from Lyrics in this way:

That does suggest that we should extend the Lyrics model to include a NEW button as well. It does feel pretty natural to me when making New Sequences to click on NEW in the Current Sequence pane (which is loaded with one of the frames), so it's probably useful to make New Cuesheets (perhaps with a context menu with a couple of options: Single column, and Double Column).

Example of editing a new C1 sequence:

Current initial view, showing NEW and UNLOCK buttons:

image

Current editing view after UNLOCK was clicked, showing SAVE... button:

image

and SAVE options:

image

mpogue2 commented 1 year ago

Commit c17733d588c1d31c04cfd817808da1ae8d836591 turns off some debug input, in case anybody is using this code in the field. Debug input causes writes to debug.log, which sometimes slows things down a bit, so the default is "commented out" for all qDebug() statements.

mpogue2 commented 1 year ago

TODO: Allow typing in an AUTHOR into preferences, so that #AUTHOR=# will be correct. TODO: Need a big incrementing number for "#REC=#". These are used when creating "dances" in CSDS -- do we really need this in the MLP? Or, maybe these should be 64-bit GUIDs? Or maybe they should have content inside, like concat(current datetime, hash(time)) or similar. They need to be globally unique, for sure, but do they need to be decodable for something? Maybe also make sure that no low numbers (used by CSDS) are possible, to avoid collision with CSDS. TODO: implementations for Move, Copy. TODO: CRUD Alert: need to figure out where in the UX to do DELETE (ALL AVAILABLE NOW: df410c52debc5670c6f59b4d60f6fa54515b15bf)

  • Create => NEW button
  • Read => normal viewing
  • Update => UNLOCK/SAVE.
  • Delete => DELETE
mpogue2 commented 1 year ago

Here's a screenshot of 2019 CSDS:

image

I do like the |< and >| buttons to go to the beginning or end of a frame. Could also use SHIFT-F11 and SHIFT-F12 for those functions. Probably need a right-click context menu to make these discoverable, or something in the main SD menu (or both).

mpogue2 commented 1 year ago

BUG: Single letter key shortcuts, like "L" are broken right now. Cmd-L works I think, but L does not. (FIXED: 21234e2d84b3a92914f6587a3ccd607a2db6f47a)

FEATURE: keyboard shortcut to swap HEADS and SIDES everywhere in the sequence (useful for those sequences where HEAD/SIDE are used in other than the first line. CSDS seems to discourage using such sequences, but I can see where something like this might come in handy.

TODO: Need a way to create a new frame (e.g. "local.ssd.easy" etc). Not sure if we need this right now, though, since just creating a file in the sd directory will create that new frame (once we've implemented scanning the sd directory for frames -- this is not there YET).

mpogue2 commented 1 year ago

FEATURE: We need a "Revert Edits" for sequences. FEATURE: When a sequence has been modified, there should be a somewhere in the frame description line. Perhaps: F6 local.plus [1/2], and that * should go away only when the Save is done (not when Move or Copy are done).

mpogue2 commented 1 year ago

Commit: df410c52debc5670c6f59b4d60f6fa54515b15bf

Now working:

  • Save current sequence to current frame (Replace)
  • Delete current sequence from current frame (Delete)
  • Move current sequence to a different frame (Move)
  • Copy current sequence to a different frame (Append)

NOTE: If you copy or move or save a C1 sequence to a Plus frame, it will do it, but the resulting sequence will NOT be loadable into the new frame. Also, many CEDER sequences are not loadable into any SD frame (this requires the translation code that is designed, but isn't written yet).

What is safe to do right now is creating an SD frame, save/copy/moving it to another SD frame (of the same or higher level).

NOTE: While care is taken to atomically modify files, there are no backups for any of the sequence files. Caveat user.

mpogue2 commented 1 year ago

Commit: 71c24519f19a5e66810da99aa0ab0465fa576ec8

SHIFT-F11 goes to sequence 1 in the current frame. SHIFT-F12 goes to the last sequence in the current frame.

FEATURE: It really feels to me like LEFT/RIGHT ARROWs should work the same as F11/F12. But, does that conflict with them being used for volume right now?

mpogue2 commented 1 year ago

commit: 094bc6f59132228caf2d8d713b3d1cbad0fbd174

As the user presses F11/F12 to move around within a frame, we keep track of that internally for displaying the frame (either in the sidebar, or in the Current Sequence pane). This commit persists that value at quit() time, so the next time the user comes in, the frameCurSeq values are remembered. If the persist file doesn't exist, it is created, with an initial value of 1 for all files.

The Current Sequence values for each frame are remembered in /sd/.current.csv, which is an invisible file (at least to Mac users). It's done this way, because the frameCurSeq values go with the musicDir, and are not separate for each laptop the user may have. File services like Dropbox, Box.net, and iCloud will sync the music directory, and in the process, will retain the frameCurSeq values across all synchronized devices.

mpogue2 commented 1 year ago

Commit: 71119993e6aa2224b659d01963e4c05332833c50

If we do a Load Sequence from File, Paste Sequence (context menu), F11/12 to move between sequences within a frame, or F1-F10 to switch frames, we should select and highlight the first item in the tableWidgetCurrentSequence, and display the ending position. Then, UP/DOWN ARROWS will work as expected within that sequence.

This was a tough one. It turns out that in order for the first row to be selected and highlighted (and not crash), AND for the up/down keys to work, there needs to be:

  1. a valid item in there, that has the info we need to display the dancer positions
  2. that item needs to be the Current Item (via setCurrentItem)
  3. that item needs to also be selected (via setSelected).

BUT, we actually don't know when the load is complete, because SD executes in a separate thread asynchronously AND there's nothing in the SD output that tells us that it's done.

So, for 1 above, I always check to make sure the item(r,c) pointer is valid before trying to do anything with it, AND I wait 100ms after the last line is received by us from SD, before I try to set the selection, AND I only set the selection once. For 2 above, I now explicitly set the current item (which I wasn't doing before). For 3 above, I was doing that before already.

In my testing, it seems stable now. No crashes, and the 100ms delay for the selection is not noticeable. And, no UP/DOWN keys are seemingly lost, because the tableWidget was in a weird state where an item was selected but was not the current item (who knew??).

mpogue2 commented 1 year ago

Commit: c47464862508810f4867273e5781ae1d82e47b6e

If on the SD page, Left/Right Arrows will go to Previous/Next sequence in the current frame, as you might have expected (it's natural to navigate this way, because the arrow keys are toward the bottom of the keyboard and placed in an easy-to-get-to pattern, while F11/12 are near the top and are often hard to distinguish from other keys up there).

NOTE: If you have the default keyboard hot keys setup, Left/Right are default assigned to moving around within a song. In that case, there are two alternatives:

  1. clear out those shortcuts in the HotKeys tab in preferences, or
  2. instead use Cmd-LEFT and Cmd_RIGHT which work even when the shortcuts are set to LEFT and RIGHT arrows.
mpogue2 commented 1 year ago

Commit: 2d215d484dc65b93fb83454107b8bb200487e273

We're going out of Edit Mode, so highlight the first item again. This is basically the Replace code.

mpogue2 commented 1 year ago

Notes on #REC=# (CSDS internally calls it RecordId):

  • It's a 32-bit int, but it's used only unsigned. So, it's really 31 bit, max = 2,147,483,647.
  • The max REC that I can see from CSDS is 10841. So, CSDS is currently using way less than 5 decimal digits.
  • REC field within SquareDesk MUST give unique ID's to all sequences for a given user.
  • REC's MUST be chosen to be "very likely unique" across all SquareDesk users, just so that when sequences are shared, they will probably not conflict with each other. So, GLUID's (Globally Likely Unique IDs). There are very few users of SquareDesk right now, so that's another reason why any random IDs we choose are very likely to be unique.
  • GLUIDs MUST be sequential for any given user (when NEW is clicked), to make it easy to avoid conflicts.
  • GLUIDs MUST be decimal numbers (i.e. not a hex number, that would likely not be compatible with CSDS).
  • GLUIDs SHOULD be human readable.

Therefore, I think the best plan for GLUIDs in SquareDesk for use in the REC field is:

  • use 31-bit decimal numbers, like CSDS
  • The lowest 5 decimal digits [0-99999] will be the sequence number on a given machine. This number will start at 1 on any given machine, and will be incremented for each NEW sequence created. NOTE: 99999 is about 10X more space than is currently being used in CSDS.
  • The highest 5 decimal digits will be chosen randomly from the range [1, 21473] (NOTE: 0 is reserved for CSDS compatibility, and 21474 is not used because it can't go up to 99999 in the low decimal places) It will be chosen once at app startup. This userID number will be stuck into a CSV file called "metadata.txt" in the .squaredesk folder within the musicDir.
  • That file will have a header: "key, value". The userID key will be "userID", and the value will be the decimal userID number [1,21473]. We can add other key value pairs in the future, that we want to be common across machines for a given user (which is not the case with Preferences!). Keys MUST be [a-zA-Z0-9]+, that is, alphanumeric with no spaces or tabs (this makes for easier parsing). Keys and value are case-sensitive.
  • This makes the userid the same on all machines that are kept synchronized with Dropbox, Box.net, iCloud, etc. The user can go to ANY sync'ed machine, and can make new sequences, and they will all be stamped with that REC_high_order GLUID for that user.
  • Because there are 21473 possibilities, it is very unlikely that any 2 SquareDesk users will have the same ID. Therefore the GLUIDs are "unique enough".

Examples of GLUID for a sequence: "7493600012" => userID: 74936, sequenceID: 12

Example of .squaredesk/metadata.txt file:

key,value
userID,74936
mpogue2 commented 1 year ago

Commit: 3c7cfbbeca92075264b3b5b6666ee5a82d5521f1

  • REC contains a userID in the top 5 decimal digits, and a SequenceID in the lower 5 digits.
  • The SequenceID is incremented whenever the sequence is created or altered.
  • The AUTHOR field contains the userID (same as used in the REC) -- this will be changed to a real author string at a later date (perhaps the Author name gets stuck into the metadata.txt file as a key, value pair?)
  • The userID and nextSequenceID are both stored in the .squaredesk/metadata.txt file (oh, I wanted that to be .csv, renamed it in 9529a50be77d3c33485d833d42eb4ec332ecb9bc)

A sequence now looks like this:

@
#REC=1658300004#
#AUTHOR=16583#
HEADS Square Thru 2
Swing Thru
BOYS Run
Ferris Wheel
CENTERS Square Thru 3

where 16583 is my userID (randomly assigned the first time the app was run), and 00004 is the sequenceID.

NOTES:

  • a choreo file always starts and ends with lines containing just "@"
  • a sequence therefore always starts with a "@" and does not include the immediately following "@"
mpogue2 commented 1 year ago

QUESTION:

  • So, when I click NEW, it makes a new sequence, say REC=3, which is saved to the frame file with REC=3.
  • Then when I save it, the REC is replaced with REC=4, which is the next available sequence ID. Because all replaces create new versions.

Should it actually do the REC=3 save at all right after NEW?
Maybe it should wait until the user does SAVE SEQUENCE, and then save it with REC=3. This would use up fewer sequence numbers, for the typical case of NEW + EDIT + SAVE.

PROS for saving as REC=3 then REC=4:

  • If I do NEW, then Quit(), I will startup with seeing a blank one next time. If I don't save the REC=3 version, then we'll be looking at REC=2 when we come back.

CONS:

  • Typical case (NEW + EDIT + SAVE) uses up more sequence numbers. (Of course, if we go beyond 99999 edits, we're go ing into a region with a new second userID, which is unexpected. BUT, will anybody really ever make 100000 edits? And, even that new userID is STILL not likely to conflict with anybody else. So, the AUTHOR (once implemented) will be the same, but this author will have more than one userID -- is that terrible, given that it's very very unlikely?

UPDATE: For now, I'm not going to do this, because changing this would mean that we have to distinguish NEW sequences (unsaved) from LOADED sequences (saved), and I'm not ready to implement that yet (I don't think it's straightforward). So for now, this is a FUTURE thing.

mpogue2 commented 1 year ago

Notes on cut/pasting (for the purposes of translation between SD, CSDS Online, and Taminations):

  • CSDS Online supports COPY TO CLIPBOARD.
  • CSDS Online does not support PASTE FROM CLIPBOARD.
  • Taminations supports COPY TO CLIPBOARD.
  • Taminations supports PASTE FROM CLIPBOARD (with comments in parens as long as by themselves on a line).

Therefore, IMPORTING TO SQUAREDESK:

  • From Clipboard: should accept all of {SD, CSDS ONLINE, and TAMINATIONS} formats, translating to SD format internally. So, we accept anything, but internally we use SD FORMAT (because our engine is SD).
  • From File: should accept CSDS format, translating to SD format internally.

And, EXPORTING FROM SQUAREDESK:

  • When copying to clipboard, we should use TAMINATIONS format, because this format is accepted by both SquareDesk and Taminations, and CSDS ONLINE doesn't matter (because it doesn't accept paste from clipboard).
  • When exporting to a file, we should always use CSDS format, because that is consistent with the import. Modifying a frame of CSDS sequences will result in a file that can (in theory) be reimported into CSDS (non-online version).

If we do the above, here are the use cases (P0 = priority 0, P1 = priority 1, etc.):

  • P0 WORKS: Import CSDS files into SDesk. CSDS provides the largest body of square dance sequences available.
  • P0 WORKS: Copy to clipboard from CSDS Online, and paste from clipboard into SDesk.
  • P0 WORKS: Copy from SDesk to clipboard, paste into a file, copy from file, and paste back to SDesk. (Copy/paste from/to SDesk should round-trip without error).
  • P1 WORKS: Copy to clipboard from Taminations, paste from clipboard into SDesk.
  • P2 WORKS: copy from SDesk to clipboard, and paste into Taminations. (Paste to Taminations is lower priority than Paste FROM Taminations).
  • P2 WORKS: Modify CSDS file using SDesk, and pass file back to CSDS (non-online) user.

Given those priorities, the order of implementation should probably be:

  1. Import from CSDS files into SDesk (new translation code, PART 1)
  2. Import from CSDS online into SDesk via clipboard (uses same translation code as PART 1 above).
  3. Make sure that roundtrip SDesk -> file -> SDesk works (even if it's SD format) (already works).
  4. Import from Taminations into SDesk via clipboard (new translation code, PART 2)
  5. Export to clipboard from SDesk in Taminations format (new translation export code, PART 3)
  6. Export to CSDS files from SDesk in CSDS format (new translation export code , PART 4)
mpogue2 commented 1 year ago

Commit: 7758dd8db0d1560115c6c4ae9a5b06ac90175784

If there isn't already a .squaredesk/metadata.csv file, the authorID is set to the same as userID (it's a number). Right now, if you want it to be a real string, you'll have to edit this by hand right now, e.g. "authorID,Mike Pogue". Then, that string will be used for the #AUTHOR=# records in saved sequences, until such time as we add this as a Preference later on.

mpogue2 commented 1 year ago

Notes regarding COMMENTS:

  • Taminations supports comments: -- whole-line comments are lines whose first non-whitespace character is not alphanumeric -- prefix comments are NOT supported, e.g. "(Each Side) Single Wheel" -- suffix comments must be in square brackets, e.g. Boys Run [Left] -- These comments are round-trippable, that is, Copy then Paste will retain the comments.

image

  • CSDS Online does not support ENTERING any comments at all.

  • CSDS (app) apparently allows creating whole-line, prefix, and suffix comments, e.g. "(left handed)", "Boys Run (Left)" or "(Each Side) Crossfire" using parens

  • SD supports ENTERING sequence comments, but it's pretty weird to do so: -- "insert a comment" -- "hello there" -- square thru 4 -- AND THEN, what is actually created in the sequence is "{hello there} square thru 4" (curly braces).

  • The resulting line with curly braces is NOT round-trippable, and it cannot be entered that way into sdtty.

  • SD does NOT support whole-line or suffix comments at all

So, there are conflicts between delimiters for inline comments.

  • Taminations requires them to be square brackets, but square brackets have real semantic meaning in SD, and are not understood by CSDS (app) at all.

For whole-line comments:

  • Taminations does them (parens)
  • CSDS Online does not do them (but it doesn't have Paste).
  • CSDS (app) apparently does them (I don't know if it has Paste).
  • SD does not deal well with comments, even ones that were entered into SD.

Also, remember that our Current Sequence pane is currently refreshed every time SD sends us stuff. And so the ONLY stuff that makes it in the Current Sequence pane is what SD understands.

I think this argues that at least for now:

  • Comments are deleted on input from CSDS file (already true today)
  • Comments are deleted on Paste into SquareDesk/SD (already true today)
  • Comments cannot be entered into SquareDesk/SD (already true today)
  • Therefore there are no comments on Export to Clipboard either (already true today)

Therefore, no work to be done on comments right now. To do so would require a major rearchitecture of how SD itself deals with comments, and that's not work for Phase 1 (Minimum Lovable Product).

mpogue2 commented 1 year ago

STILL OPEN: What to do about a trailing AL or RLG?

  • Simplest approach would be just to delete these on import (via Load Sequence or via Paste from Clipboard). The "Resolve field" will show either "Left Allemande" or "Right and Left Grand" automatically at the end.
  • More complex would be to somehow remember those two conditions separately, and stick in a pseudo-comment as the last entry into the Current Sequence window. (what would be the point of this?)

I think I'll go with the "simplest approach" for now, and see how it feels.

Implications:

  • That means that a sequence in CSDS files that ends in AL or RLG will not round trip. I think I can live with this, although it's annoying.
mpogue2 commented 1 year ago

My current TODO list for this EPIC (getting close to something I think I can actually use for P0: WRITING C1 SEQUENCES, and P0.1: PLAYING BACK C1 SEQUENCES):

HIGH PRIORITY

  • AL/RLG --> remove if at end of sequence (paste or loadFrame)

IMPORTING

  • cut/paste translator from CSDS Online (P0) and Taminations (P1)
  • error handling, when cut/paste or load doesn't work (at this level, or ever)
    • error dialog for manual correction?
    • tag for ERROR ?

ONDISK FORMAT CHANGE

  • need a way to organize by THREE factors: source.level.type
    • get rid of ".choreodb...in"
    • simplify ondisk folder organization, just use filenames?
    • perhaps .../sd//level.difficulty(.*).in
    • perhaps .../sd/source.level.type.txt
    • where type = {biggie,easy,medium,hard,getin,getout,singer,stir} and easy/medium/hard are all SStoSS sequences
    • or some code to auto import from CSDS Online?

SIMPLIFY

  • get rid of save/load to file, make cmd-s do save to current frame
  • get rid of designer, default to arranger, and rename it designer

SELECT FRAMES

  • a way to select which frames are shown (right click context menus or accordian) OR pulldown on each Frame to select which sequences are merged into the frame? e.g. View > {[X]ceder.SStoSS.basic|[X]ceder.SStoSS.ms|[X]ceder.SStoSS.plus|etc} where the choices are NOT mutually exclusive. (Choices derived from pathnames of *.in files)

FAKE DATA

  • fake data should be files stuck into the file system, so that it is a good start for new users
    • use CSDS data?

DISMISSING A SEQUENCE

  • flag as "BAD" vs "favorite" vs "worked fine" etc (Ctrl-P in CSDS) "Used" key is very similar to this (when U --> make date record)
    • Should this use some function keys, like F8/9/10 as toggles?
    • where should this data go? Maybe into the DATE RECORD below... YES YES YES
  • "date records" = what was actually used on a given date
    • put into /sd/daterecords/.csv (automatically)
    • assumes one session/day (should Jokers be split into Plus and SSD sessions?)
    • columns: ,REC,result where result = "{comma-separated list of CSDS problems}"

TODO LATER:

    • (asterisk) on the status line when modified
    • warning at app close if sequence has not been saved yet
  • create new frame
  • swap heads and sides shortcut
  • Author preference
  • tags in status line of Current Sequence for level and difficulty
  • search functionality (e.g. "find all sequences containing motivate")
  • allow Behind the Mic as a cut/paste source
  • allow Sets in Order as a cut/paste source
  • date records cleverness:
    • in /sd/daterecords have a config.txt file that contains: Jokers_Plus: Wednesday 6:15-7:15 Plus Jokers_SSD: Wednesday 7:15-9:00 SSD Then, daterecords will go into: /sd/daterecords/.Jokers_Plus.txt /sd/daterecords/.Jokers_SSD.txt
  • auto replace old calls (e.g. Curlique -> Touch 1/4)
  • make visibility of UI elements persistent
  • auto-download of CSDS data?
  • 4 buttons just on current for SHIFT-F11, F11, F12, SHIFT-F12
    • persistent CurSeq --> /.sdesk/current.txt) or sqlite DB (must be associated with a musicDir, not a laptop)
  • Revert Edits menu item
mpogue2 commented 1 year ago

After a lot of thought, I think I'm going to move to more of a Taminations-like model for writing sequences, in the following sense:

  • The Level of a sequence will NOT be enforced. Frames are collections of sequences, but they can be of any level.
  • If a user wants to name a frame by level, that's OK (it won't be enforced).
  • The current level will be selected by the user, and will be persistent. Like Taminations, this will generally be a high level, where lower-level calls are automatically part of the recognized set (e.g. All Basic/SSD/MS/Plus/A1/A2 calls are understood by a C1 parser.)
  • Calls will be color-coded based on their level, using the same colors (ideally) that Taminations uses.
  • I do like the level on the right-hand side, too, in smaller type. That's a nice-to-have.

Taminations colors:

image

As per color picker on a screen capture of Taminations:

  • Basic/MS: #E0E0FF
  • Plus: #BFFFC0
  • A1/A2: #FFF0C0
  • C1: #FEE0E0

I'm also going to get rid of the folder hierarchy, and just put all of the frame files into the <musicDir>/sd folder, just to keep it simpler. This will require renaming of files if they are downloaded from ceder.net, but I think that's a pretty simple task, and it's done only once. I'll use a standard extension so that SquareDesk can know the file type: ".seq.txt". This will allow any standard text editor to recognize the file as plain text, yet SquareDesk can still recognize it as a "Sequence File".

mpogue2 commented 1 year ago

Commit: 46d57d9822907e1d0eb0c873f88e7205cafac734

Removed the folder hierarchy, which seemed too complex. Now all sequence files are just regular files with the extension ".seq.txt" in the /sd folder.

mpogue2 commented 1 year ago

Commit: 223a25471f2eb14b9aafea3c5580f4ef61b62ded

The SD Level is now persistent. The default if you've never selected a level is "Plus". But, when you select a level, that selection will persist to the next time you open SquareDesk.

But, BE CAREFUL: Callers with a mixture of levels should set the SD level to the highest level they expect to use (otherwise, at SD startup time, a C1 sequence in the default Current Sequence window might not load properly if Plus is the default level).

mpogue2 commented 1 year ago

BUG: When initially in Sequence Designer, should not have NEW and UNLOCK buttons.

mpogue2 commented 1 year ago

Commit: 61221fa4a60fb40adbb0569c4c268a9618d173ad

image

First step in coloring. Colors are like Taminations

  • Basic/MS is blue
  • Plus is green
  • A1/A2 are yellow.
  • Right now, C1 is not recognized (that's still TODO), but it will be red.

The call lists are the internal ones used to initialize the Dance Programs.
TODO: It probably SHOULD be the EXTERNAL ones in the Reference folder.

TODO: Need to remove the WHO at the front of a call, before scanning for call level. This is true especially for the first call in a sequence, but it really should be done for all calls. TODO: Need to initialize the big long call strings just once (right now, it's for every call, which was easy to code, but dumb. TODO: Is there room for a string for level, e.g. "A1", etc.? If not, maybe colors is OK. TODO: Right now, zebra striping is still turned ON. Maybe need a preference to turn ON/OFF?

mpogue2 commented 1 year ago

BUG: If hit F11/F12 before current sequence is saved, it is gone.

mpogue2 commented 1 year ago

Commit: bef4c0c7f8b4c035901152a7847e821e00d391fd

Initial C1 coloring. Looks like this:

image

mpogue2 commented 1 year ago

Commit: 677871001ce674a533b7ba955f67a7af531f13dc

A couple of tweaks to the Current Sequence window:

  • set grid line color to black, and
  • got rid of row numbers

to better match Taminations.

Now it looks like this:

image

mpogue2 commented 1 year ago

TODO: Need ways to navigate WITHOUT the function keys, like:

  • double click on a frame to make that frame --> Current Sequence pane

TODO: Current pane arrangement (which one is Current) should be persistent.

mpogue2 commented 1 year ago

Current look and feel:

image

mpogue2 commented 1 year ago

OK, I've been thinking about how to make this paradigm better. The current UX is hard-to-understand, I think. Here are my thoughts on what would work:

  • I want to tie in the SD currently-selected level.
  • I want to have a way to edit stuff before sticking it into a file drawer (frame).
  • I want to leverage standardized names for frames, if possible.
  • I want to have the standard frames that CSDS seems to use: Biggie, Easy, Medium, Hard, Bucket Stirs. And, they should be in that order (probably the order they might be used).
  • I am totally OK with NOT allowing just any names for frames (right now). Can always open this up later.

OK, so here is what I think that implies:

  • Standard frame names used when CALLING a dance, based on the currently-selected level: level.biggie, level.easy, level.medium, level.hard -- Later on: add level.stir (but that's not very useful at C1 right now for me, so it can come later)
  • Standard frame name used when DESIGNING a dance, based on the currently-selected level: level.scratch
  • Each frame can contain any number of sequences (including the level.scratch frame, this is like a scratchpad)
  • Later on: ways to move sequences forward or backward in the frame
  • Standard Fn assignments: F1 = biggie, F2 = easy, F3 = medium, F4 = hard, (later: F5 = stir), F10 = scratch
  • Standard key assignments (in Dance Arranger mode, perhaps different in Sequence Designer mode?): -- up/down = move up/down within a sequence -- CMD-up/down = move to first/last call within a sequence -- left/right (or F11/F12, like CSDS) = move to prev/next sequence within a frame -- SHIFT-left/right = move FRAME left/right in this sequence: biggie --- easy --- medium --- hard ( later: --- stir ) -- CMD-left/right = move to first/last sequence in frame -- SHIFT-CMD-left/right = move to biggie/hard frame
  • Mental model here is: SHIFT means "work with frames instead of calls/sequences", CMD means "go as far as you can"
  • CHECK THIS: what if we're editing the call itself? left/right arrow keys need to work inside that field as expected.
  • TBD: We probably need some way to REVERT CHANGES too.
  • Moving between frames always takes you to the "Current Sequence" in that frame. This allows for varying the level while calling a dance. Biggie # 1, then Easy # 1, then Medium # 1, then Easy # 2, then Medium # 2, etc.
  • When a sequence has been modified, a "*" appears in the title bar for that frame. Somewhere.
  • If a user moves between frames OR the user QUITs the app, and there is a sequence that has been modified, the user should be asked whether to Save or Discard that Unsaved Sequence (via a dialog box).
  • When app is started, load the dance level (e.g. Plus or C1, which is persistent).
  • When dance level is manually changed, persist that new dance level.
  • At app start or new level time -- the Current Sequence pane gets level.scratch (last sequence in the file). -- Sidebar gets (in this order from top to bottom): level.biggie, level.easy, level.medium, level.hard, level.stir -- SD Level in Status Bar gets current level
  • NEW and UNLOCK buttons work as before: -- NEW adds a new sequence at the end of the Current Sequence frame -- UNLOCK allows editing of the current sequence in the Current Sequence frame
  • Hitting a Fn key brings that frame to the Current Sequence frame, and moves the level.scratch frame to the bottom-most position in the Sidebar
  • Once we're in editing mode, NEW and EDIT go away, replaced by SAVE and SAVE AS... -- SAVE = save in Current Frame; SAVE AS... has both MOVE (append to) and COPY (copy to) options -- moving a sequence will append to the selected frame, and will delete the sequence from the current frame; copying a sequence will just append that sequence to the selected frame (in both cases, the "current sequence" number for each frame will not be changed) -- selecting either SAVE or any of the SAVE AS... options will go back to VIEW mode (NEW and EDIT buttons back again)
  • NOTE: if you want to move a C1 sequence (which could be a Plus sequence actually, since Plus is a subset of calls) to one of the Plus frames, you'll have to do it manually using a text editor and cut/paste. Same for Plus to C1.
  • All sequences are numbered internally, using the previous scheme (designed to assign unique sequence numbers for each user/sequence combination). These internal numbers aren't really used for anything yet, they are basically just GUIDs.
  • Empty frames for all levels are created automatically, if they do not already exist in musicDir/sd . -- BONUS: Stick in one tip of simple initial content, just so the user has something to play with when they first start. (Note to self: get rid of the initial sample data code, and do this instead). Those could just be copied from the Resources fork of the app (which would make them easier to replace later on). -- Later on: pre-populate the files with lots of data from CSDS (maybe? A lot of these sequences are undanceable).
  • Frame files should be portable from machine-to-machine, even across users (that's why we're using a GUID + INTEGER for the sequenceID).
  • Usage data: while dancing a sequence, user can press some_key_sequence_TBD to mark a sequence as: -- WORKED OK (CSDS uses "U" key to mark it USED, but we currently use that for "Pitch Up") -- Too long (CSDS uses "CTRL-P" to bring up a Problem dialog) -- Too short -- Does not Resolve -- Illegal choreo -- Awkward flow -- Overflow -- Not liked by Dancers -- Heads/Sides used after first line -- Same hand used twice in a row
  • This usage data goes into the sqlite db (because it's metadata, similar to "this sequence was called at this location at this datetime", and a sequence may be called multiple times -- so the usage data is not 1:1 with sequences.).
  • If a sequence has not been called yet at a Location, no tag shows up in the Frame Title Bar. If a sequence was marked USED, a yellow tag "U" appears in the frame title bar. If any PROBLEM bit was set for the sequence when the sequence was called (or even if it was never called at a dance), a red tag "P" appears in the frame title bar (in place of the "U"). Right clicking on the Frame Title bar brings up a Context menu with check marks, where the used and/or problem bits can be set or cleared. When SquareDesk is started up, any USED sequences are marked in the DB associated with the session active when they were marked so. So, the DB needs to know that a sequence was marked used, and when.
mpogue2 commented 1 year ago

Key assignments would be something like this:

image

mpogue2 commented 1 year ago

Bugs:

  • Switching levels leaves the Current Sequence window blank
  • Unlock, then Move to F1 should be greyed out, if we're in F1
  • Copy should be possible without Unlocking?
  • Save Sequence should be greyed out, if not modified
  • After Unlock then SAVE, need to go back to NEW and UNLOCK buttons visible
  • If I haven't created hoedown1.*, then it will probably crash at startup (put in fake data for now)

TODO (short term):

  • USAGE tag into the frame title bar [G(ood)] or [B(ad)] or ""
  • Clear Usage Data on a sequence (just go there and press some key to clear it - same key as set the flag?)
mpogue2 commented 1 year ago

Features:

  • "Detect Error" = if any sequence doesn't end up in AL or HOME, then it's bad, so auto-mark it bad somehow
  • "Show Bad" = if a sequence was marked BAD, going to the auto-created "hoedown1.bad.ms" frame will show a list of them. OR, maybe it goes to the last Bad one, and there's a key to go backwards thru the bad ones, so they can be fixed one at a time.
  • "Show Known Formations" = in the Current Sequence list, if a call ends in a standard formation (CB, CW, PL, etc.), then annotate the end of that list item as such, e.g. "HEADS Square Thru 4.................[CB]", where [CB] is color-coded (like tags) -- In-sequence Formations: Corner Box (CB), Opposite Box (OB), Right Hand Lady Box (RB), Partner Box (PB) -- In-sequence Formations: Corner Wave (CW), Opposite Wave (OW), Right Hand Lady Box (RW), Partner Box (PW) -- Out-of-sequence Formations tack on an "O", e.g. CBO = Corner Box Out of Sequence
mpogue2 commented 1 year ago

TODO [FIXED]: Font Size for Names bigger (FIXED by f7325df269ff2c2cdddb3297b2c8986d7b21c90d) BUG [FIXED]: entry in Current Sequence list defaults to too tall, clicking on Dance Arranger fixes it (FIXED by: 21b782a27f79e43a654c1667697278a5db526f5f)

TODO: Font Size for Current Sequence calls bigger BUG: Going to Sequence Designer, title is "Current Sequence" -- where does this go? Pressing F1 changes it to hoedown1.easy.ms, as expected. So, it should probably default to that.

mpogue2 commented 1 year ago

Commit: 7318ff7c0190b0f3f4fdfdd75894cdcea7ebf431

"sd/sequenceUsed.csv" now contains a CSV list of when sequences were called. If G was hit, the sequence is marked "GOOD". If B was hit, the sequence is marked "BAD". Both B and G will take us to the next sequence. The datetime is in ISO8601 UTC. Note: This is similar to what CSDS does with U ("Used") and CTRL-P ("Problem"), however in our case we're just storing a GOOD/BAD value in a CSV file, whereas CSDS records this stuff in a database, with a lot more detail about what problems the sequence had. This file is intentionally visible (does not start with ".", so that the user can go back and manually take a look at the BAD sequences (without a specific SquareDesk UX to do so).

The current sequence number for each frame is now retained in "sd/.current.csv", and it's updated whenever the current sequence changes due to keypress. The current sequence numbers are intentionally here, because they are associated with the database, and not a specific laptop (as Preferences are).

The SD tab now defaults to Dance Arranger, since it does most all of what Sequence Designer does. User can still switch back to the simpler interface (Sequence Designer), if desired.

Sequence files are all of the format: "...txt", where:

  • dance = "hoedown1" (hard coded right now)
  • difficulty = {easy, medium, hard, stir} (hard-coded right now)
  • level = "ms" (hard-coded right now)

TODO: scan sd dir to find files of that format, and provide a mechanism for selecting one of them to work on (e.g. "hoedown1")

Keyboard navigation is as per the diagram I drew above:

  • up/down = within sequence
  • left/right = moves between sequences
  • CMD = moves all the way to beginning or end
  • SHIFT = moves between frames, in this order: {big -- easy -- medium -- hard -- stir}

".squareDesk/metadata.csv" contains a numeric userID, and numeric nextSequenceId, and a human-readable authorID. The default is to start with a random userID, nextSequenceID == 1, and authorID == userID. A human can hand edit the file to replace the authorID with a human-readable one.

mpogue2 commented 1 year ago

Feature:

  • When a sequence is edited/changed, it should get a new sequence number (because it's a different sequence!).
  • The old sequence is written to an archive file, in case we need to go back and reference it. User can always manually edit or delete the archive file. Something like "hoedown1.archive.ms.txt", perhaps?

Question:

  • We have "sessions", which are essentially automated "groups" (e.g. Jokers is a group). Should we use groups/sessions (like "Jokers") instead of dances (like "hoedown1") instead? This breaks down when Jokers meets on more than 1 night, but it's already kinda broken, since I do Plus from 6:15-7:15 and SSD from 7:15 to 9:00.
mpogue2 commented 1 year ago

Feature [FIXED]: If the resolve is Left Allemande, that should be recorded as a ( comment ) in the sequence. AND, on input, it should stick comments into the Current Sequence pane. Maybe not? The resolve line does show the "left allemande" or "at home".

OK, I decided to put the resolve into the sequence in the file, but NOT show it in the Current Sequence window. The commit that does this: e9fa34d22760a45dd49cf1a8af8d00a60b758639 .

mpogue2 commented 1 year ago

BUG?: When I save a sequence that I just wrote, it highlights the first call. Perhaps it should highlight the last call?

mpogue2 commented 1 year ago

Feature?: Key to swap HEADS and SIDES in a sequence

mpogue2 commented 1 year ago

BUG [FIXED]: REC's are incrementing by 2, they should increment by 1 (Is that because the NEW creates it, and the SAVE increments it?). Yeah, that looks like it.

This bug was fixed by commit: c42004f56f60b13004f4d33f4024fcbff053b1b1 . Now, NEW will NOT write to the file, but SAVE (really REPLACE under the covers) will. REC's are incrementing as expected now.

mpogue2 commented 1 year ago

Feature?: Should G and B be locked out for some period of time, so that they are not accidentally triggered?

mpogue2 commented 1 year ago

BUG [FIXED]: Resolve line, when it's big (e.g. circulate 1-1/2 BTL resolve) makes the whole pane very wide....

Actual long-winded wording: "promenade (1/8 promenade, or couples 1/2 circulate, bend the line, you're home)"

This was fixed by commit: 7bd204a7cbd659afbff905b36afe1b6b64ec9749 .

mpogue2 commented 1 year ago

BUG [FIXED]: "Quarter In" --> "1/4 in" should be colored like an A-1 call Fixed by: 1d1f49f268de4b27759cd27dff7cb2acf2c577b3 .

mpogue2 commented 1 year ago

Bug [FIXED]: CMD-SHIFT-DownArrow while focus is in the Title field is not moving the selected song down in the playlist. It does move the song down, when the focus is in the songTable.

EDIT: This bug was actually already reported earlier (twice!). I just fixed it in commit 44e371114a0179ab703e446b65cb2d50db661a2d .

mpogue2 commented 1 year ago

Bug [FIXED]: when first coming into SD, the resolve line isn't set to anything. Hit LEFT then RIGHT ARROW, and it appears.

This one seems to be fixed.

mpogue2 commented 1 year ago

Bug: NEW (NULL) sequence isn't viewable at all, needs to be manually edited in text editor. So, do NEW, and then quit the program. This last sequence isn't viewable.

This commit (c42004f56f60b13004f4d33f4024fcbff053b1b1) adds an edit sequence indicator, which is triggered either on NEW or UNLOCK. However, NEW will create a sequence, but now will NOT write it to the file. That will be done at SAVE time. If the app is quit between NEW and SAVE, nothing is written to the file. AND, null sequences are written as "just as you are", which makes them both viewable and editable. It also fixes the "null sequence" bug described above.

mpogue2 commented 1 year ago

Bug: Blank lines at the end of a sequence file are treated as a valid sequence (and they're not). These should not be created unless there's a bug, but if there is a bug, the UX can be very confusing.

mpogue2 commented 1 year ago

Feature: If a sequence is being edited, and user does QUIT, offer to save the sequence before quitting.

mpogue2 commented 1 year ago

Bug: New "*" shows up when last sequence is new, but previous sequence is not, and I hit LEFT_ARROW.

Bug: New doesn't give me a blank sequence (it used to).