summaryrefslogtreecommitdiffhomepage
path: root/spline/spline-widget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'spline/spline-widget.cpp')
-rw-r--r--spline/spline-widget.cpp208
1 files changed, 114 insertions, 94 deletions
diff --git a/spline/spline-widget.cpp b/spline/spline-widget.cpp
index 64f9f156..d329d8e2 100644
--- a/spline/spline-widget.cpp
+++ b/spline/spline-widget.cpp
@@ -1,10 +1,3 @@
-/* Copyright (c) 2012-2016 Stanislaw Halik <sthalik@misaki.pl>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-
#include "spline-widget.hpp"
#include "compat/math.hpp"
#include "compat/macros.hpp"
@@ -19,7 +12,7 @@
#include <QDebug>
-using namespace spline_detail;
+namespace spline_detail {
spline_widget::spline_widget(QWidget *parent) : QWidget(parent)
{
@@ -31,28 +24,31 @@ spline_widget::spline_widget(QWidget *parent) : QWidget(parent)
spline_widget::~spline_widget()
{
if (connection)
+ {
QObject::disconnect(connection);
+ connection = {};
+ }
}
-void spline_widget::setConfig(base_spline* spl)
+void spline_widget::set_config(base_spline* spl)
{
if (connection)
{
QObject::disconnect(connection);
- connection = QMetaObject::Connection();
+ connection = {};
}
- _config = spl;
+ config = spl;
if (spl)
{
- update_range();
-
- std::shared_ptr<base_spline::base_settings> s = spl->get_settings();
- connection = connect(s.get(), &base_spline::base_settings::recomputed,
+ std::shared_ptr<base_settings> s = spl->get_settings();
+ connection = connect(s.get(), &base_settings::recomputed,
this, [this] { reload_spline(); },
Qt::QueuedConnection);
}
+
+ reload_spline();
}
QColor spline_widget::colorBezier() const
@@ -68,37 +64,39 @@ void spline_widget::setColorBezier(QColor const& color)
void spline_widget::force_redraw()
{
- _background = QPixmap();
+ background_img = {};
repaint();
}
void spline_widget::set_preview_only(bool val)
{
- _preview_only = val;
+ preview_only = val;
}
bool spline_widget::is_preview_only() const
{
- return _preview_only;
+ return preview_only;
}
void spline_widget::drawBackground()
{
- QPainter painter(&_background);
+ QPainter painter(&background_img);
painter.fillRect(rect(), widget_bg_color);
{
QColor bg_color(112, 154, 209);
- if (!isEnabled() && !_preview_only)
+ if (!isEnabled() && !preview_only)
bg_color = QColor(176,176,180);
painter.fillRect(pixel_bounds, bg_color);
}
QFont font;
font.setPointSize(8);
+ font.setStyleHint(QFont::Monospace, QFont::PreferAntialias);
painter.setFont(font);
- QFontMetricsF metrics(font);
+ const QFontMetricsF metrics(font);
+ const double height = metrics.height();
QColor color__(176, 190, 209, 127);
@@ -107,11 +105,11 @@ void spline_widget::drawBackground()
const QPen pen(color__, 1, Qt::SolidLine, Qt::FlatCap);
- const int ystep = _y_step, xstep = _x_step;
- const double maxx = _config->max_input();
- const double maxy = _config->max_output();
+ const int ystep = (int)std::ceil(y_step_), xstep = (int)std::ceil(x_step_);
+ const double maxx = config->max_input();
+ const double maxy = config->max_output();
- // horizontal grid
+ // vertical grid
for (int i = 0; i <= maxy; i += ystep)
{
const double y = pixel_bounds.height() - i * c.y() + pixel_bounds.y();
@@ -120,13 +118,13 @@ void spline_widget::drawBackground()
QPointF(pixel_bounds.x() + pixel_bounds.width(), y),
pen);
painter.drawText(QRectF(10,
- y - metrics.height()/2.,
+ y - height/2,
pixel_bounds.left(),
- metrics.height()),
+ height),
QString::number(i));
}
- // vertical grid
+ // horizontal grid
for (int i = 0; i <= maxx; i += xstep)
{
const double x = pixel_bounds.x() + i * c.x();
@@ -134,21 +132,29 @@ void spline_widget::drawBackground()
QPointF(x, pixel_bounds.y()),
QPointF(x, pixel_bounds.y() + pixel_bounds.height()),
pen);
+
const QString text = QString::number(i);
- painter.drawText(QRectF(x - metrics.width(text)/2.,
- pixel_bounds.height() + 10 + metrics.height(),
- metrics.width(text),
- metrics.height()),
+
+ const double width =
+#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
+ metrics.horizontalAdvance(text);
+#else
+ metrics.width(text);
+#endif
+
+ painter.drawText(QRectF{x - width/2,
+ pixel_bounds.height() + 10 + height,
+ width, height},
text);
}
}
void spline_widget::drawFunction()
{
- QPainter painter(&_function);
+ QPainter painter(&spline_img);
painter.setRenderHint(QPainter::Antialiasing, true);
- const points_t points = _config->get_points();
+ const points_t& points = config->get_points();
if (moving_control_point_idx >= 0 &&
moving_control_point_idx < points.size())
@@ -156,7 +162,7 @@ void spline_widget::drawFunction()
const QPen pen(Qt::white, 1, Qt::SolidLine, Qt::FlatCap);
const QPointF prev_ = point_to_pixel({});
QPointF prev(iround(prev_.x()), iround(prev_.y()));
- for (auto point : points)
+ for (const auto& point : points)
{
const QPointF tmp = point_to_pixel(point);
drawLine(painter, prev, tmp, pen);
@@ -165,7 +171,7 @@ void spline_widget::drawFunction()
}
const QColor color_ = progn(
- if (!isEnabled() && !_preview_only)
+ if (!isEnabled() && !preview_only)
{
QColor color(spline_color);
const int avg = int(float(color.red() + color.green() + color.blue())/3);
@@ -187,7 +193,7 @@ void spline_widget::drawFunction()
const double dpr = devicePixelRatioF();
const double line_length_pixels = std::fmax(1, 2 * dpr);
const double step = std::fmax(.1, line_length_pixels / c.x());
- const double maxx = _config->max_input();
+ const double maxx = config->max_input();
//#define USE_CUBIC_SPLINE
#if defined USE_CUBIC_SPLINE
@@ -205,9 +211,9 @@ void spline_widget::drawFunction()
for (double k = 0; k < maxx; k += step*3) // NOLINT
{
- const auto next_1 = (double) _config->get_value_no_save(k + step*1);
- const auto next_2 = (double) _config->get_value_no_save(k + step*2);
- const auto next_3 = (double) _config->get_value_no_save(k + step*3);
+ const auto next_1 = config->get_value_no_save(k + step*1);
+ const auto next_2 = config->get_value_no_save(k + step*2);
+ const auto next_3 = config->get_value_no_save(k + step*3);
QPointF b(clamp(point_to_pixel({k + step*1, next_1}))),
c(clamp(point_to_pixel({k + step*2, next_2}))),
@@ -221,14 +227,14 @@ void spline_widget::drawFunction()
QPointF prev = point_to_pixel({});
for (double i = 0; i < maxx; i += step) // NOLINT
{
- const auto val = (double) _config->get_value_no_save(i);
+ const auto val = config->get_value_no_save(i);
const QPointF cur = point_to_pixel({i, val});
painter.drawLine(prev, cur);
prev = cur;
}
{
- const double maxx = _config->max_input();
- const double maxy = double(_config->get_value_no_save(maxx));
+ const double maxx = config->max_input();
+ const double maxy = config->get_value_no_save(maxx);
painter.drawLine(prev, point_to_pixel({ maxx, maxy }));
}
#endif
@@ -242,7 +248,7 @@ void spline_widget::drawFunction()
painter.fillRect(r2, widget_bg_color);
const int alpha = !isEnabled() ? 64 : 120;
- if (!_preview_only)
+ if (!preview_only)
{
for (auto const& point : points)
{
@@ -256,7 +262,7 @@ void spline_widget::drawFunction()
void spline_widget::paintEvent(QPaintEvent *e)
{
- if (!_config)
+ if (!config)
return;
QPainter p(this);
@@ -265,28 +271,30 @@ void spline_widget::paintEvent(QPaintEvent *e)
const int W = iround(width() * dpr);
const int H = iround(height() * dpr);
- if (_background.size() != QSize(W, H))
+ if (background_img.size() != QSize(W, H))
{
- _background = QPixmap(W, H);
- _background.setDevicePixelRatio(dpr);
- _draw_function = true;
+ update_range();
+
+ background_img = { W, H };
+ background_img.setDevicePixelRatio(dpr);
drawBackground();
+ draw_function = true;
}
- if (_draw_function)
+ if (draw_function)
{
- _draw_function = false;
- _function = _background;
+ draw_function = false;
+ spline_img = background_img;
drawFunction();
}
- p.drawPixmap(e->rect(), _function);
+ p.drawPixmap(e->rect(), spline_img);
// If the Tracker is active, the 'Last Point' it requested is recorded.
// Show that point on the graph, with some lines to assist.
// This new feature is very handy for tweaking the curves!
QPointF last;
- if (_config->get_last_value(last) && isEnabled())
+ if (config->get_last_value(last) && isEnabled())
drawPoint(p, point_to_pixel(last), QColor(255, 0, 0, 120));
}
@@ -312,14 +320,14 @@ void spline_widget::drawLine(QPainter& painter, const QPointF& start, const QPoi
void spline_widget::mousePressEvent(QMouseEvent *e)
{
- if (!_config || !isEnabled() || !is_in_bounds(e->localPos()) || _preview_only)
+ if (!config || !isEnabled() || !is_in_bounds(e->localPos()) || preview_only)
return;
const double min_dist = min_pt_distance();
moving_control_point_idx = -1;
- points_t points = _config->get_points();
+ const points_t& points = config->get_points();
if (e->button() == Qt::LeftButton)
{
@@ -352,50 +360,50 @@ void spline_widget::mousePressEvent(QMouseEvent *e)
if (!too_close)
{
- _config->add_point(pixel_to_point(e->localPos()));
+ config->add_point(pixel_to_point(e->localPos()));
show_tooltip(e->pos());
}
}
- _draw_function = true;
+ draw_function = true;
}
if (e->button() == Qt::RightButton)
{
- if (_config)
+ if (config)
{
for (int i = 0; i < points.size(); i++)
{
if (point_within_pixel(points[i], e->localPos()))
{
- _config->remove_point(i);
- _draw_function = true;
+ config->remove_point(i);
+ draw_function = true;
break;
}
}
}
}
- if (_draw_function)
+ if (draw_function)
repaint();
}
void spline_widget::mouseMoveEvent(QMouseEvent *e)
{
- if (_preview_only && _config)
+ if (preview_only && config)
{
show_tooltip(e->pos());
return;
}
- if (!_config || !isEnabled() || !isActiveWindow())
+ if (!config || !isEnabled() || !isActiveWindow())
{
QToolTip::hideText();
return;
}
const int i = moving_control_point_idx;
- const points_t points = _config->get_points();
+ const points_t& points = config->get_points();
const int sz = points.size();
if (i >= 0 && i < sz)
@@ -428,8 +436,8 @@ void spline_widget::mouseMoveEvent(QMouseEvent *e)
if ((!has_prev || check_prev()) && (!has_next || check_next()))
{
- _config->move_point(i, new_pt);
- _draw_function = true;
+ config->move_point(i, new_pt);
+ draw_function = true;
repaint();
}
}
@@ -456,7 +464,7 @@ void spline_widget::mouseMoveEvent(QMouseEvent *e)
void spline_widget::mouseReleaseEvent(QMouseEvent *e)
{
- if (!_config || !isEnabled() || !isActiveWindow() || _preview_only)
+ if (!config || !isEnabled() || !isActiveWindow() || preview_only)
return;
const bool redraw = moving_control_point_idx != -1;
@@ -479,7 +487,7 @@ void spline_widget::mouseReleaseEvent(QMouseEvent *e)
if (redraw)
{
- _draw_function = true;
+ draw_function = true;
repaint();
}
}
@@ -487,7 +495,7 @@ void spline_widget::mouseReleaseEvent(QMouseEvent *e)
void spline_widget::reload_spline()
{
// don't recompute here as the value's about to be recomputed in the callee
- update_range();
+ background_img = {};
update();
}
@@ -504,8 +512,8 @@ void spline_widget::show_tooltip(const QPoint& pos, const QPointF& value_)
double x = value.x(), y = value.y();
- if (_preview_only)
- y = _config->get_value_no_save(x);
+ if (preview_only)
+ y = config->get_value_no_save(x);
const int x_ = iround(x), y_ = iround(y);
@@ -514,16 +522,13 @@ void spline_widget::show_tooltip(const QPoint& pos, const QPointF& value_)
if (std::fabs(y_ - y) < 1e-3)
y = y_;
- // the style on OSX has different offsets
- static const bool is_fusion =
+ // the native OSX style doesn't look right otherwise
#if defined __APPLE__
- true;
+ constexpr int off_x = 0, off_y = 0;
#else
- false;
+ constexpr int off_x = 25, off_y = 15;
#endif
- const int off_x = (is_fusion ? 25 : 0), off_y = (is_fusion ? 15 : 0);
-
const QPoint pix(pos.x() + off_x, pos.y() + off_y);
QToolTip::showText(mapToGlobal(pix),
@@ -535,8 +540,8 @@ void spline_widget::show_tooltip(const QPoint& pos, const QPointF& value_)
bool spline_widget::is_in_bounds(const QPointF& pos) const
{
- const int grace = point_size_in_pixels * 3;
- const int bottom_grace = int(point_size_in_pixels * 1.5);
+ const int grace = (int)std::ceil(point_size_in_pixels * 3);
+ const int bottom_grace = (int)std::ceil(point_size_in_pixels * 1.5);
return (pos.x() + grace > pixel_bounds.left() &&
pos.x() - grace < pixel_bounds.right() &&
pos.y() + grace > pixel_bounds.top() &&
@@ -545,21 +550,22 @@ bool spline_widget::is_in_bounds(const QPointF& pos) const
void spline_widget::update_range()
{
- if (!_config)
+ if (!config)
return;
const int w = width(), h = height();
const int mwl = 40, mhl = 20;
const int mwr = 15, mhr = 35;
- pixel_bounds = QRect(mwl, mhl, (w - mwl - mwr), (h - mhl - mhr));
- c = { pixel_bounds.width() / _config->max_input(), pixel_bounds.height() / _config->max_output() };
- _draw_function = true;
-
- _background = QPixmap();
- _function = QPixmap();
+ pixel_bounds = { mwl, mhl, (w - mwl - mwr), (h - mhl - mhr) };
+ c = {
+ pixel_bounds.width() / std::fmax(1, config->max_input()),
+ pixel_bounds.height() / std::fmax(1, config->max_output())
+ };
- repaint();
+ draw_function = true;
+ background_img = {};
+ spline_img = {};
}
bool spline_widget::point_within_pixel(const QPointF& pt, const QPointF& pixel)
@@ -573,7 +579,7 @@ void spline_widget::focusOutEvent(QFocusEvent* e)
if (moving_control_point_idx != -1)
QToolTip::hideText();
moving_control_point_idx = -1;
- _draw_function = true;
+ draw_function = true;
lower();
setCursor(Qt::ArrowCursor);
e->accept();
@@ -604,8 +610,8 @@ QPointF spline_widget::pixel_to_point(const QPointF& point)
if (snap_y > 0)
y = snap(y, snap_y);
- x = clamp(x, 0, _config->max_input());
- y = clamp(y, 0, _config->max_output());
+ x = clamp(x, 0, config->max_input());
+ y = clamp(y, 0, config->max_output());
return { x, y };
}
@@ -620,19 +626,19 @@ QPointF spline_widget::point_to_pixel(const QPointF& point)
void spline_widget::resizeEvent(QResizeEvent *)
{
- update_range();
+ reload_spline();
}
bool spline_widget::is_on_pt(const QPointF& pos, int* pt)
{
- if (!_config)
+ if (!config)
{
if (pt)
*pt = -1;
return false;
}
- const points_t points = _config->get_points();
+ const points_t& points = config->get_points();
for (int i = 0; i < points.size(); i++)
{
@@ -648,3 +654,17 @@ bool spline_widget::is_on_pt(const QPointF& pos, int* pt)
*pt = -1;
return false;
}
+
+void spline_widget::changeEvent(QEvent* e)
+{
+ switch (e->type())
+ {
+ case QEvent::EnabledChange:
+ background_img = {}; spline_img = {};
+ update();
+ break;
+ default:
+ break;
+ }
+}
+} // ns spline_detail