27 void begin_path() { path = QPainterPath{}; }
28 void close_path() { path.closeSubpath(); }
29 void stroke() { painter.strokePath(path, painter.pen()); }
30 void fill() { painter.fillPath(path, painter.brush()); }
31 void update() { item.update(); }
33 void move_to(
double x,
double y) { path.moveTo(x, y); }
34 void line_to(
double x,
double y) { path.lineTo(x, y); }
35 void arc_to(
double x,
double y,
double w,
double h,
double start,
double length)
37 path.arcTo(x, y, w, h, start, length);
40 void cubic_to(
double c1x,
double c1y,
double c2x,
double c2y,
double endx,
double endy)
42 path.cubicTo(c1x, c1y, c2x, c2y, endx, endy);
45 void quad_to(
double x1,
double y1,
double x2,
double y2)
47 path.quadTo(x1, y1, x2, y2);
50 void translate(
double x,
double y) { painter.translate(x, y); }
51 void scale(
double x,
double y) { painter.scale(x, y); }
52 void rotate(
double a) { painter.rotate(a); }
53 void reset_transform() { painter.resetTransform(); }
56 void unset_stroke() { painter.setPen(score::Skin::instance().NoPen); }
59 QPen p = painter.pen();
60 p.setColor(qRgba(c.r, c.g, c.b, c.a));
64 void set_stroke_width(
double w)
66 QPen p = painter.pen();
73 painter.setBrush(QColor(qRgba(c.r, c.g, c.b, c.a)));
76 void set_linear_gradient(
79 QLinearGradient gradient(QPointF(x1, y1), QPointF(x2, y2));
80 gradient.setColorAt(0, QColor(qRgba(c1.r, c1.g, c1.b, c1.a)));
81 gradient.setColorAt(1, QColor(qRgba(c2.r, c2.g, c2.b, c2.a)));
82 painter.setBrush(gradient);
87 QRadialGradient gradient(cx, cy, cr);
88 gradient.setColorAt(0, QColor(qRgba(c1.r, c1.g, c1.b, c1.a)));
89 gradient.setColorAt(1, QColor(qRgba(c2.r, c2.g, c2.b, c2.a)));
90 painter.setBrush(gradient);
95 QConicalGradient gradient(x, y, a);
96 gradient.setColorAt(0, QColor(qRgba(c1.r, c1.g, c1.b, c1.a)));
97 gradient.setColorAt(1, QColor(qRgba(c2.r, c2.g, c2.b, c2.a)));
98 painter.setBrush(gradient);
102 void set_font(std::string_view f)
104 auto font = painter.font();
105 font.setFamily(QString::fromUtf8(f.data(), f.size()));
106 painter.setFont(font);
109 void set_font_size(
double f)
111 auto font = painter.font();
112 font.setPointSize(f);
113 painter.setFont(font);
116 void draw_text(
double x,
double y, std::string_view str)
118 path.addText(x, y, painter.font(), QString::fromUtf8(str.data(), str.size()));
121 void draw_text(
double x,
double y,
double w,
double h, std::string_view str)
123 QRectF rect{x, y, w, h};
124 const auto& m = painter.fontMetrics();
125 auto txt = QString::fromUtf8(str.data(), str.size());
126 auto text_rect = m.boundingRect(txt);
127 auto text_half_diagonal = (text_rect.center() - text_rect.topLeft()) / 2.;
128 auto pos = rect.center() + text_half_diagonal;
129 path.addText(pos.x(), pos.y(), painter.font(), txt);
133 void draw_line(
double x1,
double y1,
double x2,
double y2)
140 void draw_triangle(
double x1,
double y1,
double x2,
double y2,
double x3,
double y3)
146 painter.drawPath(path);
150 void draw_rect(
double x,
double y,
double w,
double h) { path.addRect(x, y, w, h); }
153 void draw_rounded_rect(
double x,
double y,
double w,
double h,
double r)
155 path.addRoundedRect(x, y, w, h, r, r);
159 void draw_pixmap(
double x,
double y,
const QString& str)
161 painter.drawPixmap(x, y, str);
165 void draw_ellipse(
double x,
double y,
double w,
double h)
167 path.addEllipse(x, y, w, h);
171 void draw_circle(
double cx,
double cy,
double cr)
173 path.addEllipse(QPointF{cx, cy}, cr, cr);
177 void draw_polygon(
const double* tab,
int count)
181 for(
int i = 0; i < count * 2; i += 2)
185 poly << QPointF(x, y);
187 path.addPolygon(poly);
191 int x,
int y,
int w,
int h,
const unsigned char* image,
int img_w,
int img_h,
194 auto img = QImage(image, img_w, img_h, QImage::Format_RGBA8888);
195 auto prev = painter.renderHints() & QPainter::SmoothPixmapTransform;
196 painter.setRenderHint(QPainter::SmoothPixmapTransform, smooth);
198 QRect(x, y, w, h), img, QRect(0, 0, img_w, img_h), Qt::ImageConversionFlags{});
200 painter.setRenderHint(QPainter::SmoothPixmapTransform, prev);
210 using item_type = std::decay_t<Item>;
219 this->setFlag(QGraphicsItem::ItemClipsToShape);
220 this->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
222 if constexpr(
requires { this->impl.update = [
this] {}; })
224 this->impl.update = [
this] { this->update(); };
228 QRectF boundingRect()
const override
230 return {0., 0., item_type::width(), item_type::height()};
233 void paint(QPainter* painter,
const QStyleOptionGraphicsItem* option, QWidget* widget)
236 auto& skin = score::Skin::instance();
237 painter->setRenderHint(QPainter::Antialiasing,
true);
238 painter->setPen(skin.Dark.main.pen1);
240 painter->setRenderHint(QPainter::Antialiasing,
false);
252 friend button& operator|=(button& lhs, button rhs)
noexcept
255 enum button&)(
reinterpret_cast<std::underlying_type_t<enum button>&
>(lhs) |=
reinterpret_cast<std::underlying_type_t<enum button>&
>(rhs));
265 friend modifier& operator|=(modifier& lhs, modifier rhs)
noexcept
268 enum modifier&)(
reinterpret_cast<std::underlying_type_t<enum modifier>&
>(lhs) |=
reinterpret_cast<std::underlying_type_t<enum modifier>&
>(rhs));
273 enum button button = {};
274 enum button held_buttons = {};
275 enum modifier modifiers = {};
283 p.x =
event->pos().x();
284 p.y =
event->pos().y();
286 if(event->button() == Qt::LeftButton)
287 p.button = custom_mouse_event::left;
288 else if(event->button() == Qt::RightButton)
289 p.button = custom_mouse_event::right;
290 else if(event->button() == Qt::MiddleButton)
291 p.button = custom_mouse_event::middle;
293 if(event->buttons() & Qt::LeftButton)
294 p.held_buttons |= p.left;
295 if(event->buttons() & Qt::RightButton)
296 p.held_buttons |= p.right;
297 if(event->buttons() & Qt::MiddleButton)
298 p.held_buttons |= p.middle;
300 if(event->modifiers() & Qt::ShiftModifier)
301 p.modifiers |= p.shift;
302 if(event->modifiers() & Qt::AltModifier)
303 p.modifiers |= p.alt;
304 if(event->modifiers() & Qt::ControlModifier)
305 p.modifiers |= p.ctrl;
306 if(event->modifiers() & Qt::MetaModifier)
307 p.modifiers |= p.meta;
312 void mousePressEvent(QGraphicsSceneMouseEvent* event)
override
314 if constexpr(
requires { impl.mouse_press(0, 0); })
316 if(impl.mouse_press(event->pos().x(), event->pos().y()))
319 else if constexpr(
requires { impl.mouse_press(custom_mouse_event{}); })
321 if(impl.mouse_press(make_event(event)))
327 void mouseMoveEvent(QGraphicsSceneMouseEvent* event)
override
329 if constexpr(
requires { impl.mouse_move(0, 0); })
331 impl.mouse_move(event->pos().x(),
event->pos().y());
334 else if constexpr(
requires { impl.mouse_move(custom_mouse_event{}); })
336 impl.mouse_move(make_event(event));
342 void mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
override
344 if constexpr(
requires { impl.mouse_release(0, 0); })
346 impl.mouse_release(event->pos().x(),
event->pos().y());
349 else if constexpr(
requires { impl.mouse_release(custom_mouse_event{}); })
351 impl.mouse_release(make_event(event));