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.

291 lines
7.7KB

  1. /*
  2. * Patchbay Canvas engine using QGraphicsView/Scene
  3. * Copyright (C) 2010-2012 Filipe Coelho <falktx@falktx.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/patchcanvas.h"
  25. #include "patchcanvas/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. if (first_value == false)
  96. {
  97. m_view->fitInView(min_x, min_y, abs(max_x-min_x), abs(max_y-min_y), Qt::KeepAspectRatio);
  98. fixScaleFactor();
  99. }
  100. }
  101. }
  102. void PatchScene::zoom_in()
  103. {
  104. if (m_view->transform().m11() < 3.0)
  105. m_view->scale(1.2, 1.2);
  106. emit scaleChanged(m_view->transform().m11());
  107. }
  108. void PatchScene::zoom_out()
  109. {
  110. if (m_view->transform().m11() > 0.2)
  111. m_view->scale(0.8, 0.8);
  112. emit scaleChanged(m_view->transform().m11());
  113. }
  114. void PatchScene::zoom_reset()
  115. {
  116. m_view->resetTransform();
  117. emit scaleChanged(1.0);
  118. }
  119. void PatchScene::keyPressEvent(QKeyEvent* event)
  120. {
  121. if (! m_view)
  122. return event->ignore();
  123. if (event->key() == Qt::Key_Control)
  124. {
  125. m_ctrl_down = true;
  126. }
  127. else if (event->key() == Qt::Key_Home)
  128. {
  129. zoom_fit();
  130. return event->accept();
  131. }
  132. else if (m_ctrl_down)
  133. {
  134. if (event->key() == Qt::Key_Plus)
  135. {
  136. zoom_in();
  137. return event->accept();
  138. }
  139. else if (event->key() == Qt::Key_Minus)
  140. {
  141. zoom_out();
  142. return event->accept();
  143. }
  144. else if (event->key() == Qt::Key_1)
  145. {
  146. zoom_reset();
  147. return event->accept();
  148. }
  149. }
  150. QGraphicsScene::keyPressEvent(event);
  151. }
  152. void PatchScene::keyReleaseEvent(QKeyEvent* event)
  153. {
  154. if (event->key() == Qt::Key_Control)
  155. m_ctrl_down = false;
  156. QGraphicsScene::keyReleaseEvent(event);
  157. }
  158. void PatchScene::mousePressEvent(QGraphicsSceneMouseEvent* event)
  159. {
  160. m_mouse_down_init = (event->button() == Qt::LeftButton);
  161. m_mouse_rubberband = false;
  162. QGraphicsScene::mousePressEvent(event);
  163. }
  164. void PatchScene::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
  165. {
  166. if (m_mouse_down_init)
  167. {
  168. m_mouse_down_init = false;
  169. m_mouse_rubberband = (selectedItems().count() == 0);
  170. }
  171. if (m_mouse_rubberband)
  172. {
  173. if (m_rubberband_selection == false)
  174. {
  175. m_rubberband->show();
  176. m_rubberband_selection = true;
  177. m_rubberband_orig_point = event->scenePos();
  178. }
  179. int x, y;
  180. QPointF pos = event->scenePos();
  181. if (pos.x() > m_rubberband_orig_point.x())
  182. x = m_rubberband_orig_point.x();
  183. else
  184. x = pos.x();
  185. if (pos.y() > m_rubberband_orig_point.y())
  186. y = m_rubberband_orig_point.y();
  187. else
  188. y = pos.y();
  189. m_rubberband->setRect(x, y, abs(pos.x()-m_rubberband_orig_point.x()), abs(pos.y()-m_rubberband_orig_point.y()));
  190. return event->accept();
  191. }
  192. QGraphicsScene::mouseMoveEvent(event);
  193. }
  194. void PatchScene::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
  195. {
  196. if (m_rubberband_selection)
  197. {
  198. QList<QGraphicsItem*> items_list = items();
  199. if (items_list.count() > 0)
  200. {
  201. foreach (QGraphicsItem* item, items_list)
  202. {
  203. if (item && item->isVisible() && item->type() == CanvasBoxType)
  204. {
  205. QRectF item_rect = item->sceneBoundingRect();
  206. QPointF item_top_left = QPointF(item_rect.x(), item_rect.y());
  207. QPointF item_bottom_right = QPointF(item_rect.x()+item_rect.width(), item_rect.y()+item_rect.height());
  208. if (m_rubberband->contains(item_top_left) && m_rubberband->contains(item_bottom_right))
  209. item->setSelected(true);
  210. }
  211. }
  212. m_rubberband->hide();
  213. m_rubberband->setRect(0, 0, 0, 0);
  214. m_rubberband_selection = false;
  215. }
  216. }
  217. else
  218. {
  219. QList<QGraphicsItem*> items_list = selectedItems();
  220. foreach (QGraphicsItem* item, items_list)
  221. {
  222. if (item && item->isVisible() && item->type() == CanvasBoxType)
  223. {
  224. CanvasBox* citem = (CanvasBox*)item;
  225. citem->checkItemPos();
  226. emit sceneGroupMoved(citem->getGroupId(), citem->getSplittedMode(), citem->scenePos());
  227. }
  228. }
  229. if (items_list.count() > 1)
  230. canvas.scene->update();
  231. }
  232. m_mouse_down_init = false;
  233. m_mouse_rubberband = false;
  234. QGraphicsScene::mouseReleaseEvent(event);
  235. }
  236. void PatchScene::wheelEvent(QGraphicsSceneWheelEvent* event)
  237. {
  238. if (! m_view)
  239. return event->ignore();
  240. if (m_ctrl_down)
  241. {
  242. double factor = std::pow(1.41, (event->delta()/240.0));
  243. m_view->scale(factor, factor);
  244. fixScaleFactor();
  245. return event->accept();
  246. }
  247. QGraphicsScene::wheelEvent(event);
  248. }