Fighting Int Scale Resolution

Wondering if anyone has suggestions on getting smoother values out of draggable components – if you’re dragging a component you’re essentials locked into a resolution of getHeight() or getWidth() due to bounds on components being held in ints.

Is the only option to manage some sort of points and essentially rewrite a whole set of drag functions? Would be very convenient if we could have float component bounds – even if they rounded to int on actual drawing!

1 Like

this would be a breaking change for the juce code base so a lot of people will probably be against it, but i’d also say it’s a breaking change for the better, because it rarely looks good enough to write layout code purely in int due to all the rounding errors and stuff. the question that we should ask ourselves here is: does anyone ever not convert things to float before starting with layout calculations? and if yes: do these people mind the breaking change or did they only use int because they only make little prototype apps? another useful perspective here is to compare it with game engines, where all positions are definited as float variables as well, because they know graphics are important and people don’t use int anyway, so no point in trying to “maybe save” resources. maybe trying to use int for stuff like that gained performance boosts some time in the past, but is it still true?

Perhaps use a design resolution of 10x and then use an AffineTransform to scale everything back down?

1 Like

Nice idea – gonna give this one a shot

Update no dice with affine transform - create a ton of necessary changes – float bounds JUCE 7 lets go! xP

2 Likes

Why not build your own class to do this?

class FloatPrecisionComponent : public juce::Component
{
public:
    void setBounds(juce::Rectangle<float> b)
    {
        floatBounds = b;
        juce::Component::setBounds(b.toNearestInt());
    }

    // etc for other bounds methods

private:
    juce::Rectangle<float> floatBounds;
};

You’d need to put some more time into it, and there might be other problems that pop up, but it seems like it should be possible.

Derp okay that’s also a good idea — it won’t tie in easily to the various drag helpers etc, but at least I’ll be able to retrieve the original float bounds which was the goal for the component which make dealing with the loss easier.

Will report back on that tomorrow

Yeah you might need to do a lot of casting for this. Another option would be to use the resized() virtual function like this:

class FloatPrecisionComponent : public juce::Component
{
public:

    void setBounds(juce::Rectangle<float> f)
    {
        repositionedWithFloat = true;
        floatBounds = f;
        juce::Component::setBounds(f.toNearestInt());
    }

    // etc. for other set methods

private:

    void resized() override
    {
        if (!repositionedWithFloat)
            floatBounds = getBounds().toFloat();

        repositionedWithFloat = false;
    }

    // you might need to override moved() as well

    bool repositionedWithFloat = false;
    juce::Rectangle<float> floatBounds;
};
1 Like

I’d prefer if it were easier to make JUCE’s component bounds and drawing match the screen pixel positions. Then if you drag one pixel your component will move one pixel.

JUCE hides and auto scales the actual rendered resolution away to make it easier to have different sizes for your plugin. That means the forced integer bounds of your components can fall between rendered pixels.

I’ve made changes to JUCE that let me request an actual resolution for rendered pixels and removed all the OS auto scaling but I’d prefer an ‘official’ way to do this.

2 Likes