151 lines
5.6 KiB
C++
151 lines
5.6 KiB
C++
#pragma once
|
|
#include <cstddef>
|
|
#include <cstring>
|
|
#include "../Axis/Axis.h"
|
|
#include "../architecture/Bounded_Input_Buffer.h"
|
|
#include "../architecture/Plot_p.h"
|
|
#include "Planisphere.h"
|
|
namespace YSG {
|
|
struct PlanisphereData {
|
|
QPointF mPos;
|
|
int mRemainTimes{};
|
|
int maxTotalTimes{};
|
|
};
|
|
struct Planisphere_Input_Data : Input_Data {
|
|
struct Packet {
|
|
double x{};
|
|
double y{};
|
|
};
|
|
Bounded_Input_Buffer mDataList;
|
|
void push(QPointF pos) {
|
|
Packet packet{pos.x(), pos.y()};
|
|
mDataList.push(&packet, sizeof(packet));
|
|
}
|
|
template <typename Handler>
|
|
void read_all(Handler handler) {
|
|
mDataList.read_all([&handler](const void* data, std::size_t size) {
|
|
(void)size;
|
|
Packet packet;
|
|
std::memcpy(&packet, data, sizeof(packet));
|
|
handler(QPointF(packet.x, packet.y));
|
|
});
|
|
}
|
|
void clear() override {
|
|
mDataList.clear();
|
|
}
|
|
std::uint64_t pending_count() const override {
|
|
return mDataList.pending_count();
|
|
}
|
|
std::uint64_t dropped_count() const override {
|
|
return mDataList.dropped_count();
|
|
}
|
|
std::uint64_t pushed_count() const override {
|
|
return mDataList.pushed_count();
|
|
}
|
|
};
|
|
struct Planisphere_Render_State : Render_State, Planisphere_Prop {};
|
|
struct Planisphere_Private : Typed_Render_Data<Planisphere, Planisphere_Render_State, Planisphere_Input_Data> {
|
|
friend class Planisphere;
|
|
std::list<PlanisphereData> dataList;
|
|
QVector<double> xs, ys;
|
|
QVector<QPointF> fixedPoints;
|
|
void update_fixed_points() {
|
|
Planisphere_Render_State* s = render_state();
|
|
fixedPoints.clear();
|
|
if (s->type == Planisphere_Type::Psk8) {
|
|
double xS = s->i_axis->coord_to_pixel(s->i_range.lower, SRC::Render);
|
|
double yS = s->q_axis->coord_to_pixel(s->q_range.lower, SRC::Render);
|
|
double xL = s->i_axis->coord_to_pixel(s->i_range.upper, SRC::Render) - xS;
|
|
double yL = s->q_axis->coord_to_pixel(s->q_range.upper, SRC::Render) - yS;
|
|
double xSpace = xL / 6.0;
|
|
double ySpace = yL / 6.0;
|
|
double xLineSpace = xL / 4.0;
|
|
double yLineSpace = yL / 4.0;
|
|
fixedPoints.push_back({xS + 2 * xSpace, yS + 1 * ySpace});
|
|
fixedPoints.push_back({xS + 1 * xSpace, yS + 2 * ySpace});
|
|
fixedPoints.push_back({xS + 1 * xSpace, yS + 4 * ySpace});
|
|
fixedPoints.push_back({xS + 2 * xSpace, yS + 5 * ySpace});
|
|
fixedPoints.push_back({xS + 4 * xSpace, yS + 5 * ySpace});
|
|
fixedPoints.push_back({xS + 5 * xSpace, yS + 4 * ySpace});
|
|
fixedPoints.push_back({xS + 5 * xSpace, yS + 2 * ySpace});
|
|
fixedPoints.push_back({xS + 4 * xSpace, yS + 1 * ySpace});
|
|
xs.resize(5);
|
|
ys.resize(5);
|
|
double curX = xS, curY = yS;
|
|
for (int i = 0; i < 5; ++i) {
|
|
xs[i] = curX;
|
|
curX += xLineSpace;
|
|
ys[i] = curY;
|
|
curY += yLineSpace;
|
|
}
|
|
}
|
|
}
|
|
void refresh() {
|
|
for (auto it = dataList.begin(); it != dataList.end();) {
|
|
if (--it->mRemainTimes == 0)
|
|
dataList.erase(it++);
|
|
else
|
|
++it;
|
|
}
|
|
}
|
|
void prepare_data() override {
|
|
sync_state_pipeline();
|
|
Planisphere_Input_Data* d = render_input_data();
|
|
Planisphere_Render_State* s = render_state();
|
|
int times = qMax(5, (s->continue_millisecond * q()->mPlot->d->mRefreshTimesPreSecond) / 1000);
|
|
d->read_all([this, times](const QPointF& pos) {
|
|
PlanisphereData data;
|
|
data.mPos = pos;
|
|
data.maxTotalTimes = times;
|
|
data.mRemainTimes = times;
|
|
dataList.push_back(data);
|
|
});
|
|
clear_render_input();
|
|
refresh();
|
|
}
|
|
void draw(QPainter* painter) override {
|
|
update_fixed_points();
|
|
Planisphere_Render_State* s = render_state();
|
|
{
|
|
double xS = xs.first(), xE = xs.last();
|
|
double yS = ys.first(), yE = ys.last();
|
|
QPen pen;
|
|
pen.setStyle(Qt::DotLine);
|
|
pen.setColor(Qt::white);
|
|
painter->setPen(pen);
|
|
for (double x : xs)
|
|
painter->drawLine(QPointF(x, yS), QPointF(x, yE));
|
|
for (double y : ys)
|
|
painter->drawLine(QPointF(xS, y), QPointF(xE, y));
|
|
}
|
|
{
|
|
painter->setPen(Qt::NoPen);
|
|
for (PlanisphereData& data : dataList) {
|
|
QColor c = s->point_color;
|
|
c.setAlphaF(c.alphaF() * data.mRemainTimes / data.maxTotalTimes);
|
|
painter->setBrush(c);
|
|
double centerX = s->i_axis->coord_to_pixel(data.mPos.x(), SRC::Render);
|
|
double centerY = s->q_axis->coord_to_pixel(data.mPos.y(), SRC::Render);
|
|
double radius = 2;
|
|
painter->drawEllipse({centerX - radius, centerY - radius}, 2 * radius, 2 * radius);
|
|
}
|
|
}
|
|
{
|
|
painter->setPen(QPen(s->anchor_color, 2));
|
|
painter->setBrush(Qt::NoBrush);
|
|
QVector<QPointF>& fixedPoints = this->fixedPoints;
|
|
for (auto& point : fixedPoints) {
|
|
int radius = 6;
|
|
painter->drawLine(QPointF{point.x() - radius, point.y()}, {point.x() + radius, point.y()});
|
|
painter->drawLine(QPointF{point.x(), point.y() - radius}, {point.x(), point.y() + radius});
|
|
}
|
|
}
|
|
}
|
|
void plot_event(QEvent* event) override {
|
|
if (event->type() == QEvent::Resize) {
|
|
auto e = reinterpret_cast<QResizeEvent*>(event);
|
|
}
|
|
}
|
|
};
|
|
} // namespace YSG
|