mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-09 21:54:13 +02:00
Improve terminal_strip
This commit is contained in:
@@ -38,10 +38,13 @@ namespace TerminalStripDrawer
|
||||
class DemoRealTerminal : public AbstractRealTerminalInterface
|
||||
{
|
||||
public:
|
||||
DemoRealTerminal(const QString &label, const QString &xref, const QUuid &bridge) :
|
||||
DemoRealTerminal(const QString &label, const QString &xref, const QUuid &bridge,
|
||||
ElementData::TerminalType type = ElementData::TTGeneric, bool led = false) :
|
||||
m_label { label },
|
||||
m_xref{ xref },
|
||||
m_bridge { bridge }
|
||||
m_bridge { bridge },
|
||||
m_type { type },
|
||||
m_led { led }
|
||||
{}
|
||||
|
||||
QString label() const override {
|
||||
@@ -60,9 +63,19 @@ namespace TerminalStripDrawer
|
||||
return m_xref;
|
||||
}
|
||||
|
||||
ElementData::TerminalType type() const override {
|
||||
return m_type;
|
||||
}
|
||||
|
||||
bool isLed() const override {
|
||||
return m_led;
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_label, m_xref;
|
||||
QUuid m_bridge;
|
||||
ElementData::TerminalType m_type;
|
||||
bool m_led;
|
||||
};
|
||||
|
||||
class DemoPhysicalTerminal : public AbstractPhysicalTerminalInterface
|
||||
@@ -109,19 +122,19 @@ namespace TerminalStripDrawer
|
||||
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
|
||||
new DemoRealTerminal( QStringLiteral("24vdc"),
|
||||
QStringLiteral("1_A1"),
|
||||
lvl_1)};
|
||||
lvl_1, ElementData::TTFuse, false)};
|
||||
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
|
||||
new DemoRealTerminal( QStringLiteral("0vdc"),
|
||||
QStringLiteral("1_A2"),
|
||||
lvl_2)};
|
||||
lvl_2, ElementData::TTSectional, false)};
|
||||
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
|
||||
new DemoRealTerminal( QStringLiteral("signal"),
|
||||
QStringLiteral("1_A3"),
|
||||
lvl_3)};
|
||||
lvl_3, ElementData::TTDiode, false)};
|
||||
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
|
||||
new DemoRealTerminal( QStringLiteral("teach"),
|
||||
QStringLiteral("1_A4"),
|
||||
lvl_4)};
|
||||
lvl_4, ElementData::TTGround, false)};
|
||||
m_physical_terminal << QSharedPointer<AbstractPhysicalTerminalInterface> {
|
||||
new DemoPhysicalTerminal {real_terminals_vector}};
|
||||
|
||||
@@ -129,11 +142,11 @@ namespace TerminalStripDrawer
|
||||
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
|
||||
new DemoRealTerminal( QStringLiteral("24vdc"),
|
||||
QStringLiteral("2_A1"),
|
||||
lvl_1)};
|
||||
lvl_1, ElementData::TTGeneric, true)};
|
||||
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
|
||||
new DemoRealTerminal( QStringLiteral("0vdc"),
|
||||
QStringLiteral("2_A2"),
|
||||
lvl_2)};
|
||||
lvl_2, ElementData::TTFuse, true)};
|
||||
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
|
||||
new DemoRealTerminal( QStringLiteral("signal"),
|
||||
QStringLiteral("2_A3"),
|
||||
|
||||
@@ -44,7 +44,7 @@ class TerminalStripLayoutPattern
|
||||
TerminalStripLayoutPattern();
|
||||
|
||||
//Header of terminal strip
|
||||
QRectF m_header_rect{0,30,50,130};
|
||||
QRectF m_header_rect{0,30,50,146};
|
||||
Qt::Orientation m_header_text_orientation{Qt::Horizontal};
|
||||
void setHeaderTextAlignment(const Qt::Alignment &alignment);
|
||||
Qt::Alignment headerTextAlignment() const;
|
||||
@@ -60,10 +60,10 @@ class TerminalStripLayoutPattern
|
||||
//Terminals
|
||||
QVector<QRectF> m_terminal_rect
|
||||
{
|
||||
QRectF{0, 0, 20, 190},
|
||||
QRectF{0, 10, 20, 170},
|
||||
QRectF{0, 20, 20, 150},
|
||||
QRectF{0, 30, 20, 130}
|
||||
QRectF{0, 0, 20, 206},
|
||||
QRectF{0, 10, 20, 186},
|
||||
QRectF{0, 20, 20, 166},
|
||||
QRectF{0, 30, 20, 146}
|
||||
};
|
||||
|
||||
//Terminal text
|
||||
@@ -82,6 +82,13 @@ class TerminalStripLayoutPattern
|
||||
qreal m_xref_text_y{95};
|
||||
Qt::Orientation m_xref_text_orientation {Qt::Vertical};
|
||||
|
||||
//Symbol of the terminal type (fuse, sectional, diode, ground, led).
|
||||
//A height of 0 disable the symbol.
|
||||
qreal m_type_symbol_y{160};
|
||||
qreal m_type_symbol_height{14};
|
||||
//Length of the connection drawn above and under each terminal,
|
||||
//in the middle of the terminal. 0 disable the connections.
|
||||
qreal m_connection_length{10};
|
||||
qreal m_bridge_point_d{5};
|
||||
QVector<qreal> m_bridge_point_y_offset{50,70,90,110};
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include <QPainter>
|
||||
#include <QHash>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace TerminalStripDrawer {
|
||||
|
||||
/**
|
||||
@@ -38,6 +40,156 @@ void TerminalStripDrawer::setStrip(QSharedPointer<AbstractTerminalStripInterface
|
||||
m_strip = strip;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/*
|
||||
* The symbols are described in a box of 20 x 14 units centered on (0,0).
|
||||
* The current flow from the top to the bottom, like in the terminal strip.
|
||||
* drawTypeSymbol() scale this box to fit the real available area.
|
||||
*/
|
||||
constexpr qreal symbol_width{20};
|
||||
constexpr qreal symbol_height{14};
|
||||
|
||||
void drawFuseSymbol(QPainter *painter)
|
||||
{
|
||||
painter->drawLine(QPointF{0, -7}, QPointF{0, 7});
|
||||
painter->drawRect(QRectF{-3, -5, 6, 10});
|
||||
}
|
||||
|
||||
void drawSectionalSymbol(QPainter *painter)
|
||||
{
|
||||
painter->drawLine(QPointF{0, -7}, QPointF{0, 7});
|
||||
painter->drawLine(QPointF{-4, 2}, QPointF{4, -2});
|
||||
}
|
||||
|
||||
void drawDiodeSymbol(QPainter *painter)
|
||||
{
|
||||
const qreal t{symbol_height / 3};
|
||||
const QPointF triangle[3] { {-t, -t}, {t, -t}, {0, t} };
|
||||
painter->drawLine(QPointF{0, -7}, QPointF{0, -t});
|
||||
painter->drawPolygon(triangle, 3);
|
||||
painter->drawLine(QPointF{-t, t}, QPointF{t, t});
|
||||
painter->drawLine(QPointF{0, t}, QPointF{0, 7});
|
||||
}
|
||||
|
||||
void drawLedSymbol(QPainter *painter)
|
||||
{
|
||||
drawDiodeSymbol(painter);
|
||||
const qreal t{symbol_height / 3};
|
||||
//The two rays
|
||||
painter->drawLine(QPointF{t + 0.5, -1}, QPointF{t + 3.5, -4});
|
||||
painter->drawLine(QPointF{t + 0.5, 2}, QPointF{t + 3.5, -1});
|
||||
}
|
||||
|
||||
void drawGroundSymbol(QPainter *painter)
|
||||
{
|
||||
painter->drawLine(QPointF{0, -7}, QPointF{0, -2});
|
||||
painter->drawLine(QPointF{-5, -2}, QPointF{5, -2});
|
||||
painter->drawLine(QPointF{-3, 1}, QPointF{3, 1});
|
||||
painter->drawLine(QPointF{-1, 4}, QPointF{1, 4});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief drawScaled
|
||||
* Call @a draw with the painter moved by @a dx and scaled by @a factor.
|
||||
* The width of the pen is kept constant.
|
||||
*/
|
||||
template<typename Func>
|
||||
void drawScaled(QPainter *painter, qreal dx, qreal factor, Func draw)
|
||||
{
|
||||
painter->save();
|
||||
painter->translate(dx, 0);
|
||||
painter->scale(factor, factor);
|
||||
auto pen_{painter->pen()};
|
||||
pen_.setWidthF(pen_.widthF() / factor);
|
||||
painter->setPen(pen_);
|
||||
draw(painter);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief drawTypeSymbol
|
||||
* Draw the symbol of a terminal type in @a box. The symbol is scaled
|
||||
* to fit in @a box, so it never overflow on the neighbouring terminal.
|
||||
* The painter must have a pen set, the brush is ignored.
|
||||
* @param painter
|
||||
* @param box : area available for the symbol, in the painter coordinates
|
||||
* @param type : type of the terminal, a generic terminal have no symbol
|
||||
* @param led : if true a led symbol is drawn. If the terminal have
|
||||
* also a type (fuse...), the type symbol and the led are drawn side by side.
|
||||
*/
|
||||
void drawTypeSymbol(QPainter *painter, const QRectF &box, ElementData::TerminalType type, bool led)
|
||||
{
|
||||
const bool have_type{type != ElementData::TTGeneric};
|
||||
if (!led && !have_type) {
|
||||
return;
|
||||
}
|
||||
|
||||
const qreal scale_{qMin(box.width() / symbol_width, box.height() / symbol_height)};
|
||||
if (scale_ <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
painter->save();
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->translate(box.center());
|
||||
painter->scale(scale_, scale_);
|
||||
auto pen_{painter->pen()};
|
||||
pen_.setWidthF(pen_.widthF() / scale_);
|
||||
painter->setPen(pen_);
|
||||
|
||||
auto draw_type = [type](QPainter *p)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ElementData::TTFuse : drawFuseSymbol(p); break;
|
||||
case ElementData::TTSectional : drawSectionalSymbol(p); break;
|
||||
case ElementData::TTDiode : drawDiodeSymbol(p); break;
|
||||
case ElementData::TTGround : drawGroundSymbol(p); break;
|
||||
default: break;
|
||||
}
|
||||
};
|
||||
|
||||
if (led && have_type)
|
||||
{
|
||||
//Not enough place for two full size symbols, draw them smaller side by side
|
||||
drawScaled(painter, -5, 0.7, draw_type);
|
||||
drawScaled(painter, 2.5, 0.7, drawLedSymbol);
|
||||
}
|
||||
else if (led) {
|
||||
drawLedSymbol(painter);
|
||||
}
|
||||
else {
|
||||
draw_type(painter);
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief drawConnections
|
||||
* Draw a connection above and a connection under @a terminal_rect, in the middle
|
||||
* of the rect. A connection is a short line ended by a little circle.
|
||||
* @param painter
|
||||
* @param terminal_rect
|
||||
* @param length : the total length of a connection, circle included
|
||||
*/
|
||||
void drawConnections(QPainter *painter, const QRectF &terminal_rect, qreal length)
|
||||
{
|
||||
const qreal radius{qMin<qreal>(length / 4, 2)};
|
||||
const qreal x{terminal_rect.width() / 2};
|
||||
const qreal top{terminal_rect.top()};
|
||||
const qreal bottom{terminal_rect.top() + terminal_rect.height()};
|
||||
|
||||
painter->drawLine(QPointF{x, top}, QPointF{x, top - length + radius * 2});
|
||||
painter->drawEllipse(QPointF{x, top - length + radius}, radius, radius);
|
||||
|
||||
painter->drawLine(QPointF{x, bottom}, QPointF{x, bottom + length - radius * 2});
|
||||
painter->drawEllipse(QPointF{x, bottom + length - radius}, radius, radius);
|
||||
}
|
||||
|
||||
} //End anonymous namespace
|
||||
|
||||
/**
|
||||
* @brief TerminalStripDrawer::paint
|
||||
* @param painter
|
||||
@@ -141,6 +293,21 @@ void TerminalStripDrawer::paint(QPainter *painter)
|
||||
terminal_rect = m_pattern->m_terminal_rect[index_];
|
||||
//Draw terminal rect
|
||||
painter->drawRect(terminal_rect);
|
||||
|
||||
//Draw the symbol of the terminal type (fuse, ground, led...)
|
||||
if (m_pattern->m_type_symbol_height > 0 && real_terminal_vector[i])
|
||||
{
|
||||
drawTypeSymbol(painter,
|
||||
QRectF{0, m_pattern->m_type_symbol_y,
|
||||
terminal_rect.width(), m_pattern->m_type_symbol_height},
|
||||
real_terminal_vector[i]->type(),
|
||||
real_terminal_vector[i]->isLed());
|
||||
}
|
||||
|
||||
//Draw the connections, above and under the terminal
|
||||
if (m_pattern->m_connection_length > 0) {
|
||||
drawConnections(painter, terminal_rect, m_pattern->m_connection_length);
|
||||
}
|
||||
//Draw a stronger line if the current terminal have level
|
||||
//and the current level is the first
|
||||
if (real_t_count > 1 && i == 0)
|
||||
@@ -280,7 +447,21 @@ void TerminalStripDrawer::paint(QPainter *painter)
|
||||
|
||||
QRectF TerminalStripDrawer::boundingRect() const
|
||||
{
|
||||
return QRectF{0, 0, width(), height()};;
|
||||
QRectF rect_{0, 0, width(), height()};
|
||||
|
||||
//The connections are drawn above and under the terminals
|
||||
if (m_pattern && m_pattern->m_connection_length > 0)
|
||||
{
|
||||
const auto length_{m_pattern->m_connection_length};
|
||||
qreal top_{0};
|
||||
for (const auto &terminal_rect : std::as_const(m_pattern->m_terminal_rect)) {
|
||||
top_ = std::min(top_, terminal_rect.top() - length_);
|
||||
}
|
||||
rect_.setBottom(rect_.bottom() + length_);
|
||||
rect_.setTop(top_);
|
||||
}
|
||||
|
||||
return rect_;
|
||||
}
|
||||
|
||||
void TerminalStripDrawer::setLayout(QSharedPointer<TerminalStripLayoutPattern> layout)
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <QUuid>
|
||||
|
||||
#include "properties/terminalstriplayoutpattern.h"
|
||||
#include "../../properties/elementdata.h"
|
||||
|
||||
class QPainter;
|
||||
class TerminalStrip;
|
||||
@@ -56,6 +57,10 @@ namespace TerminalStripDrawer
|
||||
virtual bool isBridged() const = 0;
|
||||
virtual AbstractBridgeInterface* bridge() const = 0;
|
||||
virtual QString xref() const = 0;
|
||||
//Type and led are only used to draw the symbol of the terminal.
|
||||
//They are not pure virtual, so an implementation can ignore them.
|
||||
virtual ElementData::TerminalType type() const { return ElementData::TTGeneric; }
|
||||
virtual bool isLed() const { return false; }
|
||||
};
|
||||
|
||||
class AbstractPhysicalTerminalInterface
|
||||
|
||||
@@ -128,6 +128,16 @@ namespace TerminalStripDrawer
|
||||
}
|
||||
}
|
||||
|
||||
ElementData::TerminalType TrueRealTerminal::type() const
|
||||
{
|
||||
return m_real ? m_real->type() : ElementData::TTGeneric;
|
||||
}
|
||||
|
||||
bool TrueRealTerminal::isLed() const
|
||||
{
|
||||
return m_real ? m_real->isLed() : false;
|
||||
}
|
||||
|
||||
TrueBridge::TrueBridge(QSharedPointer<TerminalStripBridge> bridge) :
|
||||
m_bridge { bridge }
|
||||
{}
|
||||
|
||||
@@ -59,6 +59,8 @@ namespace TerminalStripDrawer
|
||||
bool isBridged() const override;
|
||||
AbstractBridgeInterface* bridge() const override;
|
||||
QString xref() const override;
|
||||
ElementData::TerminalType type() const override;
|
||||
bool isLed() const override;
|
||||
|
||||
private:
|
||||
QSharedPointer<RealTerminal> m_real;
|
||||
|
||||
@@ -151,6 +151,11 @@ void TerminalStripLayoutEditor::valueEdited()
|
||||
m_layout.data()->m_xref_text_y = ui->m_xref_y_sb->value();
|
||||
m_layout.data()->m_xref_text_height = ui->m_xref_height_sb->value();
|
||||
|
||||
//Terminal type symbol
|
||||
m_layout.data()->m_type_symbol_y = ui->m_type_symbol_y_sb->value();
|
||||
m_layout.data()->m_type_symbol_height = ui->m_type_symbol_height_sb->value();
|
||||
m_layout.data()->m_connection_length = ui->m_connection_length_sb->value();
|
||||
|
||||
updateUi();
|
||||
m_preview_strip_item.update();
|
||||
}
|
||||
@@ -256,6 +261,10 @@ void TerminalStripLayoutEditor::updateUi()
|
||||
ui->m_xref_y_sb->setValue(data->m_xref_text_y);
|
||||
ui->m_xref_height_sb->setValue(data->m_xref_text_height);
|
||||
|
||||
ui->m_type_symbol_y_sb->setValue(data->m_type_symbol_y);
|
||||
ui->m_type_symbol_height_sb->setValue(data->m_type_symbol_height);
|
||||
ui->m_connection_length_sb->setValue(data->m_connection_length);
|
||||
|
||||
m_ui_updating = false;
|
||||
updatePreview();
|
||||
}
|
||||
|
||||
@@ -459,6 +459,50 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="6">
|
||||
<widget class="QLabel" name="label_symbol">
|
||||
<property name="text">
|
||||
<string>Symbol</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="6">
|
||||
<widget class="QSpinBox" name="m_type_symbol_y_sb">
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="6">
|
||||
<widget class="QSpinBox" name="m_type_symbol_height_sb">
|
||||
<property name="toolTip">
|
||||
<string>Height of the terminal type symbol (fuse, ground, led...). 0 disable the symbol.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="2">
|
||||
<widget class="QLabel" name="label_connection">
|
||||
<property name="text">
|
||||
<string>Connection length</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="3">
|
||||
<widget class="QSpinBox" name="m_connection_length_sb">
|
||||
<property name="toolTip">
|
||||
<string>Length of the connections drawn above and under each terminal. 0 disable the connections.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -1094,6 +1138,54 @@
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>m_type_symbol_y_sb</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>TerminalStripLayoutEditor</receiver>
|
||||
<slot>valueEdited()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>900</x>
|
||||
<y>398</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>480</x>
|
||||
<y>311</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>m_type_symbol_height_sb</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>TerminalStripLayoutEditor</receiver>
|
||||
<slot>valueEdited()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>900</x>
|
||||
<y>398</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>480</x>
|
||||
<y>311</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>m_connection_length_sb</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>TerminalStripLayoutEditor</receiver>
|
||||
<slot>valueEdited()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>700</x>
|
||||
<y>431</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>480</x>
|
||||
<y>311</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>valueEdited()</slot>
|
||||
|
||||
Reference in New Issue
Block a user