summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--spline-widget/spline-widget.cpp113
-rw-r--r--spline-widget/spline-widget.hpp4
2 files changed, 53 insertions, 64 deletions
diff --git a/spline-widget/spline-widget.cpp b/spline-widget/spline-widget.cpp
index 21c52d63..105efb77 100644
--- a/spline-widget/spline-widget.cpp
+++ b/spline-widget/spline-widget.cpp
@@ -19,6 +19,8 @@
#include <QStyle>
#include <QMouseEvent>
+#include <QDebug>
+
#include <cmath>
#include <algorithm>
@@ -139,7 +141,7 @@ void spline_widget::drawBackground()
// vertical grid
for (int i = 0; i <= maxx; i += ystep)
{
- const int x = int(std::round(pixel_bounds.x() + i * c.x()));
+ const int x = iround(pixel_bounds.x() + i * c.x());
drawLine(painter,
QPoint(x, pixel_bounds.y()),
QPoint(x, pixel_bounds.y() + pixel_bounds.height()),
@@ -166,11 +168,11 @@ void spline_widget::drawFunction()
{
const QPen pen(Qt::white, 1, Qt::SolidLine, Qt::FlatCap);
const QPointF prev_ = point_to_pixel(QPointF(0, 0));
- QPoint prev(int(std::round(prev_.x())), int(std::round(prev_.y())));
+ QPoint prev(iround(prev_.x()), iround(prev_.y()));
for (int i = 0; i < points.size(); i++)
{
const QPointF tmp_ = point_to_pixel(points[i]);
- const QPoint tmp(int(std::round(tmp_.x())), int(std::round(tmp_.y())));
+ const QPoint tmp(iround(tmp_.x()), iround(tmp_.y()));
drawLine(painter, prev, tmp, pen);
prev = tmp;
}
@@ -286,6 +288,8 @@ void spline_widget::mousePressEvent(QMouseEvent *e)
if (!is_in_bounds(e->pos()))
return;
+ const int point_pixel_closeness_limit = get_closeness_limit();
+
points_t points = _config->getPoints();
if (e->button() == Qt::LeftButton)
{
@@ -305,13 +309,13 @@ void spline_widget::mousePressEvent(QMouseEvent *e)
if (!bTouchingPoint)
{
bool too_close = false;
- const auto pos = e->pos();
+ const QPoint pos = e->pos();
for (int i = 0; i < points.size(); i++)
{
const QPointF pt = point_to_pixel(points[i]);
const qreal x = std::fabs(pt.x() - pos.x());
- if (point_closeness_limit >= x)
+ if (point_pixel_closeness_limit >= x)
{
too_close = true;
break;
@@ -360,62 +364,45 @@ void spline_widget::mouseMoveEvent(QMouseEvent *e)
return;
}
- points_t points = _config->getPoints();
+ const int i = moving_control_point_idx;
+ const points_t points = _config->getPoints();
+ const int sz = points.size();
- if (moving_control_point_idx >= 0 && moving_control_point_idx < points.size())
+ if (i >= 0 && i < sz)
{
- const int idx = moving_control_point_idx;
-
- setCursor(Qt::ClosedHandCursor);
-
+ const int point_pixel_closeness_limit = get_closeness_limit();
bool overlap = false;
- QPoint pix = e->pos();
+ const QPoint pix = progn(
+ // takes snap into account
+ const QPointF pix_ = point_to_pixel(pixel_coord_to_point(e->pos()));
+ return QPoint(int(pix_.x()), int(pix_.y()));
+ );
+
QPointF new_pt = pixel_coord_to_point(pix);
- for (int i = 0; i < 2; i++)
+ if (i + 1 < points.size())
{
- bool bad = false;
- if (idx + 1 < points.size())
- {
- auto other = points[idx+1];
- auto other_pix = point_to_pixel(other);
- bad = pix.x() + point_closeness_limit > other_pix.x();
- if (i == 0 && bad)
- {
- pix.setX(int(std::round(other_pix.x() - point_closeness_limit)));
- new_pt = pixel_coord_to_point(pix);
- }
- else
- overlap |= bad;
- }
- if (idx != 0)
- {
- const QPointF other = points[idx-1];
- const QPointF other_pix = point_to_pixel(other);
- bad = pix.x() - point_closeness_limit < other_pix.x();
- if (i == 0 && bad)
- {
- pix.setX(int(std::round(other_pix.x() + point_closeness_limit)));
- new_pt = pixel_coord_to_point(pix);
- }
- else
- overlap |= bad;
- }
- if (!bad)
- break;
+ const QPointF other_pix = point_to_pixel(points[i+1]);
+ overlap |= other_pix.x() - pix.x() < point_pixel_closeness_limit;
}
-
- if (!overlap)
+ if (i != 0)
{
- _config->movePoint(idx, new_pt);
- _draw_function = true;
-
- show_tooltip(pix, new_pt);
- update();
+ const QPointF other_pix = point_to_pixel(points[i-1]);
+ overlap |= pix.x() - other_pix.x() < point_pixel_closeness_limit;
}
+
+ if (overlap)
+ new_pt.setX(points[i].x());
+
+ _config->movePoint(i, new_pt);
+ _draw_function = true;
+
+ setCursor(Qt::ClosedHandCursor);
+ show_tooltip(pix, new_pt);
+ update();
}
- else
+ else if (sz)
{
int i;
bool is_on_point = is_on_pt(e->pos(), &i);
@@ -446,8 +433,6 @@ void spline_widget::mouseReleaseEvent(QMouseEvent *e)
if (e->button() == Qt::LeftButton)
{
- //mouseMoveEvent(e);
-
{
if (is_on_pt(e->pos(), nullptr))
setCursor(Qt::CrossCursor);
@@ -472,12 +457,17 @@ void spline_widget::reload_spline()
update_range();
}
+int spline_widget::get_closeness_limit()
+{
+ return std::max(iround(snap_x * c.x()), 1);
+}
+
void spline_widget::show_tooltip(const QPoint& pos, const QPointF& value_, const QString& prefix)
{
const QPointF value = QPoint(0, 0) == value_ ? pixel_coord_to_point(pos) : value_;
double x = value.x(), y = value.y();
- const int x_ = int(std::round(x)), y_ = int(std::round(y));
+ const int x_ = iround(x), y_ = iround(y);
using std::fabs;
@@ -500,11 +490,12 @@ void spline_widget::show_tooltip(const QPoint& pos, const QPointF& value_, const
bool spline_widget::is_in_bounds(const QPoint& pos) const
{
- static constexpr int grace = 2;
- return !(pos.x() + grace < pixel_bounds.left() ||
- pos.x() - grace > pixel_bounds.right() ||
- pos.y() + grace < pixel_bounds.top() ||
- pos.y() - grace > pixel_bounds.bottom());
+ static constexpr int grace = point_size * 3;
+ static constexpr int bottom_grace = int(point_size * 1.5);
+ return (pos.x() + grace > pixel_bounds.left() &&
+ pos.x() - grace < pixel_bounds.right() &&
+ pos.y() + grace > pixel_bounds.top() &&
+ pos.y() - bottom_grace < pixel_bounds.bottom());
}
void spline_widget::update_range()
@@ -545,8 +536,6 @@ void spline_widget::focusOutEvent(QFocusEvent* e)
QPointF spline_widget::pixel_coord_to_point(const QPoint& point)
{
- using std::round;
-
qreal x = (point.x() - pixel_bounds.x()) / c.x();
qreal y = (pixel_bounds.height() - point.y() + pixel_bounds.y()) / c.y();
@@ -580,8 +569,8 @@ QPointF spline_widget::pixel_coord_to_point(const QPoint& point)
QPointF spline_widget::point_to_pixel(const QPointF& point)
{
- return QPoint(int(std::round(pixel_bounds.x() + point.x() * c.x())),
- int(std::round(pixel_bounds.y() + pixel_bounds.height() - point.y() * c.y())));
+ return QPoint(iround(pixel_bounds.x() + point.x() * c.x()),
+ iround(pixel_bounds.y() + pixel_bounds.height() - point.y() * c.y()));
}
void spline_widget::resizeEvent(QResizeEvent *)
diff --git a/spline-widget/spline-widget.hpp b/spline-widget/spline-widget.hpp
index d94d2e8e..8886016c 100644
--- a/spline-widget/spline-widget.hpp
+++ b/spline-widget/spline-widget.hpp
@@ -56,6 +56,7 @@ protected slots:
void mouseReleaseEvent(QMouseEvent *e) override;
void reload_spline();
private:
+ int get_closeness_limit();
void show_tooltip(const QPoint& pos, const QPointF& value = QPointF(0, 0), const QString& prefix = QStringLiteral(""));
bool is_in_bounds(const QPoint& pos) const;
@@ -67,7 +68,7 @@ private:
void focusOutEvent(QFocusEvent*e) override;
void resizeEvent(QResizeEvent *) override;
-private:
+
bool is_on_pt(const QPoint& pos, int* pt = nullptr);
void update_range();
QPointF pixel_coord_to_point(const QPoint& point);
@@ -91,5 +92,4 @@ private:
static constexpr int line_length_pixels = 3;
static constexpr int point_size = 4;
- static constexpr int point_closeness_limit = 7;
};