CmQtEditorWindow.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. #include "CmQtEditorWindow.h"
  2. #include <QtWidgets/QTabWidget>
  3. #include <QtWidgets/QPushButton>
  4. #include <QtWidgets/QLayout>
  5. #include <QtWidgets/QLabel>
  6. #include <QtWidgets/QApplication>
  7. #include <QtGui/QMouseEvent>
  8. #include <QtGui/QPainter>
  9. #include <QtCore/QTimer>
  10. #include "CmDebug.h"
  11. #include "CmWindowDockManager.h"
  12. namespace CamelotEditor
  13. {
  14. QtEditorWindow::QtEditorWindow(QWidget* parent, const QString& title)
  15. :QWidget(parent), mResizeMode(RM_NONE), mMoveMode(false), mIsDocked(false)
  16. {
  17. setupUi(title);
  18. }
  19. void QtEditorWindow::setupUi(QString title)
  20. {
  21. setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
  22. //setAttribute(Qt::WA_NoBackground, true);
  23. //setAutoFillBackground(false);
  24. //
  25. mTimer = new QTimer(this);
  26. /************************************************************************/
  27. /* TITLE BAR */
  28. /************************************************************************/
  29. mTitleBar = new QWidget(this);
  30. mTitleBar->setMouseTracking(true);
  31. mLblTitle = new QLabel(this);
  32. mLblTitle->setAttribute(Qt::WA_TransparentForMouseEvents);
  33. mBtnClose = new QPushButton(this);
  34. QHBoxLayout* titleLayout = new QHBoxLayout(this);
  35. titleLayout->setMargin(0);
  36. titleLayout->addWidget(mLblTitle, 1);
  37. titleLayout->addWidget(mBtnClose);
  38. mTitleBar->setLayout(titleLayout);
  39. /************************************************************************/
  40. /* CENTRAL LAYOUT */
  41. /************************************************************************/
  42. mCentralWidget = new QWidget(this);
  43. mContentWidget = new QWidget(this);
  44. QVBoxLayout* centralLayout = new QVBoxLayout(this);
  45. centralLayout->setMargin(0);
  46. centralLayout->addWidget(mCentralWidget);
  47. setLayout(centralLayout);
  48. QVBoxLayout* mainLayout = new QVBoxLayout(this);
  49. mainLayout->setMargin(0);
  50. mainLayout->setContentsMargins(2, 0, 2, 2);
  51. mainLayout->setSpacing(0);
  52. mainLayout->addWidget(mTitleBar);
  53. mainLayout->addWidget(mContentWidget, 1);
  54. mCentralWidget->setLayout(mainLayout);
  55. setObjectNames();
  56. retranslateUi(title);
  57. setupSignals();
  58. }
  59. void QtEditorWindow::setupSignals()
  60. {
  61. connect(mBtnClose, SIGNAL(clicked()), this, SLOT(closeWindow()));
  62. connect(mTimer, SIGNAL(timeout()), this, SLOT(timerUpdate()));
  63. }
  64. void QtEditorWindow::retranslateUi(QString title)
  65. {
  66. mLblTitle->setText(title);
  67. mBtnClose->setText(tr("Close"));
  68. }
  69. void QtEditorWindow::setObjectNames()
  70. {
  71. mTitleBar->setObjectName(QStringLiteral("TitleBar"));
  72. mLblTitle->setObjectName(QStringLiteral("LblTitle"));
  73. mBtnClose->setObjectName(QStringLiteral("BtnClose"));
  74. mCentralWidget->setObjectName(QStringLiteral("CentralWidget"));
  75. mContentWidget->setObjectName(QStringLiteral("ContentWidget"));
  76. }
  77. QSizePolicy QtEditorWindow::sizePolicy() const
  78. {
  79. return QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  80. }
  81. void QtEditorWindow::undock()
  82. {
  83. if(mIsDocked)
  84. {
  85. setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
  86. mIsDocked = false;
  87. }
  88. }
  89. void QtEditorWindow::dock()
  90. {
  91. if(!mIsDocked)
  92. {
  93. setWindowFlags(Qt::Widget);
  94. mIsDocked = true;
  95. }
  96. }
  97. void QtEditorWindow::enterEvent(QEvent *e)
  98. {
  99. mTimer->start(100);
  100. }
  101. void QtEditorWindow::leaveEvent(QEvent *e)
  102. {
  103. mTimer->stop();
  104. }
  105. void QtEditorWindow::mousePressEvent(QMouseEvent* event)
  106. {
  107. if(event->buttons() & Qt::LeftButton)
  108. {
  109. if(isOverResizeArea(event->globalPos()))
  110. {
  111. //setUpdatesEnabled(false);
  112. mResizeMode = getResizeMode(event->globalPos());
  113. }
  114. else if(isOverDragArea(event->globalPos()))
  115. {
  116. mMoveMode = true;
  117. QPoint globalTopLeft = mapToGlobal(QPoint(0, 0));
  118. mDragOffset = QPoint(globalTopLeft.x() - event->globalPos().x(), globalTopLeft.y() - event->globalPos().y());
  119. }
  120. event->accept();
  121. }
  122. QWidget::mousePressEvent(event);
  123. }
  124. void QtEditorWindow::mouseReleaseEvent(QMouseEvent* event)
  125. {
  126. if(mMoveMode)
  127. {
  128. gWindowDockManager().windowReleased(this, event->globalPos());
  129. }
  130. mMoveMode = false;
  131. mResizeMode = RM_NONE;
  132. //setUpdatesEnabled(true);
  133. QWidget::mouseReleaseEvent(event);
  134. }
  135. void QtEditorWindow::mouseMoveEvent(QMouseEvent* event)
  136. {
  137. if(mMoveMode)
  138. {
  139. QPoint globalPos = mapToGlobal(event->pos());
  140. gWindowDockManager().windowDragged(this, globalPos);
  141. if(!mIsDocked)
  142. move(event->globalPos() + mDragOffset);
  143. event->accept();
  144. }
  145. else if(mResizeMode != RM_NONE)
  146. {
  147. if(!isDocked())
  148. {
  149. int left = geometry().left();
  150. int width = geometry().width();
  151. int top = geometry().top();
  152. int height = geometry().height();
  153. int leftOld = left;
  154. int topOld = top;
  155. if (mResizeMode & RM_LEFT)
  156. {
  157. width = width + (left - event->globalPos().x());
  158. left = event->globalPos().x();
  159. }
  160. if(mResizeMode & RM_RIGHT)
  161. {
  162. width = event->globalPos().x() - left;
  163. }
  164. if(mResizeMode & RM_TOP)
  165. {
  166. height = height + (top - event->globalPos().y());
  167. top = event->globalPos().y();
  168. }
  169. if(mResizeMode & RM_BOTTOM)
  170. {
  171. height = event->globalPos().y() - top;
  172. }
  173. // Check if we have reached width or height limit. We need to do some special
  174. // steps otherwise the window will move (instead of resize) after the limit is reached
  175. if(width < minimumWidth())
  176. {
  177. left = leftOld;
  178. width = minimumWidth();
  179. }
  180. if(height < minimumHeight())
  181. {
  182. top = topOld;
  183. height = minimumHeight();
  184. }
  185. setGeometry(left, top, width, height);
  186. update();
  187. }
  188. }
  189. QWidget::mouseMoveEvent(event);
  190. }
  191. void QtEditorWindow::timerUpdate()
  192. {
  193. if(!isDocked())
  194. {
  195. if(underMouse())
  196. {
  197. ResizeMode resizeMode = getResizeMode(QCursor::pos());
  198. switch(resizeMode)
  199. {
  200. case RM_LEFT:
  201. setCursor(Qt::SizeHorCursor);
  202. break;
  203. case RM_RIGHT:
  204. setCursor(Qt::SizeHorCursor);
  205. break;
  206. case RM_TOP:
  207. setCursor(Qt::SizeVerCursor);
  208. break;
  209. case RM_BOTTOM:
  210. setCursor(Qt::SizeVerCursor);
  211. break;
  212. case (ResizeMode)(RM_BOTTOM | RM_RIGHT):
  213. setCursor(Qt::SizeFDiagCursor);
  214. break;
  215. case (ResizeMode)(RM_TOP | RM_LEFT):
  216. setCursor(Qt::SizeFDiagCursor);
  217. break;
  218. case (ResizeMode)(RM_BOTTOM | RM_LEFT):
  219. setCursor(Qt::SizeBDiagCursor);
  220. break;
  221. case (ResizeMode)(RM_TOP | RM_RIGHT):
  222. setCursor(Qt::SizeBDiagCursor);
  223. break;
  224. case RM_NONE:
  225. setCursor(Qt::ArrowCursor);
  226. break;
  227. }
  228. }
  229. else
  230. {
  231. if(cursor().shape() != Qt::ArrowCursor)
  232. unsetCursor();
  233. }
  234. }
  235. }
  236. void QtEditorWindow::closeWindow()
  237. {
  238. gWindowDockManager().windowClosed(this);
  239. close();
  240. }
  241. QtEditorWindow::ResizeMode QtEditorWindow::getResizeMode(QPoint mousePos)
  242. {
  243. QPoint localMousePos = mapFromGlobal(mousePos);
  244. QPoint topLeft = mapFromParent(geometry().topLeft());
  245. QPoint botRight = mapFromParent(geometry().bottomRight());
  246. int distFromRight = botRight.x() - localMousePos.x();
  247. int distFromLeft = localMousePos.x() - topLeft.x();
  248. int distFromBot = botRight.y() - localMousePos.y();
  249. int distFromTop = localMousePos.y() - topLeft.y();
  250. if(distFromRight <= RESIZE_BORDER_SIZE && distFromRight >= 0 && distFromBot <= RESIZE_BORDER_SIZE && distFromBot >= 0)
  251. return (ResizeMode)(RM_BOTTOM | RM_RIGHT);
  252. if(distFromLeft <= RESIZE_BORDER_SIZE && distFromLeft >= 0 && distFromTop <= RESIZE_BORDER_SIZE && distFromTop >= 0)
  253. return (ResizeMode)(RM_TOP | RM_LEFT);
  254. if(distFromLeft <= RESIZE_BORDER_SIZE && distFromLeft >= 0 && distFromBot <= RESIZE_BORDER_SIZE && distFromBot >= 0)
  255. return (ResizeMode)(RM_BOTTOM | RM_LEFT);
  256. if(distFromRight <= RESIZE_BORDER_SIZE && distFromRight >= 0 && distFromTop <= RESIZE_BORDER_SIZE && distFromTop >= 0)
  257. return (ResizeMode)(RM_TOP | RM_RIGHT);
  258. if(distFromRight <= RESIZE_BORDER_SIZE && distFromRight >= 0)
  259. return RM_RIGHT;
  260. if(distFromLeft <= RESIZE_BORDER_SIZE && distFromLeft >= 0)
  261. return RM_LEFT;
  262. if(distFromBot <= RESIZE_BORDER_SIZE && distFromBot >= 0)
  263. return RM_BOTTOM;
  264. if(distFromTop <= RESIZE_BORDER_SIZE && distFromTop >= 0)
  265. return RM_TOP;
  266. return RM_NONE;
  267. }
  268. bool QtEditorWindow::isOverResizeArea(QPoint mousePos)
  269. {
  270. QPoint localMousePos = mapFromGlobal(mousePos);
  271. int distFromRight = geometry().width() - localMousePos.x();
  272. int distFromLeft = localMousePos.x();
  273. int distFromBot = geometry().height() - localMousePos.y();
  274. int distFromTop = localMousePos.y();
  275. if(distFromRight <= RESIZE_BORDER_SIZE && distFromRight >= 0)
  276. return true;
  277. if(distFromLeft <= RESIZE_BORDER_SIZE && distFromLeft >= 0)
  278. return true;
  279. if(distFromBot <= RESIZE_BORDER_SIZE && distFromBot >= 0)
  280. return true;
  281. if(distFromTop <= RESIZE_BORDER_SIZE && distFromTop >= 0)
  282. return true;
  283. return false;
  284. }
  285. bool QtEditorWindow::isOverDragArea(QPoint mousePos)
  286. {
  287. if(getResizeMode(mousePos) != RM_NONE)
  288. return false;
  289. QPoint localMousePos = mapFromGlobal(mousePos);
  290. int distFromTop = localMousePos.y();
  291. if(distFromTop <= TITLE_BAR_HEIGHT)
  292. return true;
  293. return false;
  294. }
  295. }