Open elanhickler opened 6 years ago
Note: We will differentiate between paint and draw. Paint implies repaint()
may be called and is a method found in juce::Component
. Draw implies this function is called inside a paint method. Resource classes should implement draw()
Basic resources are things like images, fonts, svg that you intend to call draw()
inside a paint method.
Resource classes are classes that hold one or more basic resources for a higher level purpose
Resources cannot be interacted with, but may be intended as a paint routine for a Component
subclass. Components are meant to be added to parent components (aka editors) so that the parent manages its visibility, repainting, resizing, etc. What you don't want to do is make a component subclass just to call its paint method in the parent component's paint method. A component is for adding to a parent usually via addAndMakeVisible()
. I didn't understand this stuff a few days ago. Based on the user interaction of the component you can manipulate the paint method to then change how said resource is drawn to create user interaction with one or more resources.
phew - that's a lot to absorb. ...need to read it again... what strikes me a bit odd is that you seem to somehow conflate painting with mouse-handling when you say things like:
You will not actually use painters. You will override the paint() method in RSlider or ModulatableSlider rather than use a painter since the mouse handling cannot be customized.
but i actually think that painting and mouse-handling are two very separate issues that should not be conflated
The only code that I seem to need to duplicate is the mouse handling, so if we figure out a good strategy to setup mouse handling this would be perfect.
i actually have an idea how to do that. client code would then do things like:
mySlider->setPainter(&mySliderPainter);
mySlider->setMouseHandler(&mySliderMouseHandler);
so client code could customize both aspects independently
You are right Robin, mouseHandler/Painter sounds like a good strategy. I wrote this more to see if it makes sense. Still figuring out if what I wrote it makes sense. If you skimmed through what I wrote, you probably read enough of it!
I have a situation in my plugin where I have both sliders and knobs and it would be confusing for the user to have to drag horizontal for just a few sliders when it's vertical for the majority of the controls. I could make all knobs and sliders respond to just vertical or just horizontal, but that is equally confusing if you are used to one way versus the other.
This solves the issue of having to code vertical or horizontal dragging. This allows for controls to respond to both horizontal and vertical seamlessly. This is how some plugins do it and probably it will become the standard in the future.
if (!e.mods.isRightButtonDown() && !e.mods.isCommandDown())
{
int newDragDistance = e.getDistanceFromDragStartY() - e.getDistanceFromDragStartX();
int dragDelta = newDragDistance - oldDragDistance;
oldDragDistance = newDragDistance;
dragValue += scale * dragDelta;
double y = normalizedValueOnMouseDown;
y -= dragValue;
y = clip(y, 0, 1);
setNormalizedValue(y);
}
so, the main difference to my RSlider::mouseDrag is this:
newDragDistance = e.getDistanceFromDragStartY() - e.getDistanceFromDragStartX();
vs this:
newDragDistance = e.getDistanceFromDragStartX();
hmmm...so it would respond equally to both drag dimensions...but - maybe i'm confused - it looks like it reverses the response to horizontal drag due to the minus sign in front of the x-value? shouldn't it be + instead of -?
Yeah you can swap around some variables/signs to make the math look better. But the math I gave you is sound.
Create a .h and .cpp dedicated to resources as static members of a class called
EditorResources()
or whatever.Font()
andImage()
static members for any fonts and images and svg etc that you will be using.paint()
onRSlider
or whatever), you do something likeclass MyFontWidget(Font desiredFont) : public RSlider
instead of doing over and over again classMyFontWidget(const char data, const size_t size)
filling outBinaryData::tekoFont
,BinaryData::tekoFontSize
Create a .h and .cpp dedicated to custom classes overriding paint.
paint()
method inRSlider
orModulatableSlider
rather than use a painter since the mouse handling cannot be customized.Every unique widget, and I mean every one, create a new class and override RSlider or ModulatableSlider. The only time you should reuse a class is if you're just changing stuff like color, size, font style, rotation, etc. OTHERWISE you should create reusable graphic/path functions that help you do the repetition of creating the
paint()
method in every new class.When viable, from your various UI classes, create a reusable UI object/template, like one knob that you use multiple times in the UI that has the same color, same size, same everything, so you can just change that one template to quickly affect all ui elements that are exact copies.
Tip: Because you are rapidly creating multiple small UI element classes, it is best not to go crazy and create functions for everything like
setFontSize()
,setFontColor()
,setBackgroundColor()
. Instead, get used to accessing the members directly, and use members that are easy to manipulate.font.setHeight()
,fontColor = Colour({x,x,x})
,backgroundColor = Colour({x,x,x})
. Or you could create a custom font class to do stuff likefont.setColor()
,font.setSize()
, and finally usefont.draw(g)
in your paint methods. Only create functions if you need to do something like call repaint when you change something or if you need special functionality likevoid doBlink(bool v)
.