base.h 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /* base.h - base for tools that support zooming & panning
  2. * Copyright (C) 2017 caryoscelus
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #ifndef STUDIO_CANVAS_TOOLS_BASE_H_BC869E8B_6486_5669_8027_CE9D9EDF4C90
  18. #define STUDIO_CANVAS_TOOLS_BASE_H_BC869E8B_6486_5669_8027_CE9D9EDF4C90
  19. #include <QWheelEvent>
  20. #include <QMouseEvent>
  21. #include <QDebug>
  22. #include <canvas/tool.h>
  23. #include <widgets/canvas.h>
  24. namespace rainynite::studio::tools {
  25. class Base : public CanvasTool {
  26. public:
  27. bool canvas_event(QEvent* event) override {
  28. if (get_canvas() == nullptr)
  29. return false;
  30. if (auto wheel_event = dynamic_cast<QWheelEvent*>(event)) {
  31. auto scale_factor = std::pow(2, wheel_event->angleDelta().y() / 256.0);
  32. get_canvas()->zoom_at(wheel_event->pos(), scale_factor);
  33. return true;
  34. }
  35. if (auto mouse_event = dynamic_cast<QMouseEvent*>(event)) {
  36. auto delta = mouse_event->pos() - scroll_pos;
  37. scroll_pos = mouse_event->pos();
  38. if (is_scrolling) {
  39. get_canvas()->scroll_by(delta);
  40. } else if (is_zooming) {
  41. auto scale_factor = std::pow(2, -delta.y() / 64.0);
  42. get_canvas()->zoom_at(zoom_pos, scale_factor);
  43. }
  44. switch (mouse_event->type()) {
  45. case QEvent::MouseButtonPress: {
  46. if (is_scrolling || is_zooming) {
  47. // this shouldn't really happen, but just in case
  48. break;
  49. }
  50. if (mouse_event->button() == Qt::MidButton) {
  51. if (mouse_event->modifiers().testFlag(Qt::ControlModifier)) {
  52. is_zooming = true;
  53. zoom_pos = mouse_event->pos();
  54. } else {
  55. is_scrolling = true;
  56. }
  57. }
  58. } break;
  59. case QEvent::MouseButtonRelease: {
  60. if (mouse_event->button() == Qt::MidButton)
  61. is_zooming = is_scrolling = false;
  62. } break;
  63. default:
  64. break;
  65. }
  66. }
  67. return is_scrolling || is_zooming;
  68. }
  69. private:
  70. bool is_scrolling = false;
  71. bool is_zooming = false;
  72. QPoint scroll_pos;
  73. QPoint zoom_pos;
  74. };
  75. } // namespace rainynite::studio::tools
  76. #endif