StateMenuOverlay.hpp
1 #pragma once
2 #include <Process/Style/ScenarioStyle.hpp>
3 
4 #include <Scenario/Document/State/StateModel.hpp>
5 #include <Scenario/Document/State/StatePresenter.hpp>
6 #include <Scenario/Document/State/StateView.hpp>
7 
8 #include <QGraphicsItem>
9 #include <QGraphicsSceneMouseEvent>
10 #include <QPainter>
11 #include <QPen>
12 
13 namespace Scenario
14 {
15 class CrossOverlay : public QGraphicsItem
16 {
17 public:
18  explicit CrossOverlay(StateView* parent)
19  : QGraphicsItem{parent}
20  {
21  this->setFlag(ItemStacksBehindParent, true);
22  this->setAcceptHoverEvents(true);
23  auto& skin = score::Skin::instance();
24  this->setCursor(skin.CursorPointingHand);
25  }
26 
27  static const constexpr int Type = ItemType::StateOverlay;
28  int type() const final override { return Type; }
29 
30  QRectF boundingRect() const override { return {-1, -1, 16, 16}; }
31 
32  virtual const score::Brush& brush() const noexcept = 0;
33 
34  void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
35  override
36  {
37  painter->setRenderHint(QPainter::Antialiasing, true);
38 
39  const auto& pending_brush = brush();
40  painter->setBrush(pending_brush);
41  const auto bright = pending_brush.color();
42  QPen p{bright.darker(300)};
43  p.setWidth(2);
44  painter->setPen(p);
45 
46  // TODO instead of a cross, make an arrow that looks like |->
47  const auto small_rad = m_big ? 4. : 2.;
48 
49  const auto l1
50  = m_big
51  ? QLineF{QPointF{15 - small_rad, 0}, QPointF{15 - small_rad, 2 * small_rad}}
52  .translated(-2, 1)
53  : QLineF{QPointF{15 - small_rad, 0}, QPointF{15 - small_rad, 2 * small_rad}}
54  .translated(-4, 2);
55  const auto l2
56  = m_big ? QLineF{QPointF{15 - 2 * small_rad, small_rad}, QPointF{15, small_rad}}
57  .translated(-2, 1)
58  : QLineF{QPointF{15 - 2 * small_rad, small_rad}, QPointF{15, small_rad}}
59  .translated(-4, 2);
60 
61  painter->drawLine(l1.translated(1, 1));
62  painter->drawLine(l2.translated(1, 1));
63  p.setColor(bright);
64  painter->setPen(p);
65  painter->drawLine(l1);
66  painter->drawLine(l2);
67 
68  painter->setRenderHint(QPainter::Antialiasing, false);
69  }
70 
71  void hoverEnterEvent(QGraphicsSceneHoverEvent* event) override
72  {
73  auto p = event->pos();
74  m_big = p.x() > 4 && p.y() < 10;
75  update();
76  }
77 
78  void hoverMoveEvent(QGraphicsSceneHoverEvent* event) override
79  {
80  auto p = event->pos();
81  m_big = p.x() > 4 && p.y() < 10;
82  update();
83  }
84 
85  void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override
86  {
87  m_big = false;
88  update();
89  }
90 
91  void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override
92  {
93  auto st = static_cast<StateView*>(parentItem());
94  st->presenter().moved(event->scenePos());
95  event->accept();
96  }
97 
98  void mouseReleaseEvent(QGraphicsSceneMouseEvent* event) override
99  {
100  auto st = static_cast<StateView*>(parentItem());
101  st->presenter().released(event->scenePos());
102  event->accept();
103  }
104 
105  bool m_big{false};
106 };
107 
108 class StatePlusOverlay final : public CrossOverlay
109 {
110 public:
111  explicit StatePlusOverlay(StateView* parent)
112  : CrossOverlay{parent}
113  {
114  this->setToolTip(
115  QObject::tr("Create an interval.\nDrag the plus to create an interval"));
116  }
117 
118 private:
119  const score::Brush& brush() const noexcept override
120  {
121  auto& skin = Process::Style::instance();
122  return skin.EventPending();
123  }
124 
125  void mousePressEvent(QGraphicsSceneMouseEvent* event) override
126  {
127  if(event->button() == Qt::MouseButton::LeftButton)
128  {
129  auto st = static_cast<StateView*>(parentItem());
130  st->presenter().select();
131  if(auto p = event->pos(); p.x() > 4 && p.y() < 10)
132  {
133  st->startCreateMode();
134  }
135 
136  st->presenter().pressed(event->scenePos());
137  event->accept();
138  }
139  }
140 };
141 
143 {
144 public:
145  explicit StateGraphPlusOverlay(StateView* parent)
146  : CrossOverlay{parent}
147  {
148  this->setToolTip(
149  QObject::tr("Create a graph link.\nDrag the plus to create a graph link"));
150  }
151 
152 private:
153  const score::Brush& brush() const noexcept override
154  {
155  auto& skin = Process::Style::instance();
156  return skin.EventDisposed();
157  }
158 
159  void mousePressEvent(QGraphicsSceneMouseEvent* event) override
160  {
161  if(event->button() == Qt::MouseButton::LeftButton)
162  {
163  auto st = static_cast<StateView*>(parentItem());
164  st->presenter().select();
165  if(auto p = event->pos(); p.x() > 4 && p.y() < 10)
166  {
167  st->startCreateGraphalMode();
168  }
169 
170  st->presenter().pressed(event->scenePos());
171  event->accept();
172  }
173  }
174 };
175 
177 {
178 public:
179  explicit StateSequencePlusOverlay(StateView* parent)
180  : CrossOverlay{parent}
181  {
182  this->setToolTip(
183  QObject::tr("Create a sequence.\nDrag the plus to create a sequence."));
184  }
185 
186 private:
187  const score::Brush& brush() const noexcept override
188  {
189  auto& skin = Process::Style::instance();
190  return skin.IntervalBase();
191  }
192 
193  void mousePressEvent(QGraphicsSceneMouseEvent* event) override
194  {
195  if(event->button() == Qt::MouseButton::LeftButton)
196  {
197  auto st = static_cast<StateView*>(parentItem());
198  st->presenter().select();
199  if(auto p = event->pos(); p.x() > 4 && p.y() < 10)
200  {
201  st->startCreateSequence();
202  }
203 
204  st->presenter().pressed(event->scenePos());
205  event->accept();
206  }
207  }
208 };
209 
211 {
213  : m_overlay{v}
214  , m_graphOverlay{v}
215  , m_sequenceOverlay{v}
216  {
217  m_overlay.setZValue(1);
218  m_sequenceOverlay.setZValue(2);
219  m_graphOverlay.setZValue(3);
220 
221  m_overlay.setPos(1, -14);
222  m_graphOverlay.setPos(1, 6);
223  if(v->presenter().model().nextInterval())
224  {
225  m_sequenceOverlay.setVisible(false);
226  m_sequenceOverlay.setEnabled(false);
227  }
228  else
229  {
230  m_sequenceOverlay.setPos(7, -4);
231  }
232  }
233 
234  StatePlusOverlay m_overlay;
235  StateGraphPlusOverlay m_graphOverlay;
236  StateSequencePlusOverlay m_sequenceOverlay;
237 };
238 }
Definition: StateMenuOverlay.hpp:16
Definition: StateMenuOverlay.hpp:143
Definition: StateMenuOverlay.hpp:109
Definition: StateMenuOverlay.hpp:177
Definition: StateView.hpp:29
Main plug-in of score.
Definition: score-plugin-dataflow/Dataflow/PortItem.hpp:14
Definition: StateMenuOverlay.hpp:211
Definition: Skin.hpp:55