I want to change the firmware of my keyboard such that I have two customised layouts in it. This means, I would have layers PRIMARY_A and PRIMARY_B, but also FUNCTION_A and FUNCTION_B, NumPad_A and NumPad_B and maybe WEIRD_STUFF_A. Basically, two unrelated groups of layouts.
I now wonder what the best way to change between them would be. I thought I would dedicate a key somehow (e.g. FN+Prog) to change the currently active layout group. Unfortunately, I cannot figure out how the firmware keeps track of which firmware it is in, currently. I suspect that LockLayer is not the right tool. I would have LockLayer in each group too, e.g. to reach NumPad.
LockLayer will be the tool you want. The easiest way would be to structure the layers like PRIMARY_A, FUNCTION_A, NumPad_A, WEIRD_STUFF_A, PRIMARY_B, FUNCTION_B, NumPad_B.
On FUNCTION_A, you’d have the Prog key do LockLayer(PRIMARY_B), so when you press Fn+Prog, it would lock to PRIMARY_B. On FUNCTION_B, you’d have UnlockLayer(PRIMARY_B), and voila! To reach numpad, PRIMARY_A would have LockLayer(NumPad_A), and PRIMARY_B would LockLayer(NumPad_B).
Imagine that layers are like stacks of foil: when you lock to or switch to one, the layers below stay active too, the higher ones merely shadow the lower ones. So as soon as you turn a higher layer off, the layers below will be used again. This way, you can shadow all the _A layers with _B.
Let me know if you need further help, or explanation!
One more thing: Your PRIMARY_B layer shouldn’t have any Key_Transparent (___) entries, to prevent getting semi-random behaviour depending on which *_A layers are active.
Thank you both very very much. That helped a lot and I was able to setup the layouts as I want them to.
I have one follow-up question. I would like to have an LED to indicate the layer the keyboard is locked to. However, with your answers I learned nothing about how the system keeps track about which layer it is in.
I currently see only the option of using a macro that accepts a layer, sets the colour and returns the right key. However, I would prefer to query some state in the loop() function instead of making the layout more complex.
You can query the highest layer with Layer.top(), and compare that to the layer, like:
if (Layer.top() == PRIMARY_A) {
LEDControl.setAllCrgbTo(CRGB(255, 0, 0)));
}
Mind you, this is very inefficient, because it runs every cycle, even if the layers did not change. It’s far less resource intensive to write a plugin that changes colors when layers do change. Thankfully, you don’t have to do that, as two such plugins already exist: the Colormap and ActiveLayerColor plugins. If you want all keys to be the same color, the latter plugin is probably the most efficient.
FWIW, the firmware stores the active layers as a 32-bit bitmap, with one bit for each active layer. You can also query all the active layers with Layer.getLayerState(), which will return you said bitmap.
Your question implies a common misconception about Kaleidoscope’s layer system — that there is only one layer active at a time. A LockLayer(N) key toggles the state of layer N, but doesn’t affect any other layers. It’s entirely possible to have all layers active (turned on) at the same time; the value looked up when a key is pressed comes from the highest active layer with a non-transparent entry for that key.