Open elanhickler opened 6 years ago
how did you implement the custom ui in fmd? did you subclass all the relevant widget classes? or do you use the setPainter
mechanism that i added to RSlider for this purpose? i could certainly add a "FilmStripSliderPainter" class or something like that to my library
my SVGKnob class inherits from ModulatableSlider. I override paint method.
hmm..ok. so how do you want that to work? i could imagine to do something like:
FilmStripSliderPainter : public RSliderPainter
{
public:
setFilmStrip(juce::Image* filmStripToUse, int numSnapshots, bool isVertical);
}
and then you could instantiate an object of that class and pass it to the sliders. a similar mechanism could be implemented for buttons. the outlying class (your editor class) would then be responsible to take care of the filmstrip image object (and ensure that its lifetime is longer than the lifetime of the widgets and painter)
yes, that will work. please auto-calculate num snapshots and isVertical.
numsnapshots and isVertical is x/y or y/x depending on which axis is longer.
that would assume that one frame is exactly square. but maybe the library should not necessarily assume that - for generality. ...but perhaps the best would be to allow both and make these arguments optional....but yeah...the "isVertical" is probably indeed not needed.....hmm...or maybe for horizontal/vertical faders with very low "snapshot-resolution" (think of a wide horizontal fader with a low number of snapshots or something)....but yeah...normally, your heuristic should work
then allow for the input of the resolution of a single frame. In my experience that would be less annoying than trying to remember isVertical and number of frames, because no software helps you figure out number of frames. But it is much easier to get the resolution of a single frame.
ok - i see. then maybe just the width or height should be passed (because the other one would then be redundant)...we'll see..but yeah
setFilmStrip(juce::Image* filmStripToUse, int frameWidth, int frameHeight);
seems reasonable. maybe with default arguments zero - and if they are zero indeed in a call, the functions applies heuristics
done. If you implement this into your library I could delete mine and reference yours.
edit: I think I should start a library of convenience classes for doing synth UI
class FilmstripPainter
{
public:
FilmstripPainter() = default;
void setImageAndFrameSize(Image * v, int singleFrameWidth, int singleFrameHeight)
{
image = v;
imageIsVertical = image->getBounds().getWidth() < image->getBounds().getHeight();
frameSizeWidth = singleFrameWidth;
frameSizeHeight = singleFrameHeight;
numFrames = imageIsVertical ?
image->getBounds().getHeight() / frameSizeHeight
:
image->getBounds().getWidth() / frameSizeWidth
;
numFrames -= 1;
}
~FilmstripPainter() = default;
void draw(Graphics & g, juce::Rectangle<int> area, float normalizedValue)
{
if (imageIsVertical)
{
frameX = 0;
frameY = (int)round(normalizedValue * numFrames) * frameSizeHeight;
}
else
{
frameX = (int)round(normalizedValue * numFrames) * frameSizeWidth;
frameY = 0;
}
g.drawImage(*image, area.getX(), area.getY(), area.getWidth(), area.getHeight(), frameX, frameY, frameSizeWidth, frameSizeHeight);
}
protected:
Image * image;
int frameSizeWidth = 0;
int frameSizeHeight = 0;
//coefficients
bool imageIsVertical;
int numFrames;
int frameX;
int frameY;
};
If you implement this into your library I could delete mine and reference yours.
you mean, i could just take this code as is and add it to my library?
yes you can use this code if you want
you'll want to add stuff like getFrameWidth / getFrameHeight.
I'm going to need to add more features to this class in the future, for example, to scale correctly for eventual resizable interfaces, and for retina display. Will keep my own version.
I may need to use filmstrip for certain ui elements.