elanhickler

Constrain Sides and Edges

Feb 26th, 2020
763
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.04 KB | None | 0 0
  1. #pragma once
  2.  
  3. enum Anchor
  4. {
  5.     TopLeft,
  6.     TopCenter,
  7.     TopRight,
  8.     MidLeft,
  9.     MidCenter,
  10.     MidRight,
  11.     BottomLeft,
  12.     BottomCenter,
  13.     BottomRight,
  14.     None
  15. };
  16.  
  17. enum Edge
  18. {
  19.     Left,
  20.     Top,
  21.     Right,
  22.     Bottom,
  23. };
  24.  
  25. struct ElanRect
  26. {
  27.     // Get a rectangle point based on anchor.
  28.     template <typename T> static juce::Point<T> getPoint(const juce::Rectangle<T>& object, Anchor anchor)
  29.     {
  30.         switch (anchor)
  31.         {
  32.         case Anchor::TopLeft:
  33.             return object.getTopLeft();
  34.         case Anchor::TopCenter:
  35.             return { object.getCentreX(), object.getY() };
  36.         case Anchor::TopRight:
  37.             return object.getTopRight();
  38.         case Anchor::MidLeft:
  39.             return { object.getX(), object.getCentreY() };
  40.         case Anchor::MidCenter:
  41.             return object.getCentre();
  42.         case Anchor::MidRight:
  43.             return { object.getRight(), object.getCentreY() };
  44.         case Anchor::BottomLeft:
  45.             return object.getBottomLeft();
  46.         case Anchor::BottomCenter:
  47.             return { object.getCentreX(), object.getBottom() };
  48.         case Anchor::BottomRight:
  49.             return object.getBottomRight();
  50.         case Anchor::None:
  51.         default:
  52.             jassertfalse;
  53.             return {};
  54.         }
  55.     }
  56.  
  57.     // Place a rectangle based on a given point and anchor of given rectangle.
  58.     template <typename T> static juce::Rectangle<T> place(const juce::Rectangle<T>& object, const juce::Point<T>& subject, Anchor objectAnchor = Anchor::None)
  59.     {
  60.         switch (objectAnchor)
  61.         {
  62.         case Anchor::TopLeft:
  63.             return { subject.getX(), subject.getY(), object.getWidth(), object.getHeight() };
  64.         case Anchor::TopCenter:
  65.             return { subject.getX() - object.getWidth() / T(2), subject.getY(), object.getWidth(), object.getHeight() };
  66.         case Anchor::TopRight:
  67.             return { subject.getX() - object.getWidth(), subject.getY(), object.getWidth(), object.getHeight() };
  68.         case Anchor::MidLeft:
  69.             return { subject.getX(), subject.getY() - object.getHeight() / T(2), object.getWidth(), object.getHeight() };
  70.         case Anchor::MidCenter:
  71.             return { subject.getX() - object.getWidth() / T(2), subject.getY() - object.getHeight() / T(2), object.getWidth(), object.getHeight() };
  72.         case Anchor::MidRight:
  73.             return { subject.getX() - object.getWidth(), subject.getY() - object.getHeight() / T(2), object.getWidth(), object.getHeight() };
  74.         case Anchor::BottomLeft:
  75.             return { subject.getX(), subject.getY() - object.getHeight(), object.getWidth(), object.getHeight() };
  76.         case Anchor::BottomCenter:
  77.             return { subject.getX() - object.getWidth() / T(2), subject.getY() - object.getHeight(), object.getWidth(), object.getHeight() };
  78.         case Anchor::BottomRight:
  79.             return { subject.getX() - object.getWidth(), subject.getY() - object.getHeight(), object.getWidth(), object.getHeight() };
  80.         case Anchor::None:
  81.         default:
  82.             jassertfalse;
  83.             return {};
  84.         }
  85.     }
  86.  
  87.     // Place a rectangle next to another rectangle based on anchor and points.
  88.     template <typename T> static juce::Rectangle<T> place(const juce::Rectangle<T> & object, const juce::Rectangle<T> & subject, Anchor objectAnchor = Anchor::None, Anchor subjectAnchor = Anchor::None)
  89.     {
  90.         juce::Point<T> p;
  91.  
  92.         switch (subjectAnchor)
  93.         {
  94.         case None:
  95.             p = getPoint(object, TopLeft);
  96.             break;
  97.         case Anchor::TopLeft:
  98.         case Anchor::TopCenter:
  99.         case Anchor::TopRight:
  100.         case Anchor::MidLeft:
  101.         case Anchor::MidCenter:
  102.         case Anchor::MidRight:
  103.         case Anchor::BottomLeft:
  104.         case Anchor::BottomCenter:
  105.         case Anchor::BottomRight:
  106.             p = getPoint(subject, subjectAnchor);
  107.             break;
  108.         default:
  109.             jassertfalse;
  110.         }
  111.  
  112.         switch (objectAnchor)
  113.         {
  114.         case Anchor::None:
  115.         case Anchor::TopLeft:
  116.             return { p.getX(), p.getY(), object.getWidth(), object.getHeight() };
  117.         case Anchor::TopCenter:
  118.             return { p.getX() - object.getWidth() / T(2), p.getY(), object.getWidth(), object.getHeight() };
  119.         case Anchor::TopRight:
  120.             return { p.getX() - object.getWidth(), p.getY(), object.getWidth(), object.getHeight() };
  121.         case Anchor::MidLeft:
  122.             return { p.getX(), p.getY() - object.getHeight() / T(2), object.getWidth(), object.getHeight() };
  123.         case Anchor::MidCenter:
  124.             return { p.getX() - object.getWidth() / T(2), p.getY() - object.getHeight() / T(2), object.getWidth(), object.getHeight() };
  125.         case Anchor::MidRight:
  126.             return { p.getX() - object.getWidth(), p.getY() - object.getHeight() / T(2), object.getWidth(), object.getHeight() };
  127.         case Anchor::BottomLeft:
  128.             return { p.getX(), p.getY() - object.getHeight(), object.getWidth(), object.getHeight() };
  129.         case Anchor::BottomCenter:
  130.             return { p.getX() - object.getWidth() / T(2), p.getY() - object.getHeight(), object.getWidth(), object.getHeight() };
  131.         case Anchor::BottomRight:
  132.             return { p.getX() - object.getWidth(), p.getY() - object.getHeight(), object.getWidth(), object.getHeight() };
  133.         default:
  134.             jassertfalse;
  135.             return {};
  136.         }
  137.     }
  138.  
  139.     template <typename T> static juce::Rectangle<T> fit(const juce::Rectangle<T> & object, const juce::Rectangle<T> & subject, Anchor objectAnchor = Anchor::None, Anchor subjectAnchor = Anchor::None)
  140.     {
  141.         auto deltaWidth = subject.getWidth() - object.getWidth();
  142.         auto deltaHeight = subject.getHeight() - object.getHeight();
  143.  
  144.         auto ratio = object.getAspectRatio();
  145.  
  146.         //juce::Rectangle<float> r;
  147.         //if (deltaWidth < deltaHeight)
  148.         //  r = { object.getWidth() + deltaWidth * ratio, subject.getHeight() };
  149.         //else
  150.         //  r = { subject.getWidth(), object.getHeight() + deltaHeight * ratio };
  151.  
  152.         juce::Rectangle<float> r;
  153.         if (deltaWidth < deltaHeight)
  154.             r = { subject.getWidth(), object.getHeight() + deltaWidth * ratio };
  155.         else
  156.             r = { object.getWidth() + deltaHeight * ratio, subject.getHeight() };
  157.  
  158.         return place(r, subject, objectAnchor, subjectAnchor);
  159.     }
  160.  
  161.     template <typename T> static juce::Rectangle<T> pad(const juce::Rectangle<T> & object, T marginLeft, T marginTop, T marginRight, T marginBottom, Anchor anchor = Anchor::None)
  162.     {
  163.         T x = object.getX() + marginLeft;
  164.         T y = object.getY() + marginTop;
  165.         T w = object.getWidth() - (marginLeft + marginRight);
  166.         T h = object.getHeight() - (marginTop + marginBottom);
  167.  
  168.         return place({ x, y, w, h }, object, anchor, anchor);
  169.     }
  170.  
  171.     template <typename T> static juce::Rectangle<T> pad(const juce::Rectangle<T> & object, T margin, Edge edge, Anchor anchor = Anchor::None)
  172.     {
  173.         switch (edge)
  174.         {
  175.         case Left:
  176.             return pad(object, margin, T(0), T(0), T(0), anchor);
  177.         case Top:
  178.             return pad(object, T(0), margin, T(0), T(0), anchor);
  179.         case Right:
  180.             return pad(object, T(0), T(0), margin, T(0), anchor);
  181.         case Bottom:
  182.             return pad(object, T(0), T(0), T(0), margin, anchor);
  183.         default:
  184.             jassertfalse;
  185.             return {};
  186.         }      
  187.     }
  188.    
  189.     template <typename T> static juce::Rectangle<T> resize(const juce::Rectangle<T> & object, T delta, Anchor anchor = Anchor::None)
  190.     {
  191.         return place({object.getX(), object.getY(), object.getWidth() + delta, object.getHeight() + delta}, object, anchor, anchor);
  192.     }
  193.  
  194.     template <typename T> static juce::Rectangle<T> resize(const juce::Rectangle<T> & object, T deltaWidth, T deltaHeight, Anchor anchor = Anchor::None)
  195.     {
  196.         return place({ object.getWidth() + deltaWidth, object.getHeight() + deltaHeight }, object, anchor, anchor);
  197.     }
  198.  
  199.     template <typename T> static juce::Rectangle<T> resize(const juce::Rectangle<T> & object, T delta, Edge edge)
  200.     {
  201.         switch (edge)
  202.         {
  203.         case Left:
  204.             return place({ object.getWidth() + delta, object.getHeight() }, object, Anchor::MidRight, Anchor::MidRight);
  205.         case Top:
  206.             return place({ object.getWidth(), object.getHeight() + delta }, object, Anchor::BottomCenter, Anchor::BottomCenter);
  207.         case Right:
  208.             return place({ object.getWidth() + delta, object.getHeight() }, object, Anchor::MidLeft, Anchor::MidLeft);
  209.         case Bottom:
  210.             return place({ object.getWidth(), object.getHeight() + delta }, object, Anchor::TopCenter, Anchor::TopCenter);
  211.         default:
  212.             jassertfalse;
  213.             return {};
  214.         }
  215.     }
  216.  
  217.     template <typename T> static juce::Rectangle<T> setSize(const juce::Rectangle<T> & object, T width, T height, Anchor anchor = Anchor::None)
  218.     {
  219.         return place({ width, height }, object, anchor, anchor);
  220.     }
  221.  
  222.     template <typename T> static juce::Rectangle<T> setSize(const juce::Rectangle<T> & object, T squareSize, Anchor anchor = Anchor::None)
  223.     {
  224.         return place({ squareSize, squareSize }, object, anchor, anchor);
  225.     }
  226.  
  227.     template <typename T> static juce::Rectangle<T> setWidth(const juce::Rectangle<T> & object, T width, Anchor anchor = Anchor::None)
  228.     {
  229.         return place({ width, object.getHeight() }, object, anchor, anchor);
  230.     }
  231.  
  232.     template <typename T> static juce::Rectangle<T> setHeight(const juce::Rectangle<T> & object, T height, Anchor anchor = Anchor::None)
  233.     {
  234.         return place({ object.getWidth(), height }, object, anchor, anchor);
  235.     }
  236.  
  237.     template <typename T> static juce::Rectangle<T> scale(const juce::Rectangle<T> & object, T scale, Anchor anchor = Anchor::None)
  238.     {
  239.         return place({ object.getWidth() * scale, object.getHeight() * scale }, object, anchor, anchor);
  240.     }
  241.  
  242.     /*
  243.     Get a rectangle for the space between area1 and area2;
  244.     */
  245.     template <typename T> static juce::Rectangle<T> space(const juce::Rectangle<T> & subject1, const juce::Rectangle<T> & subject2)
  246.     {
  247.         return { subject1.getBottomLeft(), subject2.getTopRight() };
  248.     }
  249. };
Add Comment
Please, Sign In to add comment