Created
October 29, 2022 10:17
-
-
Save christoph-hart/5f52a59cf66855d035c744aae3415fe5 to your computer and use it in GitHub Desktop.
HiseScript RectHelper functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** 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