-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TODO 4: Design system #168
Comments
Thinking out loud about panels: Fundamental LFO has a width of 9HP - here confirmed by measuring against a row of my HP1 module (pretty much what it was made to do!) I find that a bit weird though because there are 4 ports, but 9HP? We could say 0.5HP either side and we're even, but it isn't really possible to account for 0.5HP if the module were half the width of Fundamental LFO... so, it's just a "by feel" number, I guess, in Fundamental LFO's case. I imagine it probably looks rigid and uninteresting when everything is very grid-like with equilateral placement, such as if it were 8HP. Perhaps a good rule of thumb here - for panels generally - will be; Width = (number of ports * 2) + 1 The spare 1 just being a bit of thumb room. Pun intended. EDIT: Hmmm... looking at it some more, the extra 1 is a helpful offset, which allows the odd-numbered "big knob" (just one of them) to sit flush in the centre of the row of even-numbered ports. Clever. |
So if an even-number N of ports fits well into a panel width of N+1... how about an odd number of ports?? If there were three ports, then I'd be inclined to make a 5HP width - so that there can still be a "centre" and just have the ports a little more spread out. Makes me wonder if odd-numbered panel widths are a bit of a beauty spot... depending on who is beholding the eye. |
ProblemSo. Much. Boilerplate. Primarily, my module code is excessively large because:
IdeaHere's something that might work...
Bonus points
|
vague plan
In the process, I hope to also start and roughly finish the LFO module. This clears the way for some of the more interesting "main event" modules I have in mind, which I will broadly work on over the course of the coming months/year. I might attempt to push my control modules and blank panels as a plugin to the user library meanwhile, as a placeholder for the brand name, and for the sake of investigation. |
Into the nuts and bolts and backplates now... DilemmaThis (port socket backplate) is a nightmare to work with: Really difficult in code because the coloured backpanel (widget) is not coupled with (or a child of) the port (widget). Both the port socket, and the backplate are being set separately using hard-coded pixel values, which is a design-system no-no... Really difficult in Inkscape because Inkscape... To make matters even more complex, ports are of course circular, meaning we either work with their centred co-ordinates with some maths, or work with a leading edge, and some maths. SolutionSub-class Such a sub-class must be compatible with |
VCA Module Widget constructor output port member initializer: portVcaOutput(
::rack::createOutputCentered<::rack::componentlibrary::ThemedPJ301MPort>(
::rack::math::Vec(
size.x * 0.5F,
// widget is 28.55155 x 39.15691
// port is 23.7 x 23.7
// widget.x - port.x = 4.85155 (/ 2 = 2.425775 = edge distance)
((39.15691F - (23.7F * 0.5F)) - 2.425775F) + (309.05634F)
),
module,
::StoneyDSP::StoneyVCV::VCA::VCAModule::IdxOutputs::VCA_OUTPUT
)
) VCA Module Widget void draw(const DrawArgs& args)
{
// <SNIP>
// draw out port box
::nvgBeginPath(args.vg);
::nvgRoundedRect(args.vg,
/** x */(size.x * 0.5F) - (tst.x * 0.5F),
/** y */(309.05634F),
/** w */tst.x,
/** h */tst.y,
/** rx */2.83465F
);
::nvgFillColor(args.vg, bgPort);
::nvgFill(args.vg);
return ::rack::Widget::draw(args);
} Rack internal code: template <class TPortWidget>
TPortWidget* createInput(math::Vec pos, engine::Module* module, int inputId) {
TPortWidget* o = new TPortWidget;
o->box.pos = pos;
o->app::PortWidget::module = module;
o->app::PortWidget::type = engine::Port::INPUT;
o->app::PortWidget::portId = inputId;
return o;
}
template <class TPortWidget>
TPortWidget* createInputCentered(math::Vec pos, engine::Module* module, int inputId) {
TPortWidget* o = createInput<TPortWidget>(pos, module, inputId);
o->box.pos = o->box.pos.minus(o->box.size.div(2));
return o;
} We can remove many of those hard-coded decimal values (xx.xxxxxF) if the sub-class idea works.... |
I have a slider version (instead of knob) which I think I prefer for the VCA, or possibly in general... incoming. |
WIP status: working design, text labels for RoundBlackKnob: Since we can just resize the previously-known-as "opaque type" object anyway with Here, I used the exact same Knob Panel struct, simply swapped So, the cropped outer ring should be able to work the same! Still to come: add the outer ring, including an (enum?) accessor to specify whether the Knob is unipolar, or bipolar. Extra points if we can deduce the crop angle of the outer ring using the WIP: Added a cutaway with the (one-armed) scissor: I believe the slightly ugly flat-top of the clipping could be improved, by replacing this scissor method - whereby I'm simply cropping the viewbox by some constant amount(s) - with another hollow circle, moved away from the centre towards the clipping region. Nonetheless, I've sure seen (and done) much worse than this attempt. In some sense, it's good enough to pass. WIP update: using The values of So, to prove a point... let's try throwing some weird min/max values and different knob sizes - no other changes - while cleaning up the debris of unused code I've got locally (some of which I'll probably put in the StoneyDSP lib as it's useful nonetheless, if not here). EDIT: update
...I:
Result: The knob ring is perfectly tracking the parent widget's range! 🆒 The margin, or "leading" seems a bit "wrong" here, too much of it for the smaller widget size... but since that variable can be easily set externally, it's no show-stopper; I've already accomplished more here than I actually expected to. EDIT: Mission accomplished: Close-up showing rounded linecaps and corners, and nice even spacings: (VCA module still in draft mode here): 👍 |
Latest: I was able to draught this LFO panel up very quickly (comparatively speaking) within nanoVG, using the new design system and component library Widgets: Plenty missing, and some obvious thoughts straight off the bat (port spacing?) but lots of great things "just worked":
There are a couple more smells under the hood, particularly in Module and ModuleWidget constructor code... We might be too far in to the LFO already to fish those things out effectively while developing this module; I'll probably sprint to get a few more of this module's features in place before anything else. |
Interesting - and, expected - challenge with the panel spacing: I don't like the port panels being flush against the panel bounds (inner lines) - I think in a hardware scenario, those areas would be a little bit flimsy without the right care, and hence I'm using those inner lines to tell myself what my "safe margin" is, at least according to what's in my head about hardware panels. In this case, I'll probably reduce the gap just enough and see if I can condense the port panels into one, without squishing up the thumb room for handling cables. If necessary, I'll add some sort of variable to set corner types on the port panel widgets.... |
I rooted this one out. In summary; since the The problem was, that I have specified an in-class initialiser to a null-ish value on each of these vectors. This null-ish value at position 0 was making its' way all the way to the instantiated module constructor, where I was mistakenly thinking I was reserving and emplacing new elements into an empty vector, having overlooked that this null-ish value was already in there... d'oh! Just adding There are still some cases where specific element access is desired - setting labels and other ephemeral, unique options - and that is completely reasonable. I'll update the VCA module in due course, and the blank panels eventually (if at all). |
What I really want to do is...(pseudo-code)
The blocker:
|
onThemeChanged
" events, if possible, to mark framebuffer widgets asdirty()
#263The text was updated successfully, but these errors were encountered: