SlicerManipulator.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "SpriteBorderEditorCommon.h"
  9. #define UICANVASEDITOR_DRAW_SELECTABLE_AREA_OF_SLICERMANIPULATOR (0)
  10. #define UICANVASEDITOR_ARBITRARILY_LARGE_NUMBER (10000.0f)
  11. #define UICANVASEDITOR_MANIPULATOR_GRASPABLE_THICKNESS_IN_PIXELS (24)
  12. #define UICANVASEDITOR_SLICERMANIPULATOR_DRAW_HALF_WIDTH (1.0f)
  13. SlicerManipulator::SlicerManipulator(SpriteBorder border,
  14. QSize& unscaledPixmapSize,
  15. QSize& scaledPixmapSize,
  16. ISprite* sprite,
  17. QGraphicsScene* scene,
  18. SlicerEdit* edit)
  19. : QGraphicsRectItem()
  20. , m_border(border)
  21. , m_isVertical(IsBorderVertical(m_border))
  22. , m_unscaledPixmapSize(unscaledPixmapSize)
  23. , m_scaledPixmapSize(scaledPixmapSize)
  24. , m_sprite(sprite)
  25. , m_unscaledOverScaledFactor(((float)m_unscaledPixmapSize.width() / (float)m_scaledPixmapSize.width()),
  26. ((float)m_unscaledPixmapSize.height() / (float)m_scaledPixmapSize.height()))
  27. , m_scaledOverUnscaledFactor((1.0f / m_unscaledOverScaledFactor.x()),
  28. (1.0f / m_unscaledOverScaledFactor.y()))
  29. , m_penFront(Qt::DotLine)
  30. , m_penBack()
  31. , m_edit(edit)
  32. {
  33. setAcceptHoverEvents(true);
  34. scene->addItem(this);
  35. setRect((m_isVertical ? -(UICANVASEDITOR_MANIPULATOR_GRASPABLE_THICKNESS_IN_PIXELS * 0.5f) : -UICANVASEDITOR_ARBITRARILY_LARGE_NUMBER),
  36. (m_isVertical ? -UICANVASEDITOR_ARBITRARILY_LARGE_NUMBER : -(UICANVASEDITOR_MANIPULATOR_GRASPABLE_THICKNESS_IN_PIXELS * 0.5f)),
  37. (m_isVertical ? UICANVASEDITOR_MANIPULATOR_GRASPABLE_THICKNESS_IN_PIXELS : (3.0f * UICANVASEDITOR_ARBITRARILY_LARGE_NUMBER)),
  38. (m_isVertical ? (3.0f * UICANVASEDITOR_ARBITRARILY_LARGE_NUMBER) : UICANVASEDITOR_MANIPULATOR_GRASPABLE_THICKNESS_IN_PIXELS));
  39. setPixelPosition(GetBorderValueInPixels(m_sprite, m_border, aznumeric_cast<float>(m_isVertical ? m_unscaledPixmapSize.width() : m_unscaledPixmapSize.height())));
  40. setFlag(QGraphicsItem::ItemIsMovable, true);
  41. setFlag(QGraphicsItem::ItemIsSelectable, true); // This allows using the CTRL key to select multiple manipulators and move them simultaneously.
  42. setFlag(QGraphicsItem::ItemSendsScenePositionChanges, true);
  43. m_penFront.setColor(Qt::white);
  44. m_penBack.setColor(Qt::black);
  45. m_penFront.setWidthF(2.0f * UICANVASEDITOR_SLICERMANIPULATOR_DRAW_HALF_WIDTH);
  46. m_penBack.setWidthF(2.0f * UICANVASEDITOR_SLICERMANIPULATOR_DRAW_HALF_WIDTH);
  47. }
  48. void SlicerManipulator::SetEdit(SlicerEdit* edit)
  49. {
  50. m_edit = edit;
  51. }
  52. void SlicerManipulator::SetPixmapSizes(const QSize& unscaledSize, const QSize& scaledSize)
  53. {
  54. const bool validInputs = unscaledSize.isValid() && scaledSize.isValid();
  55. if (!validInputs)
  56. {
  57. return;
  58. }
  59. m_unscaledPixmapSize = unscaledSize;
  60. m_scaledPixmapSize = scaledSize;
  61. m_unscaledOverScaledFactor = QPointF(((float)m_unscaledPixmapSize.width() / (float)m_scaledPixmapSize.width()),
  62. ((float)m_unscaledPixmapSize.height() / (float)m_scaledPixmapSize.height()));
  63. m_scaledOverUnscaledFactor = QPointF((1.0f / m_unscaledOverScaledFactor.x()),
  64. (1.0f / m_unscaledOverScaledFactor.y()));
  65. }
  66. void SlicerManipulator::paint(QPainter* painter, [[maybe_unused]] const QStyleOptionGraphicsItem* option, [[maybe_unused]] QWidget* widget)
  67. {
  68. #if UICANVASEDITOR_DRAW_SELECTABLE_AREA_OF_SLICERMANIPULATOR
  69. QGraphicsRectItem::paint(painter, option, widget);
  70. #endif // UICANVASEDITOR_DRAW_SELECTABLE_AREA_OF_SLICERMANIPULATOR
  71. // Draw a thin line in the middle of the selectable area.
  72. if (m_isVertical)
  73. {
  74. float x = aznumeric_cast<float>((rect().left() + rect().right()) * 0.5f);
  75. float y_start = 0;
  76. float y_end = aznumeric_cast<float>(m_scaledPixmapSize.height());
  77. // Back.
  78. painter->setPen(m_penBack);
  79. painter->drawLine(aznumeric_cast<int>(x), aznumeric_cast<int>(y_start), aznumeric_cast<int>(x), aznumeric_cast<int>(y_end));
  80. // Front.
  81. painter->setPen(m_penFront);
  82. painter->drawLine(aznumeric_cast<int>(x), aznumeric_cast<int>(y_start), aznumeric_cast<int>(x), aznumeric_cast<int>(y_end));
  83. }
  84. else // Horizontal.
  85. {
  86. float x_start = 0.0f;
  87. float x_end = aznumeric_cast<float>(m_scaledPixmapSize.width());
  88. float y = aznumeric_cast<float>((rect().top() + rect().bottom()) * 0.5f);
  89. // Back.
  90. painter->setPen(m_penBack);
  91. painter->drawLine(aznumeric_cast<int>(x_start), aznumeric_cast<int>(y), aznumeric_cast<int>(x_end), aznumeric_cast<int>(y));
  92. // Front.
  93. painter->setPen(m_penFront);
  94. painter->drawLine(aznumeric_cast<int>(x_start), aznumeric_cast<int>(y), aznumeric_cast<int>(x_end), aznumeric_cast<int>(y));
  95. }
  96. }
  97. void SlicerManipulator::setPixelPosition(float p)
  98. {
  99. float xPos = aznumeric_cast<float>(m_isVertical ? (p * m_scaledOverUnscaledFactor.x()) : 0.0f);
  100. float yPos = aznumeric_cast<float>(m_isVertical ? 0.0f : (p * m_scaledOverUnscaledFactor.y()));
  101. setPos(xPos, yPos);
  102. }
  103. QVariant SlicerManipulator::itemChange(GraphicsItemChange change, const QVariant& value)
  104. {
  105. if ((change == ItemPositionChange) &&
  106. scene())
  107. {
  108. const float totalScaledSizeInPixels = aznumeric_cast<float>(m_isVertical ? m_scaledPixmapSize.width() : m_scaledPixmapSize.height());
  109. float manipulatorPos = aznumeric_cast<float>(AZ::GetMax(m_isVertical ? value.toPointF().x() : value.toPointF().y(), 0.0));
  110. const float borderValue = aznumeric_cast<float>(m_isVertical ? (manipulatorPos * m_unscaledOverScaledFactor.x()) : (manipulatorPos * m_unscaledOverScaledFactor.y()));
  111. m_edit->setPixelPosition(borderValue);
  112. const float cellSize = (m_isVertical ? m_sprite->GetCellSize(m_cellIndex).GetX() : m_sprite->GetCellSize(m_cellIndex).GetY());
  113. SetBorderValue(m_sprite, m_border, borderValue, cellSize, m_cellIndex);
  114. manipulatorPos = AZ::GetMin<float>(manipulatorPos, totalScaledSizeInPixels);
  115. return QPointF((m_isVertical ? manipulatorPos : 0.0f),
  116. (m_isVertical ? 0.0f : manipulatorPos));
  117. }
  118. return QGraphicsItem::itemChange(change, value);
  119. }
  120. void SlicerManipulator::hoverEnterEvent([[maybe_unused]] QGraphicsSceneHoverEvent* event)
  121. {
  122. setCursor(m_isVertical ? Qt::SizeHorCursor : Qt::SizeVerCursor);
  123. m_penFront.setColor(Qt::yellow);
  124. update();
  125. }
  126. void SlicerManipulator::hoverLeaveEvent([[maybe_unused]] QGraphicsSceneHoverEvent* event)
  127. {
  128. setCursor(Qt::ArrowCursor);
  129. m_penFront.setColor(Qt::white);
  130. update();
  131. }