Over the weekend, while finishing up the current Diablo3 season (using a Shortcut prototype, powered by Kaleidoscope; of course), my unconscious spent some time thinking about Chrysalis and its architecture, while the rest of my brain conveniently switched off while hunting demons. While I will present a number of ideas here, unfortunately, there will be no pictures, no mockups, or anything like that, so we’ll have to use our imagination. And I hope I can describe the ideas good enough to be imaginable. Mind you, some details may end up being a bit technical, this is pretty much an unedited brain dump now.
Starting up
So, we want to support different hardware with the application, so it should try to discover the device as soon as possible: it would scan the USB devices, and if it sees something it recognises, it would try to connect to it via Serial, and issue a version
command to figure out the details. For the time being, until we figure out a way to do plugins, this would be built into the application, just like it all started with Kaleidoscope, too. If it finds no device, it would present a way to manually select one.
Home screen
Once we have a device, it’s time to load up the starting screen! Up until now, the user was presented with a logo, and a progress bar. With the starting screen, we’d still have the logo, the keyboard manufacturer + product under it, and then a set of boxes with which we can reach the various functions of the application. When selecting one of the functions, a new screen loads. Each of these would have a little Home
(or Back
) icon in the top left corner, to allow navigating back to the starting screen. I think this is a better approach than the permanent sidebar, that takes up a considerable amount of space, yet, it is unlikely to see frequent use.
Layout editor
One of the most used parts, and the first one we will likely develop, is the layout editor. The latest backer update showed a preview of it:
https://ksr-ugc.imgix.net/assets/015/983/708/3bb9653e3006795de1e20bb1d49c9fb5_original.gif?w=639&fit=max&v=1490319942&auto=format&gif-q=50&q=92&s=ffd901a100c8ffce0122a08e166db518
You basically click around, or otherwise navigate the keyboard, and once you found a key you want to replace, click it. Then you are presented with a menu - either a popup, or one in a fixed place on the right - where you can configure that particular key. What I’m not sure about, is how we can discover features of the firmware? Like, if one-shots are not compiled in, we likely should not present those as possible key actions, either. I was thinking, that we could have a Features
plugin (or bake this into Kaleidoscope-Ranges
, which sort of does something related), which would keep a set of flags, whether a particular plugin is enabled or not. Plugins could then poke their flag on when they are included and used, and Chrysalis could ask the keyboard for a list of features, and get a bit mask, which it can then translate back to actual features. This would not take much space on the keyboard, and still be reasonably useful. The downside is that we have a central registry of features now, and both the firmware-side list, and Chrysalis must be in sync for this to be useful. But then, we already have something like that with Kaleidoscope-Ranges
(not going into detail what that plugin is for, feel free to ask me if you are curious).
Profiles and devices
For different keyboards, a different layout would load, and they’d be saved in different “profiles”. Question is, how do we figure out the configuration on the device? As in, if you have two Model 01s, plug one in, configure it, then unplug it and plug in the other, how will Chrysalis know it is not the same device? We could hash the EEPROM contents, I suppose. Every unconfigured keyboard would look the same then, but once you configure one, that one would be different.
And this leads to a next issue: what if multiple Kaleidoscope-powered devices are plugged in at the same time? I do that all the time: both the Model 01 and the Shortcut are plugged in. We’ll need a device chooser, I suppose. Could reuse it in the initial discovery too, when no device, or multiple devices are found.
Layout editor, take two
But, back to the layout editor! When you configure an action, it would internally store it in a structured fashion, one that is easy to work with, to export, and so on. In a format independent of the codes used under the hood. When applying the layout, Chrysalis would do so via a shared “compiler” that translates its internal format to keycodes Kaleidoscope works with. We’ll have to come up with an extensible internal representation. Doing the compiling/transformation afterwards is a walk in the park in comparison.
LED theme editor
The LED theme editor would look somewhat similar to the layout editor, except we’d have a permanent palette on the right (itself editable, of course). You click a color, then click all the keys you want to apply that color to, and done. Repeat until you have a theme you like. In the future, we may want to allow selecting a group of keys to apply colors to. But perhaps not in the initial version.
Below the palette, would be the color chooser: the selected color could be altered by selecting a different one from the chooser.
Firmware flasher
Now, this is simple. Select file, hit upload, wait, done. I don’t think we need more than that?
REPL
This is something I want to have a lot of polish too, because I will use this the most. What I have in mind, is not only a very dumb thing that I can use to send and receive data to the keyboard, by speaking its low-level protocol (though that should be an option too!), but something higher level.
It would turn the keymap.map
dump (which is a series of 16-bit integers) into a proper layout, one that looks the same as if it were on the layout editor. Even better, if it could load up, and embed the editor, that would be best.
Same goes for the colormap and the palette, and possibly other things too: Chrysalis should apply as much formatting and presentation, as is needed to represent a particular thing to the user.
However, this will only work well, if we have a reasonably modular architecture, so initially, the REPL may do some formatting, but it will not embed any other parts of the application yet.
Closing thoughts
This is all I had in mind for now. In the next few days, I’ll try to come up with a few mockups, to see if those help. Other than that, I think that pondering about the plugin architecture at this point is not necessary. It would take too much time and effort to do so, and shipping something is more important. We can - and will - rewrite parts when necessary. I did that with Kaleidoscope plugins, some of them have been rewritten more than three times. While it feels sad, and perhaps a waste to do that, these things are small enough to be rewritten in a week or so. I hope Chrysalis will end up similarly.