summaryrefslogtreecommitdiffhomepage
path: root/spline-widget
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2017-03-28 10:49:19 +0200
committerStanislaw Halik <sthalik@misaki.pl>2017-03-28 11:01:31 +0200
commit783739a2f3599e00869f907ed1747491b35486b1 (patch)
tree1b1e5179c30e9feb711ce1e678f5236d97fe1789 /spline-widget
parent8c2ed1d36e1a9d7c0eeabea40f8229d1aa6774d1 (diff)
rename spline-widget -> spline
Adjust usages.
Diffstat (limited to 'spline-widget')
-rw-r--r--spline-widget/CMakeLists.txt2
-rw-r--r--spline-widget/broken/qfunctionconfiguratorplugin.cpp111
-rw-r--r--spline-widget/broken/qfunctionconfiguratorplugin.h36
-rw-r--r--spline-widget/export.hpp27
-rw-r--r--spline-widget/lang/nl_NL.ts4
-rw-r--r--spline-widget/lang/ru_RU.ts4
-rw-r--r--spline-widget/lang/stub.ts4
-rw-r--r--spline-widget/spline-widget.cpp652
-rw-r--r--spline-widget/spline-widget.hpp106
-rw-r--r--spline-widget/spline.cpp469
-rw-r--r--spline-widget/spline.hpp108
11 files changed, 0 insertions, 1523 deletions
diff --git a/spline-widget/CMakeLists.txt b/spline-widget/CMakeLists.txt
deleted file mode 100644
index 5cc25ab8..00000000
--- a/spline-widget/CMakeLists.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-otr_module(spline-widget NO-COMPAT BIN)
-target_link_libraries(opentrack-spline-widget opentrack-options opentrack-compat)
diff --git a/spline-widget/broken/qfunctionconfiguratorplugin.cpp b/spline-widget/broken/qfunctionconfiguratorplugin.cpp
deleted file mode 100644
index 1a9da10a..00000000
--- a/spline-widget/broken/qfunctionconfiguratorplugin.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Copyright (c) 2011-2012 Stanislaw Halik <sthalik@misaki.pl>
- * Adapted to FaceTrackNoIR by Wim Vriend.
- * 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 "qfunctionconfigurator.h"
-
-#include <QtCore/QtPlugin>
-#include "qfunctionconfiguratorplugin.h"
-
-
-QFunctionConfiguratorPlugin::QFunctionConfiguratorPlugin(QObject *parent)
- : QObject(parent)
-{
- initialized = false;
-}
-
-void QFunctionConfiguratorPlugin::initialize(QDesignerFormEditorInterface *)
-{
- if (initialized)
- return;
-
- initialized = true;
-}
-
-bool QFunctionConfiguratorPlugin::isInitialized() const
-{
- return initialized;
-}
-
-QWidget *QFunctionConfiguratorPlugin::createWidget(QWidget *parent)
-{
- return new QFunctionConfigurator(parent);
-}
-
-QString QFunctionConfiguratorPlugin::name() const
-{
- return "QFunctionConfigurator";
-}
-
-QString QFunctionConfiguratorPlugin::group() const
-{
- return "My Plugins";
-}
-
-QIcon QFunctionConfiguratorPlugin::icon() const
-{
- return QIcon();
-}
-
-QString QFunctionConfiguratorPlugin::toolTip() const
-{
- return QString();
-}
-
-QString QFunctionConfiguratorPlugin::whatsThis() const
-{
- return QString();
-}
-
-bool QFunctionConfiguratorPlugin::isContainer() const
-{
- return false;
-}
-
-QString QFunctionConfiguratorPlugin::domXml() const
-{
- return "<widget class=\"QFunctionConfigurator\" name=\"qFunctionA\">\n"
- " <property name=\"geometry\">\n"
- " <rect>\n"
- " <x>0</x>\n"
- " <y>0</y>\n"
- " <width>161</width>\n"
- " <height>220</height>\n"
- " </rect>\n"
- " </property>\n"
- " <property name=\"colorBezier\">\n"
- " <color>\n"
- " <red>255</red>\n"
- " <green>170</green>\n"
- " <blue>0</blue>\n"
- " </color>\n"
- " </property>\n"
- " <property name=\"stringInputEGU\" stdset=\"0\">\n"
- " <string>Input Yaw (degr.)</string>\n"
- " </property>\n"
- " <property name=\"stringOutputEGU\" stdset=\"0\">\n"
- " <string>Output Yaw (degr.)</string>\n"
- " </property>\n"
- " <property name=\"maxInputEGU\" stdset=\"0\">\n"
- " <number>50</number>\n"
- " </property>\n"
- " <property name=\"maxOutputEGU\" stdset=\"0\">\n"
- " <number>180</number>\n"
- " </property>\n"
- " <property name=\"pixPerEGU_Input\" stdset=\"0\">\n"
- " <number>2</number>\n"
- " </property>\n"
- " <property name=\"pixPerEGU_Output\" stdset=\"0\">\n"
- " <number>1</number>\n"
- " </property>\n"
- "</widget>\n";
-}
-
-QString QFunctionConfiguratorPlugin::includeFile() const
-{
- return "qfunctionconfigurator.h";
-}
-
-Q_EXPORT_PLUGIN2(qfunctionconfigurator, QFunctionConfiguratorPlugin)
diff --git a/spline-widget/broken/qfunctionconfiguratorplugin.h b/spline-widget/broken/qfunctionconfiguratorplugin.h
deleted file mode 100644
index ca68e0e2..00000000
--- a/spline-widget/broken/qfunctionconfiguratorplugin.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (c) 2011-2012 Stanislaw Halik <sthalik@misaki.pl>
- * Adapted to FaceTrackNoIR by Wim Vriend.
- * 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.
- */
-#ifndef QFUNCTIONCONFIGURATORPLUGIN_H
-#define QFUNCTIONCONFIGURATORPLUGIN_H
-
-#include <QDesignerCustomWidgetInterface>
-
-class QFunctionConfiguratorPlugin : public QObject, public QDesignerCustomWidgetInterface
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetInterface" FILE "analogclock.json")
- Q_INTERFACES(QDesignerCustomWidgetInterface)
-
-public:
- QFunctionConfiguratorPlugin(QObject *parent = 0);
-
- bool isContainer() const;
- bool isInitialized() const;
- QIcon icon() const;
- QString domXml() const;
- QString group() const;
- QString includeFile() const;
- QString name() const;
- QString toolTip() const;
- QString whatsThis() const;
- QWidget *createWidget(QWidget *parent);
- void initialize(QDesignerFormEditorInterface *core);
-private:
- bool initialized;
-};
-
-#endif // QFUNCTIONCONFIGURATORPLUGIN_H
diff --git a/spline-widget/export.hpp b/spline-widget/export.hpp
deleted file mode 100644
index 4875b4c1..00000000
--- a/spline-widget/export.hpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#pragma once
-
-#ifdef BUILD_spline_widget
-# ifdef _WIN32
-# define OPENTRACK_SPLINE_LINKAGE __declspec(dllexport)
-# else
-# define OPENTRACK_SPLINE_LINKAGE
-# endif
-
-# ifndef _MSC_VER
-# define OPENTRACK_SPLINE_EXPORT __attribute__ ((visibility ("default"))) OPENTRACK_SPLINE_LINKAGE
-# else
-# define OPENTRACK_SPLINE_EXPORT OPENTRACK_SPLINE_LINKAGE
-# endif
-#else
- #ifdef _WIN32
- # define OPENTRACK_SPLINE_LINKAGE __declspec(dllimport)
- #else
- # define OPENTRACK_SPLINE_LINKAGE
- #endif
-
- #ifndef _MSC_VER
- # define OPENTRACK_SPLINE_EXPORT __attribute__ ((visibility ("default"))) OPENTRACK_SPLINE_LINKAGE
- #else
- # define OPENTRACK_SPLINE_EXPORT OPENTRACK_SPLINE_LINKAGE
- #endif
-#endif
diff --git a/spline-widget/lang/nl_NL.ts b/spline-widget/lang/nl_NL.ts
deleted file mode 100644
index 9e739505..00000000
--- a/spline-widget/lang/nl_NL.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE TS>
-<TS version="2.1" language="nl_NL">
-</TS>
diff --git a/spline-widget/lang/ru_RU.ts b/spline-widget/lang/ru_RU.ts
deleted file mode 100644
index f62cf2e1..00000000
--- a/spline-widget/lang/ru_RU.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE TS>
-<TS version="2.1" language="ru_RU">
-</TS>
diff --git a/spline-widget/lang/stub.ts b/spline-widget/lang/stub.ts
deleted file mode 100644
index 6401616d..00000000
--- a/spline-widget/lang/stub.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE TS>
-<TS version="2.1">
-</TS>
diff --git a/spline-widget/spline-widget.cpp b/spline-widget/spline-widget.cpp
deleted file mode 100644
index c7dd5e5a..00000000
--- a/spline-widget/spline-widget.cpp
+++ /dev/null
@@ -1,652 +0,0 @@
-/* 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 "compat/util.hpp"
-#include "spline-widget.hpp"
-#include <QPainter>
-#include <QPainterPath>
-#include <QPaintEvent>
-#include <QPen>
-#include <QPixmap>
-#include <QList>
-#include <QPoint>
-#include <QString>
-#include <QRect>
-#include <QApplication>
-#include <QStyle>
-#include <QMouseEvent>
-
-#include <QDebug>
-
-#include <cmath>
-#include <algorithm>
-
-spline_widget::spline_widget(QWidget *parent) :
- QWidget(parent),
- _config(nullptr),
- snap_x(0),
- snap_y(0),
- _x_step(10),
- _y_step(10),
- moving_control_point_idx(-1),
- _draw_function(true),
- _preview_only(false)
-{
- setMouseTracking(true);
- setFocusPolicy(Qt::ClickFocus);
- setCursor(Qt::ArrowCursor);
-}
-
-spline_widget::~spline_widget()
-{
- if (connection)
- QObject::disconnect(connection);
-}
-
-void spline_widget::setConfig(spline* spl)
-{
- if (spl != _config)
- {
- if (connection)
- {
- QObject::disconnect(connection);
- connection = QMetaObject::Connection();
- }
-
- if (spl)
- {
- mem<spline::settings> s = spl->get_settings();
- connection = connect(s.get(), &spline::settings::recomputed,
- this, [this]() { reload_spline(); },
- Qt::QueuedConnection);
- }
-
- _config = spl;
- _background = QPixmap();
- update_range();
- }
-}
-
-QColor spline_widget::colorBezier() const
-{
- return spline_color;
-}
-
-void spline_widget::setColorBezier(QColor color)
-{
- spline_color = color;
- update();
-}
-
-void spline_widget::force_redraw()
-{
- _background = QPixmap();
- update();
-}
-
-void spline_widget::set_preview_only(bool val)
-{
- _preview_only = val;
-}
-
-bool spline_widget::is_preview_only() const
-{
- return _preview_only;
-}
-
-void spline_widget::drawBackground()
-{
- _background = QPixmap(width(), height());
-
- QPainter painter(&_background);
-
- painter.fillRect(rect(), palette().color(QPalette::Light));
-
- QColor bg_color(112, 154, 209);
- if (!isEnabled() && !_preview_only)
- bg_color = QColor(176,176,180);
- painter.fillRect(pixel_bounds, bg_color);
-
- QFont font;
- font.setPointSize(8);
- painter.setFont(font);
- QFontMetrics metrics(font);
-
- QColor color__(176, 190, 209, 127);
-
- if (!isEnabled())
- color__ = QColor(70, 90, 100, 96);
-
- const QPen pen(color__, 1, Qt::SolidLine, Qt::FlatCap);
-
- const int ystep = _y_step, xstep = _x_step;
- const qreal maxx = _config->max_input();
- const qreal maxy = _config->max_output();
-
- // horizontal grid
- for (int i = 0; i <= maxy; i += ystep)
- {
- const int y = int(pixel_bounds.height() - i * c.y() + pixel_bounds.y());
- drawLine(painter,
- QPoint(pixel_bounds.x(), y),
- QPoint(pixel_bounds.x() + pixel_bounds.width(), y),
- pen);
- painter.drawText(QRectF(10,
- y - metrics.height()/2.,
- pixel_bounds.left(),
- metrics.height()),
- QString::number(i));
- }
-
- // vertical grid
- for (int i = 0; i <= maxx; i += xstep)
- {
- 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()),
- 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()),
- text);
- }
-}
-
-void spline_widget::drawFunction()
-{
- _function = _background;
- QPainter painter(&_function);
- painter.setRenderHint(QPainter::Antialiasing, true);
-
- const points_t points = _config->get_points();
-
- if (moving_control_point_idx >= 0 &&
- moving_control_point_idx < points.size())
- {
- const QPen pen(Qt::white, 1, Qt::SolidLine, Qt::FlatCap);
- const QPointF prev_ = point_to_pixel(QPointF(0, 0));
- 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(iround(tmp_.x()), iround(tmp_.y()));
- drawLine(painter, prev, tmp, pen);
- prev = tmp;
- }
- }
-
- const QColor color = progn
- (
- if (!isEnabled() && !_preview_only)
- {
- QColor color(spline_color);
- const int avg = int(float(color.red() + color.green() + color.blue())/3);
- return QColor(int(float(color.red() + avg) * .5f),
- int(float(color.green() + avg) * .5f),
- int(float(color.blue() + avg) * .5f),
- 96);
- }
- else
- {
- QColor color(spline_color);
- color.setAlphaF(color.alphaF() * .9);
- return color;
- }
- );
-
- painter.setPen(QPen(color, 1.75, Qt::SolidLine, Qt::FlatCap));
-
-//#define DEBUG_SPLINE
-#ifndef DEBUG_SPLINE
- static constexpr double step_ = 3./3;
-
- const double maxx = _config->max_input();
- const double step = step_ / c.x();
-
- QPainterPath path;
-
- path.moveTo(point_to_pixel(QPointF(0, 0)));
-
- for (double k = 0; k < maxx; k += step*3)
- {
- const float next_1(_config->get_value_no_save(k + step*1));
- const float next_2(_config->get_value_no_save(k + step*2));
- const float next_3(_config->get_value_no_save(k + step*3));
-
- const QPointF b(point_to_pixel_(QPointF(k + step*1, qreal(next_1)))),
- c(point_to_pixel_(QPointF(k + step*2, qreal(next_2)))),
- d(point_to_pixel_(QPointF(k + step*3, qreal(next_3))));
-
- path.cubicTo(b, c, d);
- }
-
- painter.drawPath(path);
-#else
- static constexpr int line_length_pixels = 3;
- const qreal max = _config->maxInput();
- const qreal step = clamp(line_length_pixels / c.x(), 5e-2, max);
- QPointF prev = point_to_pixel(QPoint(0, 0));
- for (qreal i = 0; i < max; i += step)
- {
- const qreal val = qreal(_config->get_value_no_save(i));
- const QPointF cur = point_to_pixel(QPointF(i, val));
- painter.drawLine(prev, cur);
- prev = cur;
- }
- {
- const qreal maxx = _config->maxInput();
- const qreal maxy = qreal(_config->get_value_no_save(maxx));
- painter.drawLine(QPointF(prev), point_to_pixel_(QPointF(maxx, maxy)));
- }
-#endif
-
- const int alpha = !isEnabled() ? 64 : 120;
- if (!_preview_only)
- {
- for (int i = 0; i < points.size(); i++)
- {
- drawPoint(painter,
- point_to_pixel(points[i]),
- QColor(200, 200, 210, alpha),
- isEnabled() ? QColor(50, 100, 120, 200) : QColor(200, 200, 200, 96));
- }
- }
-}
-
-void spline_widget::paintEvent(QPaintEvent *e)
-{
- if (!_config)
- return;
-
- QPainter p(this);
-
- if (_background.isNull())
- {
- _draw_function = true;
- drawBackground();
- }
-
- if (_draw_function)
- {
- _draw_function = false;
- drawFunction();
- }
-
- p.drawPixmap(e->rect(), _function);
-
- // 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())
- drawPoint(p, point_to_pixel(last), QColor(255, 0, 0, 120));
-}
-
-void spline_widget::drawPoint(QPainter& painter, const QPointF& pos, const QColor& colBG, const QColor& border)
-{
- painter.save();
- painter.setPen(QPen(border, 1, Qt::SolidLine, Qt::PenCapStyle::FlatCap));
- painter.setBrush(colBG);
- painter.drawEllipse(QRectF(pos.x() - point_size,
- pos.y() - point_size,
- point_size*2, point_size*2));
- painter.restore();
-}
-
-void spline_widget::drawLine(QPainter& painter, const QPoint& start, const QPoint& end, const QPen& pen)
-{
- painter.save();
- painter.setPen(pen);
- painter.setBrush(Qt::NoBrush);
- painter.drawLine(start, end);
- painter.restore();
-}
-
-void spline_widget::mousePressEvent(QMouseEvent *e)
-{
- if (!_config || !isEnabled() || !is_in_bounds(e->pos()))
- {
- clearFocus();
- return;
- }
-
- const int point_pixel_closeness_limit = get_closeness_limit();
-
- points_t points = _config->get_points();
- if (e->button() == Qt::LeftButton)
- {
- bool bTouchingPoint = false;
- moving_control_point_idx = -1;
- for (int i = 0; i < points.size(); i++)
- {
- if (point_within_pixel(points[i], e->pos()))
- {
- bTouchingPoint = true;
- moving_control_point_idx = int(i);
- break;
- }
- }
- if (!bTouchingPoint)
- {
- bool too_close = false;
- 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_pixel_closeness_limit >= x)
- {
- too_close = true;
- break;
- }
- }
-
- if (!too_close)
- {
- _config->add_point(pixel_coord_to_point(e->pos()));
- show_tooltip(e->pos());
- }
- }
- }
-
- if (e->button() == Qt::RightButton)
- {
- if (_config)
- {
- int found_pt = -1;
- for (int i = 0; i < points.size(); i++)
- {
- if (point_within_pixel(points[i], e->pos()))
- {
- found_pt = i;
- break;
- }
- }
-
- if (found_pt != -1)
- {
- _config->remove_point(found_pt);
- }
- moving_control_point_idx = -1;
- }
- }
- _draw_function = true;
- update();
-}
-
-void spline_widget::mouseMoveEvent(QMouseEvent *e)
-{
- if (_preview_only && _config)
- {
- show_tooltip(e->pos());
- clearFocus();
- return;
- }
-
- if (!_config || !isEnabled() || !isActiveWindow() || (moving_control_point_idx != -1 && !hasFocus()))
- {
- clearFocus();
- return;
- }
-
- const int i = moving_control_point_idx;
- const points_t points = _config->get_points();
- const int sz = points.size();
-
- if (i >= 0 && i < sz)
- {
- const int point_pixel_closeness_limit = get_closeness_limit();
- bool overlap = false;
-
- 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(e->pos());
-
- if (i + 1 < points.size())
- {
- const QPointF other_pix = point_to_pixel(points[i+1]);
- overlap |= other_pix.x() - pix.x() < point_pixel_closeness_limit;
- }
- if (i != 0)
- {
- 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->move_point(i, new_pt);
- _draw_function = true;
-
- setCursor(Qt::ClosedHandCursor);
- show_tooltip(pix, new_pt);
- update();
- }
- else if (sz)
- {
- int i;
- bool is_on_point = is_on_pt(e->pos(), &i);
-
- if (is_on_point)
- {
- setCursor(Qt::CrossCursor);
- show_tooltip(e->pos(), points[i]);
- }
- else
- {
- setCursor(Qt::ArrowCursor);
- if (is_in_bounds(e->pos()))
- show_tooltip(e->pos());
- else
- QToolTip::hideText();
- }
- }
-}
-
-void spline_widget::mouseReleaseEvent(QMouseEvent *e)
-{
- if (!_config || !isEnabled() || !isActiveWindow() || !hasFocus())
- {
- clearFocus();
- return;
- }
-
- if (e->button() == Qt::LeftButton)
- {
- {
- if (is_on_pt(e->pos(), nullptr))
- setCursor(Qt::CrossCursor);
- else
- setCursor(Qt::ArrowCursor);
- }
- moving_control_point_idx = -1;
- _draw_function = true;
-
- if (is_in_bounds(e->pos()))
- show_tooltip(e->pos());
- else
- QToolTip::hideText();
-
- update();
- }
-}
-
-void spline_widget::reload_spline()
-{
- // don't recompute here as the value's about to be recomputed in the callee
- 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 QPointF value = QPoint(0, 0) == value_ ? pixel_coord_to_point(pos) : value_;
-
- double x = value.x(), y = value.y();
-
- if (_preview_only)
- y = _config->get_value_no_save(x);
-
- const int x_ = iround(x), y_ = iround(y);
-
- using std::fabs;
-
- if (fabs(x_ - x) < 1e-3)
- x = x_;
- if (fabs(y_ - y) < 1e-3)
- y = y_;
-
- const bool is_fusion = QStringLiteral("fusion") == QApplication::style()->objectName();
- const int add_x = (is_fusion ? 25 : 0), add_y = (is_fusion ? 15 : 0);
-
- const QPoint pix(int(pos.x()) + add_x, int(pos.y()) + add_y);
-
- QToolTip::showText(mapToGlobal(pix),
- QStringLiteral("value: %1x%2").arg(x).arg(y),
- this,
- rect(),
- 0);
-}
-
-bool spline_widget::is_in_bounds(const QPoint& pos) const
-{
- 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()
-{
- 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 = QPointF(pixel_bounds.width() / _config->max_input(), pixel_bounds.height() / _config->max_output());
- _draw_function = true;
-
- _background = QPixmap();
- _function = QPixmap();
-
- update();
-}
-
-bool spline_widget::point_within_pixel(const QPointF& pt, const QPoint &pixel)
-{
- const QPointF tmp = pixel - point_to_pixel(pt);
- return QPointF::dotProduct(tmp, tmp) < point_size * point_size;
-}
-
-void spline_widget::focusOutEvent(QFocusEvent* e)
-{
- if (moving_control_point_idx != -1)
- QToolTip::hideText();
- moving_control_point_idx = -1;
- _draw_function = true;
- lower();
- setCursor(Qt::ArrowCursor);
- e->accept();
-}
-
-QPointF spline_widget::pixel_coord_to_point(const QPoint& point)
-{
- qreal x = (point.x() - pixel_bounds.x()) / c.x();
- qreal y = (pixel_bounds.height() - point.y() + pixel_bounds.y()) / c.y();
-
- static constexpr int c = 1000;
-
- if (snap_x > 0)
- {
- x += snap_x * .5;
- x -= std::fmod(x, snap_x);
- // truncate after few decimal places to reduce rounding errors.
- // round upward to nearest.
- x = int(x * c + .5/c) / double(c);
- }
- if (snap_y > 0)
- {
- y += snap_y * .5;
- y -= std::fmod(y, snap_y);
- // idem
- y = int(y * c + .5/c) / double(c);
- }
-
- if (x < 0)
- x = 0;
- if (x > _config->max_input())
- x = _config->max_input();
-
- if (y < 0)
- y = 0;
- if (y > _config->max_output())
- y = _config->max_output();
-
- return QPointF(x, y);
-}
-
-QPointF spline_widget::point_to_pixel_(const QPointF& point)
-{
- return QPointF(pixel_bounds.x() + point.x() * c.x(),
- pixel_bounds.y() + pixel_bounds.height() - point.y() * c.y());
-}
-
-QPoint spline_widget::point_to_pixel(const QPointF& point)
-{
- QPointF pt(point_to_pixel_(point));
-
- return QPoint(iround(pt.x()), iround(pt.y()));
-}
-
-void spline_widget::resizeEvent(QResizeEvent *)
-{
- update_range();
-}
-
-bool spline_widget::is_on_pt(const QPoint& pos, int* pt)
-{
- if (!_config)
- {
- if (pt)
- *pt = -1;
- return false;
- }
-
- const points_t points = _config->get_points();
-
- for (int i = 0; i < points.size(); i++)
- {
- if (point_within_pixel(points[i], pos))
- {
- if (pt)
- *pt = i;
- return true;
- }
- }
-
- if (pt)
- *pt = -1;
- return false;
-}
diff --git a/spline-widget/spline-widget.hpp b/spline-widget/spline-widget.hpp
deleted file mode 100644
index 4d5a7680..00000000
--- a/spline-widget/spline-widget.hpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/* 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.
- */
-
-// Adapted to FaceTrackNoIR by Wim Vriend.
-
-#pragma once
-
-#include "spline.hpp"
-#include "api/plugin-api.hpp"
-#include "options/options.hpp"
-using namespace options;
-
-#include "export.hpp"
-
-#include <QWidget>
-#include <QRect>
-#include <QPoint>
-#include <QPointF>
-#include <QToolTip>
-#include <QShowEvent>
-#include <QFocusEvent>
-#include <QMetaObject>
-
-#include <QDebug>
-
-class OPENTRACK_SPLINE_EXPORT spline_widget final : public QWidget
-{
- Q_OBJECT
- Q_PROPERTY(QColor colorBezier READ colorBezier WRITE setColorBezier)
- Q_PROPERTY(bool is_preview_only READ is_preview_only WRITE set_preview_only)
- Q_PROPERTY(int x_step READ x_step WRITE set_x_step)
- Q_PROPERTY(int y_step READ y_step WRITE set_y_step)
-
- using points_t = spline::points_t;
-public:
- spline_widget(QWidget *parent = 0);
- ~spline_widget();
-
- spline* config();
- void setConfig(spline* spl);
-
- QColor colorBezier() const;
- void setColorBezier(QColor color);
-
- void force_redraw();
- void set_preview_only(bool val);
- bool is_preview_only() const;
-
- double x_step() { return _x_step; }
- double y_step() { return _y_step; }
- void set_x_step(double val) { _x_step = val; }
- void set_y_step(double val) { _y_step = val; }
-
- void set_snap(double x, double y) { snap_x = x; snap_y = y; }
- void get_snap(double& x, double& y) const { x = snap_x; y = snap_y; }
-public slots:
- void reload_spline();
-protected slots:
- void paintEvent(QPaintEvent *e) override;
- void mousePressEvent(QMouseEvent *e) override;
- void mouseMoveEvent(QMouseEvent *e) override;
- void mouseReleaseEvent(QMouseEvent *e) override;
-private:
- int get_closeness_limit();
- void show_tooltip(const QPoint& pos, const QPointF& value = QPointF(0, 0));
- bool is_in_bounds(const QPoint& pos) const;
-
- void drawBackground();
- void drawFunction();
- void drawPoint(QPainter& painter, const QPointF& pt, const QColor& colBG, const QColor& border = QColor(50, 100, 120, 200));
- void drawLine(QPainter& painter, const QPoint& start, const QPoint& end, const QPen& pen);
- bool point_within_pixel(const QPointF& pt, const QPoint& pixel);
-
- void focusOutEvent(QFocusEvent*e) override;
- void resizeEvent(QResizeEvent *) override;
-
- bool is_on_pt(const QPoint& pos, int* pt = nullptr);
- void update_range();
- QPointF pixel_coord_to_point(const QPoint& point);
-
- QPointF point_to_pixel_(const QPointF& point);
- QPoint point_to_pixel(const QPointF& point);
-
- QPointF c;
- spline* _config;
-
- QPixmap _background;
- QPixmap _function;
- QColor spline_color;
-
- // bounds of the rectangle user can interact with
- QRect pixel_bounds;
-
- QMetaObject::Connection connection;
-
- double snap_x, snap_y;
- double _x_step, _y_step;
- int moving_control_point_idx;
- bool _draw_function, _preview_only;
-
- static constexpr int point_size = 4;
-};
diff --git a/spline-widget/spline.cpp b/spline-widget/spline.cpp
deleted file mode 100644
index 2db23c14..00000000
--- a/spline-widget/spline.cpp
+++ /dev/null
@@ -1,469 +0,0 @@
-/* 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.hpp"
-
-#include <algorithm>
-#include <cmath>
-#include <memory>
-
-#include <QObject>
-#include <QMutexLocker>
-#include <QCoreApplication>
-#include <QPointF>
-#include <QSettings>
-#include <QString>
-
-#include <QDebug>
-
-constexpr int spline::value_count;
-
-spline::spline(qreal maxx, qreal maxy, const QString& name) :
- s(nullptr),
- data(value_count, -1.f),
- _mutex(QMutex::Recursive),
- max_x(maxx),
- max_y(maxy),
- activep(false),
- validp(false)
-{
- set_bundle(options::make_bundle(name));
-}
-
-spline::~spline()
-{
- QMutexLocker l(&_mutex);
-
- if (connection)
- {
- QObject::disconnect(connection);
- connection = QMetaObject::Connection();
- }
-}
-
-spline::spline() : spline(0, 0, "") {}
-
-void spline::set_tracking_active(bool value)
-{
- activep = value;
-}
-
-bundle spline::get_bundle()
-{
- return s->b;
-}
-
-void spline::clear()
-{
- QMutexLocker l(&_mutex);
- s->points = points_t();
- validp = false;
-}
-
-void spline::set_max_input(qreal max_input)
-{
- QMutexLocker l(&_mutex);
- max_x = max_input;
- recompute();
-}
-
-void spline::set_max_output(qreal max_output)
-{
- QMutexLocker l(&_mutex);
- max_y = max_output;
- recompute();
-}
-
-qreal spline::max_input() const
-{
- QMutexLocker l(&_mutex);
- return max_x;
-}
-
-qreal spline::max_output() const
-{
- QMutexLocker l(&_mutex);
- return max_y;
-}
-
-float spline::get_value(double x)
-{
- QMutexLocker foo(&_mutex);
-
- const float ret = get_value_no_save(x);
- last_input_value.setX(std::fabs(x));
- last_input_value.setY(double(std::fabs(ret)));
- return ret;
-}
-
-float spline::get_value_no_save(double x) const
-{
- return const_cast<spline&>(*this).get_value_no_save_internal(x);
-}
-
-float spline::get_value_no_save_internal(double x)
-{
- QMutexLocker foo(&_mutex);
-
- if (max_x > 0)
- x = std::min(max_x, x);
-
- float q = float(x * precision(s->points));
- int xi = (int)q;
- float yi = get_value_internal(xi);
- float yiplus1 = get_value_internal(xi+1);
- float f = (q-xi);
- float ret = yiplus1 * f + yi * (1.0f - f); // at least do a linear interpolation.
- return ret;
-}
-
-DEFUN_WARN_UNUSED bool spline::get_last_value(QPointF& point)
-{
- QMutexLocker foo(&_mutex);
- point = last_input_value;
- return activep;
-}
-
-float spline::get_value_internal(int x)
-{
- if (!validp)
- {
- update_interp_data();
- validp = true;
- }
-
- float sign = x < 0 ? -1 : 1;
- x = std::abs(x);
- float ret;
- ret = data[std::min(unsigned(x), unsigned(value_count)-1u)];
- return ret * sign;
-}
-
-void spline::add_lone_point()
-{
- points_t points;
- points.push_back(QPointF(max_x, max_y));
-
- s->points = points;
-}
-
-QPointF spline::ensure_in_bounds(const QList<QPointF>& points, double max_x, int i)
-{
- const int sz = element_count(points, max_x);
-
- if (i < 0 || sz == 0)
- return QPointF(0, 0);
-
- if (i < sz)
- return points[i];
-
- return points[sz - 1];
-}
-
-int spline::element_count(const QList<QPointF>& points, double max_x)
-{
- if (!(max_x > 0))
- return points.size();
- else
- {
- const unsigned sz = points.size();
- for (unsigned i = 0; i < sz; i++)
- {
- if (!(points[i].x() <= max_x))
- return i;
- }
- return points.size();
- }
-}
-
-bool spline::sort_fn(const QPointF& one, const QPointF& two)
-{
- return one.x() <= two.x();
-}
-
-void spline::update_interp_data()
-{
- points_t points = s->points;
-
- int sz = element_count(points, max_x);
-
- if (sz == 0)
- points.prepend(QPointF(max_x, max_y));
-
- std::stable_sort(points.begin(), points.begin() + sz, sort_fn);
-
- const double mult = precision(points);
- const double mult_ = mult * 30;
-
- for (unsigned i = 0; i < value_count; i++)
- data[i] = -1;
-
- if (sz < 2)
- {
- if (points[0].x() - 1e-2 <= max_x)
- {
- const double x = points[0].x();
- const double y = points[0].y();
- const int max = clamp(int(x * precision(points)), 1, value_count-1);
- for (int k = 0; k <= max; k++)
- {
- if (k < value_count)
- data[unsigned(k)] = float(y * k / max);
- }
- }
- }
- else
- {
- if (points[0].x() > 1e-2 && points[0].x() <= max_x)
- points.push_front(QPointF(0, 0));
-
- for (int i = 0; i < sz; i++)
- {
- const QPointF p0 = ensure_in_bounds(points, max_x, i - 1);
- const QPointF p1 = ensure_in_bounds(points, max_x, i + 0);
- const QPointF p2 = ensure_in_bounds(points, max_x, i + 1);
- const QPointF p3 = ensure_in_bounds(points, max_x, i + 2);
- const double p0_x = p0.x(), p1_x = p1.x(), p2_x = p2.x(), p3_x = p3.x();
- const double p0_y = p0.y(), p1_y = p1.y(), p2_y = p2.y(), p3_y = p3.y();
-
- const double cx[4] = {
- 2 * p1_x, // 1
- -p0_x + p2_x, // t
- 2 * p0_x - 5 * p1_x + 4 * p2_x - p3_x, // t^2
- -p0_x + 3 * p1_x - 3 * p2_x + p3_x, // t3
- };
-
- const double cy[4] =
- {
- 2 * p1_y, // 1
- -p0_y + p2_y, // t
- 2 * p0_y - 5 * p1_y + 4 * p2_y - p3_y, // t^2
- -p0_y + 3 * p1_y - 3 * p2_y + p3_y, // t3
- };
-
- // multiplier helps fill in all the x's needed
- const unsigned end = std::min(unsigned(value_count), unsigned(p2_x * mult_));
- const unsigned start = std::max(0u, unsigned(p1_x * mult));
-
- for (unsigned j = start; j < end; j++)
- {
- const double t = (j - start) / (double) (end - start);
- const double t2 = t*t;
- const double t3 = t*t*t;
-
- const int x = iround(.5 * mult * (cx[0] + cx[1] * t + cx[2] * t2 + cx[3] * t3));
- const float y = float(.5 * (cy[0] + cy[1] * t + cy[2] * t2 + cy[3] * t3));
-
- if (x >= 0 && x < value_count)
- data[unsigned(x)] = y;
- }
- }
- }
-
- float last = 0;
- for (unsigned i = 0; i < unsigned(value_count); i++)
- {
- if (data[i] < 0)
- data[i] = last;
- last = data[i];
- }
-}
-
-void spline::remove_point(int i)
-{
- QMutexLocker foo(&_mutex);
-
- points_t points = s->points;
- const int sz = element_count(points, max_x);
-
- if (i >= 0 && i < sz)
- {
- points.erase(points.begin() + i);
- s->points = points;
- validp = false;
- }
-}
-
-void spline::add_point(QPointF pt)
-{
- QMutexLocker foo(&_mutex);
-
- points_t points = s->points;
- points.push_back(pt);
- std::stable_sort(points.begin(), points.end(), sort_fn);
- s->points = points;
- validp = false;
-}
-
-void spline::add_point(double x, double y)
-{
- add_point(QPointF(x, y));
-}
-
-void spline::move_point(int idx, QPointF pt)
-{
- QMutexLocker foo(&_mutex);
-
- points_t points = s->points;
-
- const int sz = element_count(points, max_x);
-
- if (idx >= 0 && idx < sz)
- {
- points[idx] = pt;
- // we don't allow points to be reordered, but sort due to possible caller logic error
- std::stable_sort(points.begin(), points.end(), sort_fn);
- s->points = points;
- validp = false;
- }
-}
-
-QList<QPointF> spline::get_points() const
-{
- QMutexLocker foo(&_mutex);
- return s->points;
-}
-
-int spline::get_point_count() const
-{
- QMutexLocker foo(&_mutex);
- return element_count(s->points, max_x);;
-}
-
-void spline::reload()
-{
- QMutexLocker foo(&_mutex);
- s->b->reload();
-}
-
-void spline::save(QSettings& settings)
-{
- QMutexLocker foo(&_mutex);
- s->b->save_deferred(settings);
-}
-
-void spline::save()
-{
- save(*group::ini_file());
-}
-
-void spline::set_bundle(bundle b)
-{
- QMutexLocker l(&_mutex);
-
- // gets called from ctor hence the need for nullptr checks
- // the sentinel settings/bundle objects don't need any further branching once created
- if (!s || s->b != b)
- {
- s = std::make_shared<settings>(b);
-
- if (connection)
- QObject::disconnect(connection);
-
- if (b)
- {
- connection = QObject::connect(b.get(), &bundle_::changed,
- s.get(), [&]() {
- // we're holding the mutex to allow signal disconnection in spline dtor
- // before this slot gets called for the next time
-
- // spline isn't a QObject and the connection context is incorrect
-
- QMutexLocker l(&_mutex);
- recompute();
- emit s->recomputed();
- },
- Qt::QueuedConnection);
- }
-
- recompute();
-
- emit s->recomputed();
- }
-}
-
-void spline::recompute()
-{
- QMutexLocker foo(&_mutex);
-
- QList<QPointF> list = s->points;
-
- // storing to s->points fires bundle::changed and that leads to an infinite loop
- // only store if we can't help it
- std::stable_sort(list.begin(), list.end(), sort_fn);
-
- if (list != s->points)
- s->points = list;
-
- const int sz = list.size();
-
- QList<QPointF> ret_list;
- ret_list.reserve(sz);
-
- for (int i = 0; i < sz; i++)
- {
- QPointF& pt(list[i]);
-
- const bool overlap = progn(
- for (int j = 0; j < i; j++)
- {
- QPointF& pt2(list[j]);
- const double dist_sq = (pt.x() - pt2.x())*(pt.x() - pt2.x());
- static constexpr double overlap = .6;
- if (dist_sq < overlap * overlap)
- return true;
- }
- return false;
- );
- if (!overlap)
- ret_list.push_back(pt);
- }
-
- if (ret_list != s->points)
- s->points = ret_list;
-
- last_input_value = QPointF(0, 0);
- activep = false;
- validp = false;
-}
-
-// the return value is only safe to use with no spline::set_bundle calls
-mem<spline::settings> spline::get_settings()
-{
- QMutexLocker foo(&_mutex);
- return s;
-}
-
-mem<const spline::settings> spline::get_settings() const
-{
- QMutexLocker foo(&_mutex);
- return s;
-}
-
-double spline::precision(const QList<QPointF>& points) const
-{
- // this adjusts the memoized range to the largest X value. empty space doesn't take value_count discrete points.
- const int sz = element_count(points, max_x);
- if (sz)
- return clamp(value_count / clamp(points[sz - 1].x(), 1., max_x), 0., double(value_count));
-
- return value_count / clamp(max_x, 1., double(value_count));
-}
-
-namespace spline_detail {
-
-settings::settings(bundle b):
- b(b ? b : make_bundle("")),
- points(b, "points", QList<QPointF>())
-{}
-
-settings::~settings()
-{
-}
-
-}
diff --git a/spline-widget/spline.hpp b/spline-widget/spline.hpp
deleted file mode 100644
index 77b2bdf9..00000000
--- a/spline-widget/spline.hpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/* 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.
- */
-
-#pragma once
-
-#include "compat/qcopyable-mutex.hpp"
-#include "options/options.hpp"
-#include "compat/util.hpp"
-using namespace options;
-
-#include "export.hpp"
-
-#include <vector>
-#include <limits>
-#include <memory>
-
-#include <QObject>
-#include <QPointF>
-#include <QString>
-#include <QMetaObject>
-
-namespace spline_detail {
-
-class OPENTRACK_SPLINE_EXPORT settings final : public QObject
-{
- Q_OBJECT
-public:
- bundle b;
- value<QList<QPointF>> points;
- settings(bundle b);
- ~settings() override;
-signals:
- void recomputed() const;
-};
-
-}
-
-class OPENTRACK_SPLINE_EXPORT spline final
-{
- double precision(const QList<QPointF>& points) const;
- void update_interp_data();
- float get_value_internal(int x);
- void add_lone_point();
- float get_value_no_save_internal(double x);
- static bool sort_fn(const QPointF& one, const QPointF& two);
-
- static QPointF ensure_in_bounds(const QList<QPointF>& points, double max_x, int i);
- static int element_count(const QList<QPointF>& points, double max_x);
-
- mem<spline_detail::settings> s;
- QMetaObject::Connection connection;
-
- std::vector<float> data;
- using interp_data_t = decltype(data);
-
- static constexpr int value_count = 4096;
-
- MyMutex _mutex;
- QPointF last_input_value;
- qreal max_x, max_y;
- volatile bool activep;
- bool validp;
-
-public:
- using settings = spline_detail::settings;
-
- void reload();
- void save(QSettings& s);
- void save();
- void set_bundle(bundle b);
-
- qreal max_input() const;
- qreal max_output() const;
- spline();
- spline(qreal maxx, qreal maxy, const QString& name);
- ~spline();
-
- spline& operator=(const spline&) = default;
- spline(const spline&) = default;
-
- float get_value(double x);
- float get_value_no_save(double x) const;
- DEFUN_WARN_UNUSED bool get_last_value(QPointF& point);
- void remove_point(int i);
- void clear();
-
- void add_point(QPointF pt);
- void add_point(double x, double y);
- void move_point(int idx, QPointF pt);
- QList<QPointF> get_points() const;
- void set_max_input(qreal MaxInput);
- void set_max_output(qreal MaxOutput);
-
- void set_tracking_active(bool value);
- bundle get_bundle();
- void recompute();
-
- mem<settings> get_settings();
- mem<const settings> get_settings() const;
-
- using points_t = decltype(s->points());
- int get_point_count() const;
-};