Customizable constant lines in smith chart
This commit is contained in:
parent
483618befb
commit
cd106b3040
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>307</width>
|
<width>856</width>
|
||||||
<height>255</height>
|
<height>259</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -16,7 +16,11 @@
|
|||||||
<property name="modal">
|
<property name="modal">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="0,0">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,1">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
@ -97,6 +101,80 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
|
<property name="title">
|
||||||
|
<string>Constant Lines</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QTableView" name="lineTable">
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||||
|
</property>
|
||||||
|
<property name="selectionBehavior">
|
||||||
|
<enum>QAbstractItemView::SelectRows</enum>
|
||||||
|
</property>
|
||||||
|
<attribute name="horizontalHeaderMinimumSectionSize">
|
||||||
|
<number>20</number>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="horizontalHeaderStretchLastSection">
|
||||||
|
<bool>true</bool>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="verticalHeaderVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="verticalHeaderDefaultSectionSize">
|
||||||
|
<number>21</number>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="addLine">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="list-add" resource="../icons.qrc">
|
||||||
|
<normaloff>:/icons/add.png</normaloff>:/icons/add.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="removeLine">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="list-remove" resource="../icons.qrc">
|
||||||
|
<normaloff>:/icons/remove.png</normaloff>:/icons/remove.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@ -116,7 +194,9 @@
|
|||||||
<header>CustomWidgets/siunitedit.h</header>
|
<header>CustomWidgets/siunitedit.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources/>
|
<resources>
|
||||||
|
<include location="../icons.qrc"/>
|
||||||
|
</resources>
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
<sender>buttonBox</sender>
|
<sender>buttonBox</sender>
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QColorDialog>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -35,6 +36,11 @@ nlohmann::json TraceSmithChart::toJSON()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
j["traces"] = jtraces;
|
j["traces"] = jtraces;
|
||||||
|
nlohmann::json jlines;
|
||||||
|
for(auto line : constantLines) {
|
||||||
|
jlines.push_back(line.toJSON());
|
||||||
|
}
|
||||||
|
j["constantLines"] = jlines;
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,6 +63,13 @@ void TraceSmithChart::fromJSON(nlohmann::json j)
|
|||||||
qWarning() << "Unable to find trace with hash" << hash;
|
qWarning() << "Unable to find trace with hash" << hash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(j.contains("constantLines")) {
|
||||||
|
for(auto jline : j["constantLines"]) {
|
||||||
|
SmithChartConstantLine line;
|
||||||
|
line.fromJSON(jline);
|
||||||
|
constantLines.push_back(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TraceSmithChart::wheelEvent(QWheelEvent *event)
|
void TraceSmithChart::wheelEvent(QWheelEvent *event)
|
||||||
@ -91,6 +104,12 @@ void TraceSmithChart::axisSetupDialog()
|
|||||||
ui->zoomFactor->setPrecision(3);
|
ui->zoomFactor->setPrecision(3);
|
||||||
ui->zoomReflection->setValue(edgeReflection);
|
ui->zoomReflection->setValue(edgeReflection);
|
||||||
ui->zoomFactor->setValue(1.0/edgeReflection);
|
ui->zoomFactor->setValue(1.0/edgeReflection);
|
||||||
|
|
||||||
|
auto model = new SmithChartContantLineModel(*this);
|
||||||
|
ui->lineTable->setModel(model);
|
||||||
|
ui->lineTable->setItemDelegateForColumn(SmithChartContantLineModel::ColIndexType, new SmithChartTypeDelegate);
|
||||||
|
ui->lineTable->setItemDelegateForColumn(SmithChartContantLineModel::ColIndexParam, new SmithChartParamDelegate);
|
||||||
|
|
||||||
connect(ui->buttonBox, &QDialogButtonBox::accepted, [=](){
|
connect(ui->buttonBox, &QDialogButtonBox::accepted, [=](){
|
||||||
limitToSpan = ui->displayModeFreq->currentIndex() == 1;
|
limitToSpan = ui->displayModeFreq->currentIndex() == 1;
|
||||||
limitToEdge = ui->displayModeImp->currentIndex() == 1;
|
limitToEdge = ui->displayModeImp->currentIndex() == 1;
|
||||||
@ -104,6 +123,48 @@ void TraceSmithChart::axisSetupDialog()
|
|||||||
edgeReflection = ui->zoomReflection->value();
|
edgeReflection = ui->zoomReflection->value();
|
||||||
ui->zoomFactor->setValueQuiet(1.0 / edgeReflection);
|
ui->zoomFactor->setValueQuiet(1.0 / edgeReflection);
|
||||||
});
|
});
|
||||||
|
connect(ui->lineTable, &QTableView::clicked, [=](const QModelIndex &index){
|
||||||
|
if(index.column() == SmithChartContantLineModel::ColIndexColor) {
|
||||||
|
auto line = &constantLines[index.row()];
|
||||||
|
auto newColor = QColorDialog::getColor(line->getColor(), parentWidget(), "Select color", QColorDialog::DontUseNativeDialog);
|
||||||
|
if(newColor.isValid()) {
|
||||||
|
line->setColor(newColor);
|
||||||
|
emit model->dataChanged(index, index);
|
||||||
|
triggerReplot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
auto updatePersistentEditors = [=](){
|
||||||
|
for(unsigned int i=0;i<constantLines.size();i++) {
|
||||||
|
ui->lineTable->openPersistentEditor(model->index(i, SmithChartContantLineModel::ColIndexType));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
connect(ui->addLine, &QPushButton::clicked, [=](){
|
||||||
|
model->beginResetModel();
|
||||||
|
constantLines.push_back(SmithChartConstantLine());
|
||||||
|
model->endResetModel();
|
||||||
|
updatePersistentEditors();
|
||||||
|
});
|
||||||
|
connect(ui->removeLine, &QPushButton::clicked, [=](){
|
||||||
|
auto selected = ui->lineTable->selectionModel()->selectedRows();
|
||||||
|
// get indices of lines to delete
|
||||||
|
std::vector<int> toDelete;
|
||||||
|
for(auto s : selected) {
|
||||||
|
toDelete.push_back(s.row());
|
||||||
|
}
|
||||||
|
// delete starting with highest index (this makes sure that indices are not messed up after deleting an element
|
||||||
|
std::sort(toDelete.begin(), toDelete.end());
|
||||||
|
model->beginResetModel();
|
||||||
|
for (auto i = toDelete.rbegin(); i != toDelete.rend(); i++) {
|
||||||
|
constantLines.erase(constantLines.begin() + *i);
|
||||||
|
}
|
||||||
|
model->endResetModel();
|
||||||
|
updatePersistentEditors();
|
||||||
|
});
|
||||||
|
|
||||||
|
updatePersistentEditors();
|
||||||
dialog->show();
|
dialog->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,7 +274,7 @@ void TraceSmithChart::draw(QPainter &p) {
|
|||||||
transform = p.transform();
|
transform = p.transform();
|
||||||
p.restore();
|
p.restore();
|
||||||
|
|
||||||
auto drawArc = [&](Arc a) {
|
auto drawArc = [&](SmithChartArc a) {
|
||||||
a.constrainToCircle(QPointF(0,0), edgeReflection);
|
a.constrainToCircle(QPointF(0,0), edgeReflection);
|
||||||
auto topleft = dataToPixel(complex<double>(a.center.x() - a.radius, a.center.y() - a.radius));
|
auto topleft = dataToPixel(complex<double>(a.center.x() - a.radius, a.center.y() - a.radius));
|
||||||
auto bottomright = dataToPixel(complex<double>(a.center.x() + a.radius, a.center.y() + a.radius));
|
auto bottomright = dataToPixel(complex<double>(a.center.x() + a.radius, a.center.y() + a.radius));
|
||||||
@ -226,7 +287,7 @@ void TraceSmithChart::draw(QPainter &p) {
|
|||||||
auto pen = QPen(pref.Graphs.Color.axis);
|
auto pen = QPen(pref.Graphs.Color.axis);
|
||||||
pen.setCosmetic(true);
|
pen.setCosmetic(true);
|
||||||
p.setPen(pen);
|
p.setPen(pen);
|
||||||
drawArc(Arc(QPointF(0, 0), edgeReflection, 0, 2*M_PI));
|
drawArc(SmithChartArc(QPointF(0, 0), edgeReflection, 0, 2*M_PI));
|
||||||
|
|
||||||
constexpr int Circles = 6;
|
constexpr int Circles = 6;
|
||||||
pen = QPen(pref.Graphs.Color.Ticks.divisions, 0.5, Qt::DashLine);
|
pen = QPen(pref.Graphs.Color.Ticks.divisions, 0.5, Qt::DashLine);
|
||||||
@ -234,8 +295,8 @@ void TraceSmithChart::draw(QPainter &p) {
|
|||||||
p.setPen(pen);
|
p.setPen(pen);
|
||||||
for(int i=1;i<Circles * 2;i++) {
|
for(int i=1;i<Circles * 2;i++) {
|
||||||
auto radius = (double) i / Circles;
|
auto radius = (double) i / Circles;
|
||||||
drawArc(Arc(QPointF(1.0 - radius, 0.0), radius, 0, 2*M_PI));
|
drawArc(SmithChartArc(QPointF(1.0 - radius, 0.0), radius, 0, 2*M_PI));
|
||||||
drawArc(Arc(QPointF(1.0 + radius, 0.0), radius, 0, 2*M_PI));
|
drawArc(SmithChartArc(QPointF(1.0 + radius, 0.0), radius, 0, 2*M_PI));
|
||||||
}
|
}
|
||||||
|
|
||||||
p.drawLine(dataToPixel(complex<double>(edgeReflection,0)),dataToPixel(complex<double>(-edgeReflection,0)));
|
p.drawLine(dataToPixel(complex<double>(edgeReflection,0)),dataToPixel(complex<double>(-edgeReflection,0)));
|
||||||
@ -243,8 +304,18 @@ void TraceSmithChart::draw(QPainter &p) {
|
|||||||
for(auto z : impedanceLines) {
|
for(auto z : impedanceLines) {
|
||||||
z /= ReferenceImpedance;
|
z /= ReferenceImpedance;
|
||||||
auto radius = 1.0/z;
|
auto radius = 1.0/z;
|
||||||
drawArc(Arc(QPointF(1.0, radius), radius, 0, 2*M_PI));
|
drawArc(SmithChartArc(QPointF(1.0, radius), radius, 0, 2*M_PI));
|
||||||
drawArc(Arc(QPointF(1.0, -radius), radius, 0, 2*M_PI));
|
drawArc(SmithChartArc(QPointF(1.0, -radius), radius, 0, 2*M_PI));
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw custom constant parameter lines
|
||||||
|
for(auto line : constantLines) {
|
||||||
|
pen = QPen(line.getColor(), pref.Graphs.lineWidth);
|
||||||
|
pen.setCosmetic(true);
|
||||||
|
p.setPen(pen);
|
||||||
|
for(auto arc : line.getArcs()) {
|
||||||
|
drawArc(arc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto t : traces) {
|
for(auto t : traces) {
|
||||||
@ -429,7 +500,7 @@ bool TraceSmithChart::dropSupported(Trace *t)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TraceSmithChart::Arc::Arc(QPointF center, double radius, double startAngle, double spanAngle)
|
SmithChartArc::SmithChartArc(QPointF center, double radius, double startAngle, double spanAngle)
|
||||||
: center(center),
|
: center(center),
|
||||||
radius(radius),
|
radius(radius),
|
||||||
startAngle(startAngle),
|
startAngle(startAngle),
|
||||||
@ -438,7 +509,7 @@ TraceSmithChart::Arc::Arc(QPointF center, double radius, double startAngle, doub
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TraceSmithChart::Arc::constrainToCircle(QPointF center, double radius)
|
void SmithChartArc::constrainToCircle(QPointF center, double radius)
|
||||||
{
|
{
|
||||||
// check if arc/circle intersect
|
// check if arc/circle intersect
|
||||||
auto centerDiff = this->center - center;
|
auto centerDiff = this->center - center;
|
||||||
@ -502,3 +573,267 @@ void TraceSmithChart::Arc::constrainToCircle(QPointF center, double radius)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SmithChartConstantLine::SmithChartConstantLine()
|
||||||
|
{
|
||||||
|
type = Type::VSWR;
|
||||||
|
param = 10.0;
|
||||||
|
color = Qt::darkRed;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SmithChartArc> SmithChartConstantLine::getArcs()
|
||||||
|
{
|
||||||
|
std::vector<SmithChartArc> arcs;
|
||||||
|
switch(type) {
|
||||||
|
case Type::VSWR:
|
||||||
|
arcs.push_back(SmithChartArc(QPointF(0.0, 0.0), (param - 1.0) / (param + 1.0)));
|
||||||
|
break;
|
||||||
|
case Type::Resistance: {
|
||||||
|
auto circleLeft = (param / 50.0 - 1.0) / (param / 50.0 + 1.0);
|
||||||
|
arcs.push_back(SmithChartArc(QPointF((circleLeft + 1.0) / 2, 0.0), (1.0 - circleLeft) / 2.0));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Type::Reactance: {
|
||||||
|
auto radius = 1.0/(param / 50.0);
|
||||||
|
if(radius > 0) {
|
||||||
|
arcs.push_back(SmithChartArc(QPointF(1.0, radius), radius));
|
||||||
|
} else {
|
||||||
|
arcs.push_back(SmithChartArc(QPointF(1.0, radius), -radius));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Type::Q: {
|
||||||
|
auto center = 1.0 / param;
|
||||||
|
auto radius = sqrt(center*center + 1.0);
|
||||||
|
arcs.push_back(SmithChartArc(QPointF(0.0, center), radius));
|
||||||
|
arcs.push_back(SmithChartArc(QPointF(0.0, -center), radius));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Type::Last:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return arcs;
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor SmithChartConstantLine::getColor() const
|
||||||
|
{
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmithChartConstantLine::fromJSON(nlohmann::json j)
|
||||||
|
{
|
||||||
|
type = TypeFromString(QString::fromStdString(j.value("type", "VSWR")));
|
||||||
|
if(type == Type::Last) {
|
||||||
|
type = Type::VSWR;
|
||||||
|
}
|
||||||
|
param = j.value("param", 1.0);
|
||||||
|
color = QColor(QString::fromStdString(j.value("color", "red")));
|
||||||
|
}
|
||||||
|
|
||||||
|
nlohmann::json SmithChartConstantLine::toJSON()
|
||||||
|
{
|
||||||
|
nlohmann::json j;
|
||||||
|
j["type"] = TypeToString(type).toStdString();
|
||||||
|
j["param"] = param;
|
||||||
|
j["color"] = color.name().toStdString();
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SmithChartConstantLine::getParamUnit()
|
||||||
|
{
|
||||||
|
switch(type) {
|
||||||
|
case Type::VSWR: return "";
|
||||||
|
case Type::Resistance: return "Ω";
|
||||||
|
case Type::Reactance: return "Ωj";
|
||||||
|
case Type::Q: return "";
|
||||||
|
case Type::Last: break;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SmithChartConstantLine::TypeToString(SmithChartConstantLine::Type type)
|
||||||
|
{
|
||||||
|
switch(type) {
|
||||||
|
case Type::VSWR: return "VSWR";
|
||||||
|
case Type::Resistance: return "Resistance";
|
||||||
|
case Type::Reactance: return "Reactance";
|
||||||
|
case Type::Q: return "Q";
|
||||||
|
case Type::Last:break;
|
||||||
|
}
|
||||||
|
// should never get here
|
||||||
|
return "Invalid";
|
||||||
|
}
|
||||||
|
|
||||||
|
SmithChartConstantLine::Type SmithChartConstantLine::TypeFromString(QString s)
|
||||||
|
{
|
||||||
|
for(unsigned int i=0;i<(unsigned int)Type::Last;i++) {
|
||||||
|
if(TypeToString((Type) i) == s) {
|
||||||
|
return (Type) i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Type::Last;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmithChartConstantLine::setColor(const QColor &value)
|
||||||
|
{
|
||||||
|
color = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
double SmithChartConstantLine::getParam() const
|
||||||
|
{
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmithChartConstantLine::setParam(double value)
|
||||||
|
{
|
||||||
|
param = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmithChartConstantLine::setType(const Type &value)
|
||||||
|
{
|
||||||
|
type = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
SmithChartConstantLine::Type SmithChartConstantLine::getType() const
|
||||||
|
{
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr int rowHeight = 21;
|
||||||
|
|
||||||
|
QSize SmithChartParamDelegate::sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return QSize(0, rowHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *SmithChartParamDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
auto line = static_cast<const SmithChartContantLineModel*>(index.model())->lineFromIndex(index);
|
||||||
|
auto editor = new SIUnitEdit(line->getParamUnit(), "pnum kMG", 6);
|
||||||
|
editor->setValue(line->getParam());
|
||||||
|
editor->setMaximumHeight(rowHeight);
|
||||||
|
editor->setParent(parent);
|
||||||
|
connect(editor, &SIUnitEdit::valueUpdated, this, &SmithChartParamDelegate::commitData);
|
||||||
|
return editor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmithChartParamDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
auto line = ((SmithChartContantLineModel*)model)->lineFromIndex(index);
|
||||||
|
auto si = (SIUnitEdit*) editor;
|
||||||
|
line->setParam(si->value());
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize SmithChartTypeDelegate::sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return QSize(0, rowHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *SmithChartTypeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
auto line = static_cast<const SmithChartContantLineModel*>(index.model())->lineFromIndex(index);
|
||||||
|
auto editor = new QComboBox();
|
||||||
|
for(unsigned int i=0;i<(unsigned int)SmithChartConstantLine::Type::Last;i++) {
|
||||||
|
editor->addItem(SmithChartConstantLine::TypeToString((SmithChartConstantLine::Type) i));
|
||||||
|
}
|
||||||
|
editor->setCurrentIndex((int) line->getType());
|
||||||
|
connect(editor, qOverload<int>(&QComboBox::currentIndexChanged), [=](int) {
|
||||||
|
emit const_cast<SmithChartTypeDelegate*>(this)->commitData(editor);
|
||||||
|
});
|
||||||
|
editor->setMaximumHeight(rowHeight);
|
||||||
|
editor->setParent(parent);
|
||||||
|
return editor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmithChartTypeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
auto line = ((SmithChartContantLineModel*)model)->lineFromIndex(index);
|
||||||
|
auto *cb = (QComboBox*) editor;
|
||||||
|
line->setType((SmithChartConstantLine::Type) cb->currentIndex());
|
||||||
|
// parameter unit may have changed, update model
|
||||||
|
auto paramIndex = model->index(index.row(), SmithChartContantLineModel::ColIndexParam);
|
||||||
|
emit model->dataChanged(paramIndex, paramIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
SmithChartContantLineModel::SmithChartContantLineModel(TraceSmithChart &chart, QObject *parent)
|
||||||
|
: chart(chart)
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SmithChartContantLineModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent);
|
||||||
|
return chart.constantLines.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int SmithChartContantLineModel::columnCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent);
|
||||||
|
return ColIndexLast;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant SmithChartContantLineModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
if ((unsigned int) index.row() >= chart.constantLines.size())
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
auto line = chart.constantLines[index.row()];
|
||||||
|
switch(index.column()) {
|
||||||
|
case ColIndexColor:
|
||||||
|
if (role == Qt::BackgroundColorRole) {
|
||||||
|
return line.getColor();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ColIndexType:
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
return SmithChartConstantLine::TypeToString(line.getType());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ColIndexParam:
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
return Unit::ToString(line.getParam(), line.getParamUnit(), "pnum kMG", 6);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant SmithChartContantLineModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(orientation);
|
||||||
|
if(role == Qt::DisplayRole) {
|
||||||
|
switch(section) {
|
||||||
|
case ColIndexColor: return "Color";
|
||||||
|
case ColIndexType: return "Type";
|
||||||
|
case ColIndexParam: return "Parameter";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags SmithChartContantLineModel::flags(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
||||||
|
switch(index.column()) {
|
||||||
|
case ColIndexType:
|
||||||
|
case ColIndexParam:
|
||||||
|
flags |= Qt::ItemIsEditable;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
SmithChartConstantLine* SmithChartContantLineModel::lineFromIndex(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
if(index.isValid() && index.row() < (int) chart.constantLines.size()) {
|
||||||
|
return &chart.constantLines[index.row()];
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,10 +6,102 @@
|
|||||||
#include <QPen>
|
#include <QPen>
|
||||||
#include <QPainterPath>
|
#include <QPainterPath>
|
||||||
#include <QTransform>
|
#include <QTransform>
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
|
class TraceSmithChart;
|
||||||
|
|
||||||
|
class SmithChartArc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SmithChartArc(QPointF center, double radius, double startAngle = 0.0, double spanAngle = 2*M_PI);
|
||||||
|
void constrainToCircle(QPointF center, double radius);
|
||||||
|
|
||||||
|
QPointF center;
|
||||||
|
double radius;
|
||||||
|
double startAngle, spanAngle;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SmithChartConstantLine : public Savable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class Type {
|
||||||
|
VSWR,
|
||||||
|
Resistance,
|
||||||
|
Reactance,
|
||||||
|
Q,
|
||||||
|
Last,
|
||||||
|
};
|
||||||
|
|
||||||
|
SmithChartConstantLine();
|
||||||
|
std::vector<SmithChartArc> getArcs();
|
||||||
|
QColor getColor() const;
|
||||||
|
void setColor(const QColor &value);
|
||||||
|
|
||||||
|
void fromJSON(nlohmann::json j) override;
|
||||||
|
nlohmann::json toJSON() override;
|
||||||
|
|
||||||
|
QString getParamUnit();
|
||||||
|
|
||||||
|
Type getType() const;
|
||||||
|
void setType(const Type &value);
|
||||||
|
|
||||||
|
double getParam() const;
|
||||||
|
void setParam(double value);
|
||||||
|
|
||||||
|
static QString TypeToString(Type type);
|
||||||
|
static Type TypeFromString(QString s);
|
||||||
|
private:
|
||||||
|
QColor color;
|
||||||
|
double param;
|
||||||
|
Type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SmithChartTypeDelegate : public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT;
|
||||||
|
QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const override;
|
||||||
|
QWidget *createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const override;
|
||||||
|
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SmithChartParamDelegate : public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT;
|
||||||
|
QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const override;
|
||||||
|
QWidget *createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const override;
|
||||||
|
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SmithChartContantLineModel : public QAbstractTableModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
friend TraceSmithChart;
|
||||||
|
public:
|
||||||
|
SmithChartContantLineModel(TraceSmithChart &chart, QObject *parent = 0);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ColIndexColor,
|
||||||
|
ColIndexType,
|
||||||
|
ColIndexParam,
|
||||||
|
ColIndexLast,
|
||||||
|
};
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
QVariant data(const QModelIndex &index, int role) const override;
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||||
|
// bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||||
|
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||||
|
|
||||||
|
SmithChartConstantLine *lineFromIndex(const QModelIndex &index) const;
|
||||||
|
private:
|
||||||
|
TraceSmithChart &chart;
|
||||||
|
};
|
||||||
|
|
||||||
class TraceSmithChart : public TracePlot
|
class TraceSmithChart : public TracePlot
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
friend class SmithChartContantLineModel;
|
||||||
public:
|
public:
|
||||||
TraceSmithChart(TraceModel &model, QWidget *parent = 0);
|
TraceSmithChart(TraceModel &model, QWidget *parent = 0);
|
||||||
|
|
||||||
@ -27,17 +119,6 @@ protected:
|
|||||||
static constexpr double screenUsage = 0.9;
|
static constexpr double screenUsage = 0.9;
|
||||||
static constexpr double smithCoordMax = 4096;
|
static constexpr double smithCoordMax = 4096;
|
||||||
|
|
||||||
class Arc
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Arc(QPointF center, double radius, double startAngle, double spanAngle);
|
|
||||||
void constrainToCircle(QPointF center, double radius);
|
|
||||||
|
|
||||||
QPointF center;
|
|
||||||
double radius;
|
|
||||||
double startAngle, spanAngle;
|
|
||||||
};
|
|
||||||
|
|
||||||
QPoint dataToPixel(std::complex<double> d);
|
QPoint dataToPixel(std::complex<double> d);
|
||||||
QPoint dataToPixel(Trace::Data d);
|
QPoint dataToPixel(Trace::Data d);
|
||||||
std::complex<double> pixelToData(QPoint p);
|
std::complex<double> pixelToData(QPoint p);
|
||||||
@ -56,6 +137,7 @@ protected:
|
|||||||
bool limitToEdge;
|
bool limitToEdge;
|
||||||
double edgeReflection; // magnitude of reflection coefficient at the edge of the smith chart (zoom factor)
|
double edgeReflection; // magnitude of reflection coefficient at the edge of the smith chart (zoom factor)
|
||||||
QTransform transform;
|
QTransform transform;
|
||||||
|
std::vector<SmithChartConstantLine> constantLines;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TRACESMITHCHART_H
|
#endif // TRACESMITHCHART_H
|
||||||
|
Loading…
Reference in New Issue
Block a user