1 #include "FloatingWindow.h"
2 #include "plugin/ColorPalette.h"
3 #include "Window.hpp"
4
FloatingWindow(Widget * group,ColorPalette & palette)5 FloatingWindow::FloatingWindow(Widget *group, ColorPalette &palette)
6 : NanoWidget(group),
7 fPalette(palette)
8 {
9 }
10
setMoveLimits(DGL::Point<int> origin,DGL::Size<uint> size)11 void FloatingWindow::setMoveLimits(DGL::Point<int> origin, DGL::Size<uint> size)
12 {
13 fLimitOrigin = origin;
14 fLimitSize = size;
15 }
16
repositionWithinLimits()17 void FloatingWindow::repositionWithinLimits()
18 {
19 setAbsolutePos(restrictWithinLimits(getAbsolutePos()));
20 }
21
moveAlong(Widget * w)22 void FloatingWindow::moveAlong(Widget *w)
23 {
24 DISTRHO_SAFE_ASSERT_RETURN(w != nullptr, );
25
26 fMoveAlong.push_back(w);
27 }
28
setAllVisible(bool visible)29 void FloatingWindow::setAllVisible(bool visible)
30 {
31 setVisible(visible);
32 for (Widget *w : fMoveAlong)
33 w->setVisible(visible);
34 }
35
onNanoDisplay()36 void FloatingWindow::onNanoDisplay()
37 {
38 ColorPalette &cp = fPalette;
39
40 double w = getWidth();
41 double h = getHeight();
42
43 beginPath();
44 roundedRect(0.0, 0.0, w, h, 10.0);
45 fillColor(Colors::fromRGBA8(cp[Colors::floating_window_back]));
46 fill();
47 }
48
onPositionChanged(const PositionChangedEvent & ev)49 void FloatingWindow::onPositionChanged(const PositionChangedEvent &ev)
50 {
51 int dX = ev.pos.getX() - ev.oldPos.getX();
52 int dY = ev.pos.getY() - ev.oldPos.getY();
53
54 for (Widget *w : fMoveAlong) {
55 DGL::Point<int> p = w->getAbsolutePos();
56 p.setX(p.getX() + dX);
57 p.setY(p.getY() + dY);
58 w->setAbsolutePos(p);
59 }
60 }
61
onMouse(const MouseEvent & ev)62 bool FloatingWindow::onMouse(const MouseEvent &ev)
63 {
64 if (ev.press && ev.button == 1) {
65 const int w = getWidth();
66 const int h = getHeight();
67 const int evX = ev.pos.getX();
68 const int evY = ev.pos.getY();
69 const DGL::Point<int> a = getAbsolutePos();
70 const bool inside = evX >= 0 && evX < w && evY >= 0 && evY < h;
71 if (inside) {
72 fIsDragging = true;
73 fDragMouseOrigin = {evX + a.getX(), evY + a.getY()};
74 fDragStartingWindowPos = a;
75 return true;
76 }
77 }
78 else if (!ev.press && ev.button == 1) {
79 if (fIsDragging) {
80 fIsDragging = false;
81 return true;
82 }
83 }
84
85 return false;
86 }
87
onMotion(const MotionEvent & ev)88 bool FloatingWindow::onMotion(const MotionEvent &ev)
89 {
90 if (fIsDragging) {
91 DGL::Point<int> orig = fDragMouseOrigin;
92 int curx = ev.pos.getX() + getAbsoluteX();
93 int cury = ev.pos.getY() + getAbsoluteY();
94 int dx = curx - orig.getX();
95 int dy = cury - orig.getY();
96 DGL::Point<int> a = fDragStartingWindowPos;
97 a += DGL::Point<int>(dx, dy);
98 setAbsolutePos(restrictWithinLimits(a));
99 return true;
100 }
101
102 return false;
103 }
104
restrictWithinLimits(DGL::Point<int> pos)105 DGL::Point<int> FloatingWindow::restrictWithinLimits(DGL::Point<int> pos)
106 {
107 int x = pos.getX();
108 int y = pos.getY();
109 const uint w = getWidth();
110 const uint h = getHeight();
111 const int lx = fLimitOrigin.getX();
112 const int ly = fLimitOrigin.getY();
113 const uint lw = fLimitSize.getWidth();
114 const uint lh = fLimitSize.getHeight();
115
116 if (lw == 0 || lh == 0)
117 return pos;
118
119 x = std::max(lx - (int)(w / 2), std::min(lx + (int)lw - (int)(w / 2), x));
120 y = std::max(ly - (int)(h / 2), std::min(ly + (int)lh - (int)(h / 2), y));
121
122 return DGL::Point<int>(x, y);
123 }
124