Home Artists Posts Import Register

Content

The re-write of all the drag and drop stuff is going well. I just got to the point of handling the sample override feature. Currently if you are stamping a single sample, you can hover over an existing sampler block to override the sample to the one you are stamping, and if you want to keep it, just left click to assign the new sample to the sampler block. Up until now this has been coded in a pretty hacky way, because I have always planned to generalise the idea to allow overriding entire blocks, not just samples

The block "clone" operation in Blockhead works because every "block" on the workspace is actually an instance of an underlying "base block". Cloning a block is simply a case of creating a new instance which points to the same base block. Implementing a generalised "block hot-switching" operation similar to the way sample overriding works now is not straightforward because blocks instances can't currently be updated to point at a new underlying block. Once a block instance is created it will always point to the same base block.

There's no good technical reason for this. It just simplified things a lot while putting everything together because I don't have to worry about updating all the user-facing controls when the underlying base block changes. So there are many places in the codebase where I am making the assumption that the base block will never ever change.

My initial assumption while thinking about this was that if I want to support hot-switching a block instance from one base block to another then I will have to make the big change to allow block instances to update the base that they are pointing to.

However this isn't actually necessary, since the overhead of creating and removing blocks is very light, I could just temporarily replace the entire block instance with a new one while the user is hovering over it, and then when they click to commit the change, just discard the old block instance. This way there is no need to change the way block instances work.

With sample overriding the implementation only needs to be slightly different. Since the behavior of sample overriding is to keep all of the current sampler block settings but just change the sample that is being used, so I will have to take a temporary copy of the sampler block with just the sample changed, and use the result of that for the temporary block instance.

So the plan is, when the user is in the process of placing a single block (not including drag operations), any time they hover over an existing block, a temporary "hot-switch" will occur in which the sample on the workspace is entirely replaced with the new block, with some special behavior for when it's a new sample being added over an existing sampler block, in which case just the sample will be replaced.

This could actually be annoying though, because sometimes you just want to place a new block over the top of an existing block, overlapping some portion of it. This is the default behavior now, except when you hover a new sample over an existing sampler block, which triggers the current overriding behavior, so it's inconsistent.

So what I should probably do is introduce another modifier key so that overrides only occur while a key is pressed. This brings me on to the next thing I have been thinking about...

The current Modifier Key situation in v0.26.0

  • To disable snapping while dragging blocks around or adding new ones, hold down SHIFT or CTRL (both work because personally I think I would find it too hard to remember which one it is.)
  • To change a sampler block's sample offset, you can hold SHIFT and drag left and right on it
  • To change the amplitude of any block that has an amplitude parameter, you can hold SHIFT and drag up and down on it
  • To change the choke envelope "Level Curve" segment of a block, you can hold SHIFT+ALT and drag up/down/left/right on it
  • To manipulate warp markers on a block that supports warping (currently just sampler blocks), hold down ALT and drag left/right on it, or right-click on an existing warp marker to delete it

None of this was thought through properly because I was just adding things as I went along but I think it's ok at the moment. We're running out of the "common" modifier keys though (CTRL/SHIFT/ALT) and now I want to add a new one to enable/disable the overriding behavior and a question arises about which operations really deserve to be tied to those special keys on the keyboard.

An alternative to a modifier key would be a toggle, where you press a keyboard shortcut once to enable a mode and it just stays on until you press the shortcut again to turn it off. I think this is probably what I should be doing for snapping and overriding, but I will need to add something to the UI to clearly show which modes are currently enabled and disabled.

The correct place for that is probably the right-hand side panel, but it's not clear at the moment where in the side panel to add something like that. The sidebar has an "expanded" and "collapsed" view. In the collapsed view I can just add an icon for each toggle to the bar the way I do currently for file browser drive/shortcut buttons, but when the sidebar is expanded i'm not sure how to best position them where they could be always visible.

I am already planning to throw the entire sidebar away and replace it, so I have been thinking about how things should be laid out. I like the fact that the file browser is separate from everything else and can stay visible regardless of which tab is open at the top so I will probably try to keep that. In the future I will likely add a docking system so you can drag it over to the left of the screen if you want but I don't think I will worry about that yet.


Something like this would be ok. The collapsed view would just be the left-hand edge items of the expanded view, and the toggles would be visible regardless of which tab you're looking at.

Whatever the interface for accessing blocks and samples eventually looks like, it's going to have to interact with the instrument editor. I have no idea what the instrument editor is going to look like yet but I'm pretty sure it's going to be far too complex to cram into the sidebar, so it will probably be a window that pops out over the top of the workspace area.

The instrument editor will allow you to do things like, map a block or many blocks to the notes of a MIDI keyboard and specify what transformations to apply to its parameters based on which key was pressed (the obvious one is to map the played MIDI note to the "Pitch" parameter of the block so you can play it like an actual instrument. Would Blockhead finally count as a real DAW once we have that?!)

"Blocks" and "samples" are still different types of entity and I think I do want the instrument editor to have access to both. I really don't want to have some duplicate interface inside the instrument editor for accessing blocks and samples which is why I would like it to behave as a sub-window of the sidebar tab. But Blocks and Samples are currently on separate tabs so I might squash them together into one place something like this:


I am now in a slightly awkward place where I am still in the middle of working on the drag/drop rewrite and suddenly I am thinking about the eventual instrument editor because the UI is all subtly connected. I still want to keep releasing useable alpha builds at least semi-regularly so I don't want start rebuilding the side panel just because of this block overriding thing.

So I think what I will do is just write the code to support the new block overriding stuff but just temporarily disable it until I have a way to represent toggles in the UI. Snapping will temporarily continue working as it does (hold down SHIFT or CTRL to disable it).

Then I can get on with finishing the rest of this drag/drop system rewrite, try to fix the few bugs and crashes that we found in v0.26.0, and then that will be a v0.26.1 build. Then I will probably get to working on the new sidebar.

Comments

No comments found for this post.