Collection of tools useful for audio production
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.

288 lines
7.6KB

  1. /*
  2. * Patchbay Canvas engine using QGraphicsView/Scene
  3. * Copyright (C) 2010-2012 Filipe Coelho <falktx@gmail.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the COPYING file
  16. */
  17. #include "patchscene.h"
  18. #include <cmath>
  19. #include <QtGui/QKeyEvent>
  20. #include <QtGui/QGraphicsRectItem>
  21. #include <QtGui/QGraphicsSceneMouseEvent>
  22. #include <QtGui/QGraphicsSceneWheelEvent>
  23. #include <QtGui/QGraphicsView>
  24. #include "patchcanvas.h"
  25. #include "canvasbox.h"
  26. using namespace PatchCanvas;
  27. PatchScene::PatchScene(QObject* parent, QGraphicsView* view) :
  28. QGraphicsScene(parent)
  29. {
  30. m_ctrl_down = false;
  31. m_mouse_down_init = false;
  32. m_mouse_rubberband = false;
  33. m_rubberband = addRect(QRectF(0, 0, 0, 0));
  34. m_rubberband->setZValue(-1);
  35. m_rubberband->hide();
  36. m_rubberband_selection = false;
  37. m_rubberband_orig_point = QPointF(0, 0);
  38. m_view = view;
  39. if (! m_view)
  40. qFatal("PatchCanvas::PatchScene() - invalid view");
  41. }
  42. void PatchScene::fixScaleFactor()
  43. {
  44. qreal scale = m_view->transform().m11();
  45. if (scale > 3.0)
  46. {
  47. m_view->resetTransform();
  48. m_view->scale(3.0, 3.0);
  49. }
  50. else if (scale < 0.2)
  51. {
  52. m_view->resetTransform();
  53. m_view->scale(0.2, 0.2);
  54. }
  55. emit scaleChanged(m_view->transform().m11());
  56. }
  57. void PatchScene::updateTheme()
  58. {
  59. setBackgroundBrush(canvas.theme->canvas_bg);
  60. m_rubberband->setPen(canvas.theme->rubberband_pen);
  61. m_rubberband->setBrush(canvas.theme->rubberband_brush);
  62. }
  63. void PatchScene::zoom_fit()
  64. {
  65. qreal min_x, min_y, max_x, max_y;
  66. bool first_value = true;
  67. QList<QGraphicsItem*> items_list = items();
  68. if (items_list.count() > 0)
  69. {
  70. foreach (const QGraphicsItem* item, items_list)
  71. {
  72. if (item && item->isVisible() and item->type() == CanvasBoxType)
  73. {
  74. QPointF pos = item->scenePos();
  75. QRectF rect = item->boundingRect();
  76. if (first_value)
  77. min_x = pos.x();
  78. else if (pos.x() < min_x)
  79. min_x = pos.x();
  80. if (first_value)
  81. min_y = pos.y();
  82. else if (pos.y() < min_y)
  83. min_y = pos.y();
  84. if (first_value)
  85. max_x = pos.x()+rect.width();
  86. else if (pos.x()+rect.width() > max_x)
  87. max_x = pos.x()+rect.width();
  88. if (first_value)
  89. max_y = pos.y()+rect.height();
  90. else if (pos.y()+rect.height() > max_y)
  91. max_y = pos.y()+rect.height();
  92. first_value = false;
  93. }
  94. }
  95. m_view->fitInView(min_x, min_y, abs(max_x-min_x), abs(max_y-min_y), Qt::KeepAspectRatio);
  96. fixScaleFactor();
  97. }
  98. }
  99. void PatchScene::zoom_in()
  100. {
  101. if (m_view->transform().m11() < 3.0)
  102. m_view->scale(1.2, 1.2);
  103. emit scaleChanged(m_view->transform().m11());
  104. }
  105. void PatchScene::zoom_out()
  106. {
  107. if (m_view->transform().m11() > 0.2)
  108. m_view->scale(0.8, 0.8);
  109. emit scaleChanged(m_view->transform().m11());
  110. }
  111. void PatchScene::zoom_reset()
  112. {
  113. m_view->resetTransform();
  114. emit scaleChanged(1.0);
  115. }
  116. void PatchScene::keyPressEvent(QKeyEvent* event)
  117. {
  118. if (! m_view)
  119. return event->ignore();
  120. if (event->key() == Qt::Key_Control)
  121. {
  122. m_ctrl_down = true;
  123. }
  124. else if (event->key() == Qt::Key_Home)
  125. {
  126. zoom_fit();
  127. return event->accept();
  128. }
  129. else if (m_ctrl_down)
  130. {
  131. if (event->key() == Qt::Key_Plus)
  132. {
  133. zoom_in();
  134. return event->accept();
  135. }
  136. else if (event->key() == Qt::Key_Minus)
  137. {
  138. zoom_out();
  139. return event->accept();
  140. }
  141. else if (event->key() == Qt::Key_1)
  142. {
  143. zoom_reset();
  144. return event->accept();
  145. }
  146. }
  147. QGraphicsScene::keyPressEvent(event);
  148. }
  149. void PatchScene::keyReleaseEvent(QKeyEvent* event)
  150. {
  151. if (event->key() == Qt::Key_Control)
  152. m_ctrl_down = false;
  153. QGraphicsScene::keyReleaseEvent(event);
  154. }
  155. void PatchScene::mousePressEvent(QGraphicsSceneMouseEvent* event)
  156. {
  157. m_mouse_down_init = (event->button() == Qt::LeftButton);
  158. m_mouse_rubberband = false;
  159. QGraphicsScene::mousePressEvent(event);
  160. }
  161. void PatchScene::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
  162. {
  163. if (m_mouse_down_init)
  164. {
  165. m_mouse_down_init = false;
  166. m_mouse_rubberband = (selectedItems().count() == 0);
  167. }
  168. if (m_mouse_rubberband)
  169. {
  170. if (m_rubberband_selection == false)
  171. {
  172. m_rubberband->show();
  173. m_rubberband_selection = true;
  174. m_rubberband_orig_point = event->scenePos();
  175. }
  176. int x, y;
  177. QPointF pos = event->scenePos();
  178. if (pos.x() > m_rubberband_orig_point.x())
  179. x = m_rubberband_orig_point.x();
  180. else
  181. x = pos.x();
  182. if (pos.y() > m_rubberband_orig_point.y())
  183. y = m_rubberband_orig_point.y();
  184. else
  185. y = pos.y();
  186. m_rubberband->setRect(x, y, abs(pos.x()-m_rubberband_orig_point.x()), abs(pos.y()-m_rubberband_orig_point.y()));
  187. return event->accept();
  188. }
  189. QGraphicsScene::mouseMoveEvent(event);
  190. }
  191. void PatchScene::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
  192. {
  193. if (m_rubberband_selection)
  194. {
  195. QList<QGraphicsItem*> items_list = items();
  196. if (items_list.count() > 0)
  197. {
  198. foreach (QGraphicsItem* item, items_list)
  199. {
  200. if (item && item->isVisible() && item->type() == CanvasBoxType)
  201. {
  202. QRectF item_rect = item->sceneBoundingRect();
  203. QPointF item_top_left = QPointF(item_rect.x(), item_rect.y());
  204. QPointF item_bottom_right = QPointF(item_rect.x()+item_rect.width(), item_rect.y()+item_rect.height());
  205. if (m_rubberband->contains(item_top_left) && m_rubberband->contains(item_bottom_right))
  206. item->setSelected(true);
  207. }
  208. }
  209. m_rubberband->hide();
  210. m_rubberband->setRect(0, 0, 0, 0);
  211. m_rubberband_selection = false;
  212. }
  213. }
  214. else
  215. {
  216. QList<QGraphicsItem*> items_list = selectedItems();
  217. foreach (QGraphicsItem* item, items_list)
  218. {
  219. if (item && item->isVisible() && item->type() == CanvasBoxType)
  220. {
  221. CanvasBox* citem = (CanvasBox*)item;
  222. citem->checkItemPos();
  223. emit sceneGroupMoved(citem->getGroupId(), citem->getSplittedMode(), citem->scenePos());
  224. }
  225. }
  226. if (items_list.count() > 1)
  227. canvas.scene->update();
  228. }
  229. m_mouse_down_init = false;
  230. m_mouse_rubberband = false;
  231. QGraphicsScene::mouseReleaseEvent(event);
  232. }
  233. void PatchScene::wheelEvent(QGraphicsSceneWheelEvent* event)
  234. {
  235. if (! m_view)
  236. return event->ignore();
  237. if (m_ctrl_down)
  238. {
  239. double factor = std::pow(1.41, (event->delta()/240.0));
  240. m_view->scale(factor, factor);
  241. fixScaleFactor();
  242. return event->accept();
  243. }
  244. QGraphicsScene::wheelEvent(event);
  245. }