Collection of DPF-based plugins for packaging
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

685 lines
18KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any purpose with
  6. * or without fee is hereby granted, provided that the above copyright notice and this
  7. * permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
  10. * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
  11. * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  12. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
  13. * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include "../EventHandlers.hpp"
  17. #include "../SubWidget.hpp"
  18. START_NAMESPACE_DGL
  19. // --------------------------------------------------------------------------------------------------------------------
  20. struct ButtonEventHandler::PrivateData {
  21. ButtonEventHandler* const self;
  22. SubWidget* const widget;
  23. ButtonEventHandler::Callback* internalCallback;
  24. ButtonEventHandler::Callback* userCallback;
  25. int button;
  26. int state;
  27. bool checkable;
  28. bool checked;
  29. Point<double> lastClickPos;
  30. Point<double> lastMotionPos;
  31. PrivateData(ButtonEventHandler* const s, SubWidget* const w)
  32. : self(s),
  33. widget(w),
  34. internalCallback(nullptr),
  35. userCallback(nullptr),
  36. button(-1),
  37. state(kButtonStateDefault),
  38. checkable(false),
  39. checked(false),
  40. lastClickPos(0, 0),
  41. lastMotionPos(0, 0) {}
  42. bool mouseEvent(const Widget::MouseEvent& ev)
  43. {
  44. lastClickPos = ev.pos;
  45. // button was released, handle it now
  46. if (button != -1 && ! ev.press)
  47. {
  48. DISTRHO_SAFE_ASSERT(state & kButtonStateActive);
  49. // release button
  50. const int button2 = button;
  51. button = -1;
  52. const int state2 = state;
  53. state &= ~kButtonStateActive;
  54. self->stateChanged(static_cast<State>(state), static_cast<State>(state2));
  55. widget->repaint();
  56. // cursor was moved outside the button bounds, ignore click
  57. if (! widget->contains(ev.pos))
  58. return true;
  59. // still on bounds, register click
  60. if (checkable)
  61. checked = !checked;
  62. if (internalCallback != nullptr)
  63. internalCallback->buttonClicked(widget, button2);
  64. else if (userCallback != nullptr)
  65. userCallback->buttonClicked(widget, button2);
  66. return true;
  67. }
  68. // button was pressed, wait for release
  69. if (ev.press && widget->contains(ev.pos))
  70. {
  71. const int state2 = state;
  72. button = static_cast<int>(ev.button);
  73. state |= kButtonStateActive;
  74. self->stateChanged(static_cast<State>(state), static_cast<State>(state2));
  75. widget->repaint();
  76. return true;
  77. }
  78. return false;
  79. }
  80. bool motionEvent(const Widget::MotionEvent& ev)
  81. {
  82. // keep pressed
  83. if (button != -1)
  84. {
  85. lastMotionPos = ev.pos;
  86. return true;
  87. }
  88. bool ret = false;
  89. if (widget->contains(ev.pos))
  90. {
  91. // check if entering hover
  92. if ((state & kButtonStateHover) == 0x0)
  93. {
  94. const int state2 = state;
  95. state |= kButtonStateHover;
  96. ret = widget->contains(lastMotionPos);
  97. self->stateChanged(static_cast<State>(state), static_cast<State>(state2));
  98. widget->repaint();
  99. }
  100. }
  101. else
  102. {
  103. // check if exiting hover
  104. if (state & kButtonStateHover)
  105. {
  106. const int state2 = state;
  107. state &= ~kButtonStateHover;
  108. ret = widget->contains(lastMotionPos);
  109. self->stateChanged(static_cast<State>(state), static_cast<State>(state2));
  110. widget->repaint();
  111. }
  112. }
  113. lastMotionPos = ev.pos;
  114. return ret;
  115. }
  116. void setActive(const bool active2, const bool sendCallback) noexcept
  117. {
  118. const bool active = state & kButtonStateActive;
  119. if (active == active2)
  120. return;
  121. state |= kButtonStateActive;
  122. widget->repaint();
  123. if (sendCallback)
  124. {
  125. if (internalCallback != nullptr)
  126. internalCallback->buttonClicked(widget, -1);
  127. else if (userCallback != nullptr)
  128. userCallback->buttonClicked(widget, -1);
  129. }
  130. }
  131. void setChecked(const bool checked2, const bool sendCallback) noexcept
  132. {
  133. if (checked == checked2)
  134. return;
  135. checked = checked2;
  136. widget->repaint();
  137. if (sendCallback)
  138. {
  139. if (internalCallback != nullptr)
  140. internalCallback->buttonClicked(widget, -1);
  141. else if (userCallback != nullptr)
  142. userCallback->buttonClicked(widget, -1);
  143. }
  144. }
  145. DISTRHO_DECLARE_NON_COPYABLE(PrivateData)
  146. };
  147. // --------------------------------------------------------------------------------------------------------------------
  148. ButtonEventHandler::ButtonEventHandler(SubWidget* const self)
  149. : pData(new PrivateData(this, self)) {}
  150. ButtonEventHandler::~ButtonEventHandler()
  151. {
  152. delete pData;
  153. }
  154. bool ButtonEventHandler::isActive() noexcept
  155. {
  156. return pData->state & kButtonStateActive;
  157. }
  158. void ButtonEventHandler::setActive(const bool active, const bool sendCallback) noexcept
  159. {
  160. pData->setActive(active, sendCallback);
  161. }
  162. bool ButtonEventHandler::isChecked() const noexcept
  163. {
  164. return pData->checked;
  165. }
  166. void ButtonEventHandler::setChecked(const bool checked, const bool sendCallback) noexcept
  167. {
  168. pData->setChecked(checked, sendCallback);
  169. }
  170. bool ButtonEventHandler::isCheckable() const noexcept
  171. {
  172. return pData->checkable;
  173. }
  174. void ButtonEventHandler::setCheckable(const bool checkable) noexcept
  175. {
  176. if (pData->checkable == checkable)
  177. return;
  178. pData->checkable = checkable;
  179. }
  180. Point<double> ButtonEventHandler::getLastClickPosition() const noexcept
  181. {
  182. return pData->lastClickPos;
  183. }
  184. Point<double> ButtonEventHandler::getLastMotionPosition() const noexcept
  185. {
  186. return pData->lastMotionPos;
  187. }
  188. void ButtonEventHandler::setCallback(Callback* const callback) noexcept
  189. {
  190. pData->userCallback = callback;
  191. }
  192. bool ButtonEventHandler::mouseEvent(const Widget::MouseEvent& ev)
  193. {
  194. return pData->mouseEvent(ev);
  195. }
  196. bool ButtonEventHandler::motionEvent(const Widget::MotionEvent& ev)
  197. {
  198. return pData->motionEvent(ev);
  199. }
  200. ButtonEventHandler::State ButtonEventHandler::getState() const noexcept
  201. {
  202. return static_cast<State>(pData->state);
  203. }
  204. void ButtonEventHandler::clearState() noexcept
  205. {
  206. pData->state = kButtonStateDefault;
  207. }
  208. void ButtonEventHandler::stateChanged(State, State)
  209. {
  210. }
  211. void ButtonEventHandler::setInternalCallback(Callback* const callback) noexcept
  212. {
  213. pData->internalCallback = callback;
  214. }
  215. void ButtonEventHandler::triggerUserCallback(SubWidget* const widget, const int button)
  216. {
  217. if (pData->userCallback != nullptr)
  218. pData->userCallback->buttonClicked(widget, button);
  219. }
  220. // --------------------------------------------------------------------------------------------------------------------
  221. struct KnobEventHandler::PrivateData {
  222. KnobEventHandler* const self;
  223. SubWidget* const widget;
  224. KnobEventHandler::Callback* callback;
  225. float accel;
  226. float minimum;
  227. float maximum;
  228. float step;
  229. float value;
  230. float valueDef;
  231. float valueTmp;
  232. bool usingDefault;
  233. bool usingLog;
  234. Orientation orientation;
  235. int state;
  236. double lastX;
  237. double lastY;
  238. uint lastClickTime;
  239. PrivateData(KnobEventHandler* const s, SubWidget* const w)
  240. : self(s),
  241. widget(w),
  242. callback(nullptr),
  243. accel(200.f),
  244. minimum(0.f),
  245. maximum(1.f),
  246. step(0.0f),
  247. value(0.5f),
  248. valueDef(value),
  249. valueTmp(value),
  250. usingDefault(false),
  251. usingLog(false),
  252. orientation(Vertical),
  253. state(kKnobStateDefault),
  254. lastX(0.0),
  255. lastY(0.0),
  256. lastClickTime(0) {}
  257. PrivateData(KnobEventHandler* const s, SubWidget* const w, PrivateData* const other)
  258. : self(s),
  259. widget(w),
  260. callback(other->callback),
  261. accel(other->accel),
  262. minimum(other->minimum),
  263. maximum(other->maximum),
  264. step(other->step),
  265. value(other->value),
  266. valueDef(other->valueDef),
  267. valueTmp(value),
  268. usingDefault(other->usingDefault),
  269. usingLog(other->usingLog),
  270. orientation(other->orientation),
  271. state(kKnobStateDefault),
  272. lastX(0.0),
  273. lastY(0.0),
  274. lastClickTime(0) {}
  275. void assignFrom(PrivateData* const other)
  276. {
  277. callback = other->callback;
  278. accel = other->accel;
  279. minimum = other->minimum;
  280. maximum = other->maximum;
  281. step = other->step;
  282. value = other->value;
  283. valueDef = other->valueDef;
  284. valueTmp = value;
  285. usingDefault = other->usingDefault;
  286. usingLog = other->usingLog;
  287. orientation = other->orientation;
  288. state = kKnobStateDefault;
  289. lastX = 0.0;
  290. lastY = 0.0;
  291. lastClickTime = 0;
  292. }
  293. inline float logscale(const float v) const
  294. {
  295. const float b = std::log(maximum/minimum)/(maximum-minimum);
  296. const float a = maximum/std::exp(maximum*b);
  297. return a * std::exp(b*v);
  298. }
  299. inline float invlogscale(const float v) const
  300. {
  301. const float b = std::log(maximum/minimum)/(maximum-minimum);
  302. const float a = maximum/std::exp(maximum*b);
  303. return std::log(v/a)/b;
  304. }
  305. bool mouseEvent(const Widget::MouseEvent& ev, const double scaleFactor)
  306. {
  307. if (ev.button != 1)
  308. return false;
  309. if (ev.press)
  310. {
  311. if (! widget->contains(ev.pos))
  312. return false;
  313. if ((ev.mod & kModifierShift) != 0 && usingDefault)
  314. {
  315. setValue(valueDef, true);
  316. valueTmp = value;
  317. return true;
  318. }
  319. lastX = ev.pos.getX() / scaleFactor;
  320. lastY = ev.pos.getY() / scaleFactor;
  321. if (lastClickTime > 0 && ev.time > lastClickTime && ev.time - lastClickTime <= 300)
  322. {
  323. lastClickTime = 0;
  324. if (callback != nullptr)
  325. callback->knobDoubleClicked(widget);
  326. return true;
  327. }
  328. lastClickTime = ev.time;
  329. state |= kKnobStateDragging;
  330. widget->repaint();
  331. if (callback != nullptr)
  332. callback->knobDragStarted(widget);
  333. return true;
  334. }
  335. else if (state & kKnobStateDragging)
  336. {
  337. state &= ~kKnobStateDragging;
  338. widget->repaint();
  339. if (callback != nullptr)
  340. callback->knobDragFinished(widget);
  341. return true;
  342. }
  343. return false;
  344. }
  345. bool motionEvent(const Widget::MotionEvent& ev, const double scaleFactor)
  346. {
  347. if ((state & kKnobStateDragging) == 0x0)
  348. return false;
  349. float movDiff;
  350. switch (orientation)
  351. {
  352. case Horizontal:
  353. movDiff = ev.pos.getX() / scaleFactor - lastX;
  354. break;
  355. case Vertical:
  356. movDiff = lastY - ev.pos.getY() / scaleFactor;
  357. break;
  358. case Both:
  359. {
  360. const float movDiffX = ev.pos.getX() / scaleFactor - lastX;
  361. const float movDiffY = lastY - ev.pos.getY() / scaleFactor;
  362. movDiff = std::abs(movDiffX) > std::abs(movDiffY) ? movDiffX : movDiffY;
  363. }
  364. break;
  365. default:
  366. return false;
  367. }
  368. if (d_isZero(movDiff))
  369. return false;
  370. const float divisor = (ev.mod & kModifierControl) ? accel * 10.f : accel;
  371. valueTmp += (maximum - minimum) / divisor * movDiff;
  372. if (usingLog)
  373. valueTmp = logscale(valueTmp);
  374. float value2;
  375. bool valueChanged = false;
  376. if (valueTmp < minimum)
  377. {
  378. valueTmp = value2 = minimum;
  379. valueChanged = true;
  380. }
  381. else if (valueTmp > maximum)
  382. {
  383. valueTmp = value2 = maximum;
  384. valueChanged = true;
  385. }
  386. else
  387. {
  388. if (d_isNotZero(step))
  389. {
  390. if (std::abs(valueTmp - value) >= step)
  391. {
  392. const float rest = std::fmod(valueTmp, step);
  393. valueChanged = true;
  394. value2 = valueTmp - rest;
  395. if (rest < 0 && rest < step * -0.5f)
  396. value2 -= step;
  397. else if (rest > 0 && rest > step * 0.5f)
  398. value2 += step;
  399. if (value2 < minimum)
  400. value2 = minimum;
  401. else if (value2 > maximum)
  402. value2 = maximum;
  403. }
  404. }
  405. else
  406. {
  407. value2 = valueTmp;
  408. valueChanged = true;
  409. }
  410. }
  411. if (valueChanged)
  412. setValue(value2, true);
  413. lastX = ev.pos.getX() / scaleFactor;
  414. lastY = ev.pos.getY() / scaleFactor;
  415. return true;
  416. }
  417. bool scrollEvent(const Widget::ScrollEvent& ev)
  418. {
  419. if (! widget->contains(ev.pos))
  420. return false;
  421. const float dir = (ev.delta.getY() > 0.f) ? 1.f : -1.f;
  422. const float d = (ev.mod & kModifierControl) ? accel * 10.f : accel;
  423. float value2 = (usingLog ? invlogscale(valueTmp) : valueTmp)
  424. + ((maximum - minimum) / d * 10.f * dir);
  425. if (usingLog)
  426. value2 = logscale(value2);
  427. if (value2 < minimum)
  428. {
  429. valueTmp = value2 = minimum;
  430. }
  431. else if (value2 > maximum)
  432. {
  433. valueTmp = value2 = maximum;
  434. }
  435. else
  436. {
  437. valueTmp = value2;
  438. if (d_isNotZero(step))
  439. {
  440. const float rest = std::fmod(value2, step);
  441. value2 = value2 - rest + (rest > step/2.0f ? step : 0.0f);
  442. }
  443. }
  444. setValue(value2, true);
  445. return true;
  446. }
  447. float getNormalizedValue() const noexcept
  448. {
  449. const float diff = maximum - minimum;
  450. return ((usingLog ? invlogscale(value) : value) - minimum) / diff;
  451. }
  452. void setRange(const float min, const float max) noexcept
  453. {
  454. DISTRHO_SAFE_ASSERT_RETURN(max > min,);
  455. if (value < min)
  456. {
  457. valueTmp = value = min;
  458. widget->repaint();
  459. }
  460. else if (value > max)
  461. {
  462. valueTmp = value = max;
  463. widget->repaint();
  464. }
  465. minimum = min;
  466. maximum = max;
  467. }
  468. bool setValue(const float value2, const bool sendCallback)
  469. {
  470. if (d_isEqual(value, value2))
  471. return false;
  472. valueTmp = value = value2;
  473. widget->repaint();
  474. if (sendCallback && callback != nullptr)
  475. {
  476. try {
  477. callback->knobValueChanged(widget, value);
  478. } DISTRHO_SAFE_EXCEPTION("KnobEventHandler::setValue");
  479. }
  480. return true;
  481. }
  482. };
  483. // --------------------------------------------------------------------------------------------------------------------
  484. KnobEventHandler::KnobEventHandler(SubWidget* const self)
  485. : pData(new PrivateData(this, self)) {}
  486. KnobEventHandler::KnobEventHandler(SubWidget* const self, const KnobEventHandler& other)
  487. : pData(new PrivateData(this, self, other.pData)) {}
  488. KnobEventHandler& KnobEventHandler::operator=(const KnobEventHandler& other)
  489. {
  490. pData->assignFrom(other.pData);
  491. return *this;
  492. }
  493. KnobEventHandler::~KnobEventHandler()
  494. {
  495. delete pData;
  496. }
  497. bool KnobEventHandler::isInteger() const noexcept
  498. {
  499. return d_isEqual(pData->step, 1.f);
  500. }
  501. float KnobEventHandler::getValue() const noexcept
  502. {
  503. return pData->value;
  504. }
  505. bool KnobEventHandler::setValue(const float value, const bool sendCallback) noexcept
  506. {
  507. return pData->setValue(value, sendCallback);
  508. }
  509. float KnobEventHandler::getNormalizedValue() const noexcept
  510. {
  511. return pData->getNormalizedValue();
  512. }
  513. void KnobEventHandler::setDefault(const float def) noexcept
  514. {
  515. pData->valueDef = def;
  516. pData->usingDefault = true;
  517. }
  518. void KnobEventHandler::setRange(const float min, const float max) noexcept
  519. {
  520. pData->setRange(min, max);
  521. }
  522. void KnobEventHandler::setStep(const float step) noexcept
  523. {
  524. pData->step = step;
  525. }
  526. void KnobEventHandler::setUsingLogScale(const bool yesNo) noexcept
  527. {
  528. pData->usingLog = yesNo;
  529. }
  530. KnobEventHandler::Orientation KnobEventHandler::getOrientation() const noexcept
  531. {
  532. return pData->orientation;
  533. }
  534. void KnobEventHandler::setOrientation(const Orientation orientation) noexcept
  535. {
  536. pData->orientation = orientation;
  537. }
  538. void KnobEventHandler::setCallback(Callback* const callback) noexcept
  539. {
  540. pData->callback = callback;
  541. }
  542. void KnobEventHandler::setMouseDeceleration(float accel) noexcept
  543. {
  544. pData->accel = accel;
  545. }
  546. bool KnobEventHandler::mouseEvent(const Widget::MouseEvent& ev, const double scaleFactor)
  547. {
  548. return pData->mouseEvent(ev, scaleFactor);
  549. }
  550. bool KnobEventHandler::motionEvent(const Widget::MotionEvent& ev, const double scaleFactor)
  551. {
  552. return pData->motionEvent(ev, scaleFactor);
  553. }
  554. bool KnobEventHandler::scrollEvent(const Widget::ScrollEvent& ev)
  555. {
  556. return pData->scrollEvent(ev);
  557. }
  558. KnobEventHandler::State KnobEventHandler::getState() const noexcept
  559. {
  560. return static_cast<State>(pData->state);
  561. }
  562. // --------------------------------------------------------------------------------------------------------------------
  563. END_NAMESPACE_DGL