Skip to content

Instantly share code, notes, and snippets.

@christoph-hart
Created October 29, 2022 10:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christoph-hart/5f52a59cf66855d035c744aae3415fe5 to your computer and use it in GitHub Desktop.
Save christoph-hart/5f52a59cf66855d035c744aae3415fe5 to your computer and use it in GitHub Desktop.
HiseScript RectHelper functions
/** This namespace contains a few helper functions for manipulating rectangles
Most of the functions are heavily "inspired" (aka stolen) from the juce::Rectangle class:
https://docs.juce.com/master/classRectangle.html
If you're working with paint routines and LAF functions in HISE learning these functions will
help you a lot with manipulating rectangles to look like you want them!
The general usage of these functions is to pass in an area (a `[x, y, w, h]` array) and you'll return
a new array with the modified rectangle. Be aware that some of the functions change the original area -
however this is intended so you can slice an existing area into multiple parts.
*/
namespace Rect
{
/**
Returns a copy of the given `area` rectangle reduced by `amount` pixels
Example for `
Rect.reduced([0, 0, 12, 7], 2)`:
```
OOOOOOOOOOO
OOOOOOOOOOO
OORRRRRRROO
OORRRRRRROO
OORRRRRRROO
OOOOOOOOOOO
OOOOOOOOOOO
```
*/
inline function reduced(area, amount)
{
return [ area[0] + amount,
area[1] + amount,
area[2] - 2 * amount,
area[3] - 2 * amount];
}
/**
Returns a copy of the given area object that you can manipulate without
changing the old rectangle.
*/
inline function copy(area)
{
return area.clone();
}
/** Checks whether the given `point` (an [x,y] array) lies within the rectangle. */
inline function contains(area, point)
{
return point[0] >= area[0] &&
point[0] < area[0] + area[2] &&
point[1] >= area[1] &&
point[1] < area[1] + area[3];
}
/**
Returns a copy of the given `area` rectangle with the same centre position
but other dimensions
Example for `Rect.withSizeKeepingCentre([0, 0, 22, 5], 5, 3)`
```
OOOOOOOOOOOOOOOOOOOOO
OOOOOOOORRRRROOOOOOOO
OOOOOOOORRRRROOOOOOOO
OOOOOOOORRRRROOOOOOOO
OOOOOOOOOOOOOOOOOOOOO
```
*/
inline function withSizeKeepingCentre(area, width, height)
{
return [ area[0] + (area[2] - width) / 2,
area[1] + (area[3] - height) / 2,
width,
height];
}
/** Slices the given amount from the `area` rectangle and returns
the part that has been sliced away.
> The original `area` rectangle is modified!
**Example for** `Rect.removeFromLeft([0, 0, 12, 5], 3)` with
- `O`: original rectangle
- `N`: new original rectangle
- `R`: rectangle that's returned from the function
```
OOOOOOOOOOOOOO RRR NNNNNNNNNN
OOOOOOOOOOOOOO RRR NNNNNNNNNN
OOOOOOOOOOOOOO => RRR + NNNNNNNNNN
OOOOOOOOOOOOOO RRR NNNNNNNNNN
OOOOOOOOOOOOOO RRR NNNNNNNNNN
```
*/
inline function removeFromLeft(area, amount)
{
area[0] += amount;
area[2] -= amount;
return [area[0] - amount, area[1], amount, area[3]];
}
/** Slices the given amount from the `area` rectangle and returns
the part that has been sliced away.
> The original `area` rectangle is modified!
**Example for** `Rect.removeFromRight([0, 0, 12, 5], 3)` with
- `O`: original rectangle
- `N`: new original rectangle
- `R`: rectangle that's returned from the function
```
OOOOOOOOOOOOOO NNNNNNNNNN RRR
OOOOOOOOOOOOOO NNNNNNNNNN RRR
OOOOOOOOOOOOOO => NNNNNNNNNN + RRR
OOOOOOOOOOOOOO NNNNNNNNNN RRR
OOOOOOOOOOOOOO NNNNNNNNNN RRR
```
*/
inline function removeFromRight(area, amount)
{
area[2] -= amount;
return [area[0] + area[2], area[1], amount, area[3]];
}
/** Slices the given amount from the `area` rectangle and returns
the part that has been sliced away.
> The original `area` rectangle is modified!
**Example for** `Rect.removeFromTop([0, 0, 12, 5], 2)` with
- `O`: original rectangle
- `N`: new original rectangle
- `R`: rectangle that's returned from the function
```
OOOOOOOOOOOOOO RRRRRRRRRRRR
OOOOOOOOOOOOOO RRRRRRRRRRRR
OOOOOOOOOOOOOO => +
OOOOOOOOOOOOOO NNNNNNNNNNNN
OOOOOOOOOOOOOO NNNNNNNNNNNN
NNNNNNNNNNNN
```
*/
inline function removeFromTop(area, amount)
{
area[1] += amount;
area[3] -= amount;
return [area[0], area[1] - amount, area[2], amount];
}
/** Slices the given amount from the `area` rectangle and returns
the part that has been sliced away.
> The original `area` rectangle is modified!
**Example for** `Rect.removeFromTop([0, 0, 12, 5], 2)` with
- `O`: original rectangle
- `N`: new original rectangle
- `R`: rectangle that's returned from the function
```
OOOOOOOOOOOOOO NNNNNNNNNNNN
OOOOOOOOOOOOOO NNNNNNNNNNNN
OOOOOOOOOOOOOO => NNNNNNNNNNNN
OOOOOOOOOOOOOO +
OOOOOOOOOOOOOO RRRRRRRRRRRR
RRRRRRRRRRRR
```
*/
inline function removeFromBottom(area, amount)
{
area[3] -= amount;
return [area[0], area[1] + area[3], area[2], amount];
}
/** Returns a copy of the `area` rectangle with a scale factor
applied to its size **and position**.
**Example* for `Rect.scale([4, 2, 8, 4], 0.5)` with
- `O`: old rectangle
- `R`: returned rectangle
- `x`: origin `[0, 0]``
```
x
OOOOOOOO [4, 2, 8, 4]
OOOOOOOO
OOOOOOOO
OOOOOOOO
x
RRRR [2, 1, 4, 2]
RRRR
```
*/
inline function scale(area, scaleFactor)
{
local newArea = [];
newArea.reserve(4);
for(a in area)
newArea.push(a * scaleFactor);
return newArea;
}
/** Returns a copy of the `area` rectangle with a translation applied to it
**Example** for Rect.translated([6, 3, 2, 2], -4, -2) with:
- `O`: original rectangle
- `R`: returned rectangle
- `x`: origin (`[0, 0]`)
``
x
OO [6, 3, 2, 2]
OO
x
RR [2, 1, 2, 2]
RR
```
*/
inline function translated(area, xDelta, yDelta)
{
return [area[0] + xDelta, area[1] + yDelta, area[2], area[3]];
}
/** returns a copy of the `area` rectangle with the same aspect ratio
as the `otherArea` rectangle.
> This is useful in order to fit a path into a given rectangle without skewing its aspect ratio.
*/
inline function withAspectRatioLike(area, otherArea)
{
local ar = otherArea[3] / otherArea[2];
local w = area[2];
local h = area[2] * ar;
local x = area[0];
local y = area[1] + Math.abs(h - ar[3]) / 2.0;
if(ar > 1.0)
{
w = area[3] / ar;
h = area[3];
x = area[0] + Math.abs(w - area[2]) / 2.0;
y = area[1];
}
else
{
w = area[2];
h = area[2] * ar;
x = area[0];
y = area[1] + Math.abs(h - area[3]) / 2.0;
}
return [x, y, w, h];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment