Rectangle suggestion : removeProportionFromTop()


#1

I know Rectangle already has many methods, so I would understand if you don’t want to add the following ones, but I think they would be really useful and avoid quite some typing when writing resizable interfaces.
the removeFromXX methods are great, but I keep having to calculate the amountToRemove before calling them.

   /** Removes a strip from the top of this rectangle, reducing this rectangle
        by the specified proportion and returning the section that was removed.

        E.g. if this rectangle is (100, 100, 200, 200) and proportionToRemove is 0.25, this will
        return (100, 100, 200, 50) and leave this rectangle as (100, 150, 200, 150).
    */
    template <typename FloatType>
    Rectangle removeProportionFromTop (FloatType proportionToRemove) noexcept
    {
        const Rectangle r (pos.x, pos.y, w, ValueType (proportionToRemove * h));
        pos.y += r.h; h -= r.h;
        return r;
    }

    /** Removes a strip from the left-hand edge of this rectangle, reducing this rectangle
        by the specified proportion and returning the section that was removed.
     
        E.g. if this rectangle is (100, 100, 200, 200) and proportionToRemove is 0.25, this will
        return (100, 100, 50, 200) and leave this rectangle as (150, 100, 150, 200).
    */
    template <typename FloatType>
    Rectangle removeProportionFromLeft (FloatType proportionToRemove) noexcept
    {
        const Rectangle r (pos.x, pos.y, ValueType (proportionToRemove * w), h);
        pos.x += r.w; w -= r.w;
        return r;
    }

    /** Removes a strip from the right-hand edge of this rectangle, reducing this rectangle
        by the specified proportion and returning the section that was removed.

        E.g. if this rectangle is (100, 100, 200, 200) and proportionToRemove is 0.25, this will
        return (150, 100, 50, 200) and leave this rectangle as (100, 100, 50, 200).
    */
    template <typename FloatType>
    Rectangle removeProportionFromRight (FloatType proportionToRemove) noexcept
    {
        const ValueType amountToRemove = ValueType (proportionToRemove * w);
        const Rectangle r (pos.x + w - amountToRemove, pos.y, amountToRemove, h);
        w -= amountToRemove;
        return r;
    }

    /** Removes a strip from the bottom of this rectangle, reducing this rectangle
        by the specified proportion and returning the section that was removed.

        E.g. if this rectangle is (100, 100, 200, 200) and proportionToRemove is 0.25, this will
        return (100, 150, 200, 50) and leave this rectangle as (100, 100, 200, 150).
     */
    template <typename FloatType>
    Rectangle removeProportionFromBottom (FloatType proportionToRemove) noexcept
    {
        const ValueType amountToRemove = ValueType (proportionToRemove * h);
        const Rectangle r (pos.x, pos.y + h - amountToRemove, w, amountToRemove);
        h -= amountToRemove;
        return r;
    }

#2

That’s a nice idea, actually - I can imagine that being handy in a lot of situations. Thanks, I’ll take a look!


#3

note however that it would be useful ‘only’ when dividing component in 2 parts.
Doing something like :

comp1->setBounds (b.removeProportionFromLeft (0.25f));
comp2->setBounds (b.removeProportionFromLeft (0.25f));
comp3->setBounds (b.removeProportionFromLeft (0.25f));
comp4->setBounds (b.removeProportionFromLeft (0.25f));

would make the bounds smaller and smaller.

Perhaps we can think of another way that would be more useful in such cases. perhaps something that would not reduce the original bounds, but just allow getting a proportion out of it

Rectangle getProportion (FloatType xProportion, FloatType yProportion, FloatType widthProportion, FloatType heightProportion)


#4

Probably

Rectangle getProportion (Rectangle<float> proportion) const noexcept

would be better


#5

yes.
it would also be nice to have those ones I think :

ValueType proportionOfWidth (float proportion) const noexcept;
ValueType proportionOfHeight (float proportion) const noexcept;

#6

You are aware, that you wouldn’t get four equal sized components, if removeProportionFromLeft changes it’s instance (i.e. b)?


#7

That’s exactly the point he was making!


#8

Sorry, overread that one:

I was misled by the example


#9

maybe something like this solves your needs?

/**
 Returns the n-th equal sized proportion of a rectangle
 */
template <typename FloatType>
Rectangle getNthProportionHorizontal (FloatType proportion, int index, bool reverse=false) const noexept;

with the reverse flag to attach to the right / bottom.


#10

I’m not sure what that method would return (?)

But actually I think that just Rectangle::proportionOfWidth and Rectangle::proportionOfHeight is all I need to be happy :slight_smile:


#11

sorry, thought that would be obvious :wink:

/**
 Returns the n-th equal sized proportion of a rectangle
 */
template <typename FloatType>
Rectangle getNthProportionHorizontal (FloatType proportion, int index, bool reverse=false) const noexept
{
    const FloatType newWidth = proportion * w;
    const FloatType newX = reverse ? x + w - (index + 1) * newWidth : x + index * newWidth;
    Rectangle<FloatType> r (newX, y, newWidth, h);
    return r;
}

So you can split bounds into four equal rectangles:

comp1->setBounds (b.getNthProportionHorizontal (0.25f, 0));
comp2->setBounds (b.getNthProportionHorizontal (0.25f, 1));
comp3->setBounds (b.getNthProportionHorizontal (0.25f, 2));
comp4->setBounds (b.getNthProportionHorizontal (0.25f, 3));

…that’s at least how I understood the initial post, but I might be completely off track, so maybe just ignore that :wink:


#12

ah yes, sure :slight_smile: Would be really useful yes to construct layout. But it’s perhaps a bit too much specific compare to getProportion (Rectangle proportion)

I’m not sure what’s the best option (I’m sure Jules will come with the perfect one ;)), but Rectangle would definitely benefit some proportional methods yes.


#13

Thanks for the commit! :heart_eyes: