Merge branch 'terminal_strip'

This commit is contained in:
joshua
2025-10-15 23:30:54 +02:00
45 changed files with 1894 additions and 587 deletions

View File

@@ -16,6 +16,7 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "terminalstripdrawer.h"
#include <QPainter>
namespace TerminalStripDrawer {
@@ -42,12 +43,13 @@ void TerminalStripDrawer::setStrip(QSharedPointer<AbstractTerminalStripInterface
*/
void TerminalStripDrawer::paint(QPainter *painter)
{
if (m_strip && m_pattern)
{
//To draw text, QPainter need a Qrect. Instead of create an instance
//for each text, we re-use the same instance of QRect.
QRect text_rect;
painter->save();
if (m_strip && m_pattern)
{
m_united_xref_text_rect = QRectF();
//To draw text, QPainter need a Qrect. Instead of create an instance
//for each text, we re-use the same instance of QRect.
QRect text_rect;
painter->save();
auto pen_{painter->pen()};
pen_.setColor(Qt::black);
@@ -56,16 +58,20 @@ void TerminalStripDrawer::paint(QPainter *painter)
auto brush_ = painter->brush();
brush_.setColor(Qt::white);
painter->setPen(pen_);
painter->setBrush(brush_);
painter->setFont(m_pattern->font());
if (m_preview_draw)
{
painter->save();
painter->setPen(Qt::blue);
painter->drawRect(boundingRect());
painter->restore();
}
painter->setPen(pen_);
painter->setBrush(brush_);
if (m_preview_draw)
{
painter->save();
painter->setPen(Qt::blue);
painter->drawRect(boundingRect());
painter->drawLine(QPointF{boundingRect().left(), boundingRect().center().y()},
QPointF{boundingRect().right(), boundingRect().center().y()});
painter->restore();
}
//Draw header
painter->drawRect(m_pattern->m_header_rect);
@@ -84,14 +90,13 @@ void TerminalStripDrawer::paint(QPainter *painter)
text_rect.setRect(0,0,m_pattern->m_header_rect.height(),m_pattern->m_header_rect.width());
}
const auto text_{m_strip->installation() + " " + m_strip->location() + " " + m_strip->name()};
painter->drawText(text_rect, text_, m_pattern->headerTextOption());
const auto text_{m_strip->installation() + " " + m_strip->location() + " " + m_strip->name()};
painter->drawText(text_rect, text_, m_pattern->headerTextOption());
painter->restore();
//Move painter pos to next drawing
painter->translate(m_pattern->m_header_rect.width(),0);
int x_offset{m_pattern->m_header_rect.width()};
//Move painter pos to next drawing
painter->translate(m_pattern->m_header_rect.width(),0);
qreal x_offset{m_pattern->m_header_rect.width()};
//Draw spacer
painter->drawRect(m_pattern->m_spacer_rect);
@@ -99,22 +104,30 @@ void TerminalStripDrawer::paint(QPainter *painter)
painter->translate(m_pattern->m_spacer_rect.width(),0);
x_offset += m_pattern->m_spacer_rect.width();
//Draw terminals
const auto terminals_text_orientation{m_pattern->m_terminals_text_orientation};
const auto terminals_text_option{m_pattern->terminalsTextOption()};
const auto terminals_text_height{m_pattern->m_terminals_text_height};
const auto terminals_text_y{m_pattern->m_terminals_text_y};
QRectF terminal_rect;
//Draw terminals
const auto terminals_text_rect{m_pattern->m_terminals_text_rect};
const auto terminals_text_orientation{m_pattern->m_terminals_text_orientation};
const auto terminals_text_option{m_pattern->terminalsTextOption()};
QRect terminal_rect;
const auto xref_text_orientation{m_pattern->m_xref_text_orientation};
const auto xref_text_option{m_pattern->xrefTextOption()};
const auto xref_text_height{m_pattern->m_xref_text_height};
const auto xref_text_y{m_pattern->m_xref_text_y};
QRectF xref_rect;
QHash<QUuid, QVector<QPointF>> bridges_anchor_points;
//Loop over physical terminals
for (const auto &physical_t : m_strip->physicalTerminal())
{
//Get the good offset according to how many level have the current physical terminal
const QVector<QSharedPointer<AbstractRealTerminalInterface>> real_terminal_vector{physical_t->realTerminals()};
const auto real_t_count{real_terminal_vector.size()};
const auto offset_{4 - real_t_count};
m_hovered_xref = hoverTerminal{};
int physical_index = 0;
//Loop over physical terminals
for (const auto &physical_t : m_strip->physicalTerminal())
{
//Get the good offset according to how many level have the current physical terminal
const QVector<QSharedPointer<AbstractRealTerminalInterface>> real_terminal_vector{physical_t->realTerminals()};
const auto real_t_count{real_terminal_vector.size()};
const auto offset_{4 - real_t_count};
//Loop over real terminals
for (auto i=0 ; i<real_t_count ; ++i)
@@ -124,45 +137,50 @@ void TerminalStripDrawer::paint(QPainter *painter)
break;
}
terminal_rect = m_pattern->m_terminal_rect[index_];
//Draw terminal rect
painter->drawRect(terminal_rect);
//Draw a stronger line if the current terminal have level
//and the current level is the first
if (real_t_count > 1 && i == 0)
{
painter->save();
pen_ = painter->pen();
pen_.setWidth(4);
pen_.setCapStyle(Qt::FlatCap);
painter->setPen(pen_);
const auto p1 { terminal_rect.topLeft() };
//We can't use terminal_rect.bottomLeft for p2 because
//the returned value deviate from the true value
//(see Qt documentation about QRect)
const QPoint p2 { p1.x(), p1.y() + terminal_rect.height() };
painter->drawLine(p1, p2);
painter->restore();
terminal_rect = m_pattern->m_terminal_rect[index_];
//Draw terminal rect
painter->drawRect(terminal_rect);
//Draw a stronger line if the current terminal have level
//and the current level is the first
if (real_t_count > 1 && i == 0)
{
painter->save();
pen_ = painter->pen();
pen_.setWidth(4);
pen_.setCapStyle(Qt::FlatCap);
painter->setPen(pen_);
const auto p1 { terminal_rect.topLeft() };
//We can't use terminal_rect.bottomLeft for p2 because
//the returned value deviate from the true value
//(see Qt documentation about QRect)
const QPointF p2 { p1.x(), p1.y() + terminal_rect.height() };
painter->drawLine(p1, p2);
painter->restore();
}
if(m_preview_draw)
{
painter->save();
painter->setPen(Qt::yellow);
painter->drawLine(QPointF{terminal_rect.x(), terminal_rect.y() + terminal_rect.height()/2},
QPointF{terminal_rect.width(), terminal_rect.y() + terminal_rect.height()/2});
painter->restore();
}
//Draw text
painter->save();
if (terminals_text_orientation[index_] == Qt::Horizontal)
{
text_rect = terminals_text_rect[index_];
}
else
{
const auto rect_{terminals_text_rect[index_]};
painter->translate(rect_.bottomLeft());
painter->rotate(270);
text_rect.setRect(0, 0, rect_.height(), terminal_rect.width());
}
//Draw text
painter->save();
text_rect.setRect(0, terminals_text_y, terminal_rect.width(), terminals_text_height);
if (terminals_text_orientation == Qt::Vertical)
{
painter->translate(text_rect.bottomLeft());
painter->rotate(270);
text_rect.setRect(0, 0, text_rect.height(), text_rect.width());
}
const auto shared_real_terminal{real_terminal_vector[i]};
const auto shared_real_terminal{real_terminal_vector[i]};
painter->drawText(text_rect,
shared_real_terminal ? shared_real_terminal->label() : QLatin1String(),
terminals_text_option[index_]);
terminals_text_option);
if (m_preview_draw)
{
@@ -172,16 +190,60 @@ void TerminalStripDrawer::paint(QPainter *painter)
painter->restore();
//Add bridge anchor
if (shared_real_terminal->isBridged())
//Draw xref
xref_rect.setRect(0, xref_text_y, terminal_rect.width(), xref_text_height);
painter->save();
if (xref_text_orientation == Qt::Vertical)
{
painter->save();
if (QScopedPointer<AbstractBridgeInterface> bridge_ {
shared_real_terminal->bridge() })
{
const auto x_anchor{terminal_rect.width()/2};
const auto y_anchor {m_pattern->m_bridge_point_y_offset[index_]};
const auto radius_anchor{m_pattern->m_bridge_point_d/2};
painter->translate(xref_rect.bottomLeft());
painter->rotate(270);
xref_rect.setRect(0, 0, xref_rect.height(), xref_rect.width());
}
QTransform transform;
transform.translate(x_offset, 0);
if (xref_text_orientation == Qt::Vertical)
{
transform.translate(0, xref_text_y + xref_text_height);
transform.rotate(270);
}
auto xref_string = shared_real_terminal->xref();
const auto mapped_xref_text_rect = transform.mapRect(painter->boundingRect(xref_rect, xref_string, xref_text_option));
if (m_united_xref_text_rect.isNull()) {
m_united_xref_text_rect = mapped_xref_text_rect;
} else {
m_united_xref_text_rect = m_united_xref_text_rect.united(mapped_xref_text_rect);
}
//if mouse hover the xref text, draw it in blue to advise user the xref is clickable.
if (!m_mouse_hover_pos.isNull() && mapped_xref_text_rect.contains(m_mouse_hover_pos)) {
painter->setPen(Qt::blue);
m_hovered_xref.physical = physical_index;
m_hovered_xref.real = i;
}
painter->drawText(xref_rect, xref_string, xref_text_option);
if (m_preview_draw)
{
painter->setPen(Qt::blue);
painter->drawRect(xref_rect);
}
painter->restore();
//Add bridge anchor
if (shared_real_terminal->isBridged())
{
painter->save();
if (QScopedPointer<AbstractBridgeInterface> bridge_ {
shared_real_terminal->bridge() })
{
const auto x_anchor{terminal_rect.width()/2};
const auto y_anchor {m_pattern->m_bridge_point_y_offset[index_]};
const auto radius_anchor{m_pattern->m_bridge_point_d/2};
painter->setBrush(Qt::SolidPattern);
painter->drawEllipse(QPointF(x_anchor, y_anchor),
@@ -194,12 +256,13 @@ void TerminalStripDrawer::paint(QPainter *painter)
painter->restore();
}
//Move painter pos to next drawing
painter->translate(terminal_rect.width(),0);
x_offset += terminal_rect.width();
}
}
painter->restore();
//Move painter pos to next drawing
painter->translate(terminal_rect.width(),0);
x_offset += terminal_rect.width();
}
physical_index++;
}
painter->restore();
//Draw the bridges
for (const auto &points_ : qAsConst(bridges_anchor_points))
@@ -216,7 +279,7 @@ void TerminalStripDrawer::paint(QPainter *painter)
QRectF TerminalStripDrawer::boundingRect() const
{
return QRect{0, 0, width(), height()};;
return QRectF{0, 0, width(), height()};;
}
void TerminalStripDrawer::setLayout(QSharedPointer<TerminalStripLayoutPattern> layout)
@@ -233,7 +296,42 @@ void TerminalStripDrawer::setPreviewDraw(bool draw) {
m_preview_draw = draw;
}
int TerminalStripDrawer::height() const
void TerminalStripDrawer::setMouseHoverPos(const QPointF &pos)
{
m_last_mouse_pos_in_xrefs_rect = m_united_xref_text_rect.contains(m_mouse_hover_pos);
m_mouse_hover_pos = pos;
}
/**
* @brief TerminalStripDrawer::mouseHoverXref
* @return True if the mouse position (given through the function setMouseHoverPos)
* hover the rect of a xref.
*/
bool TerminalStripDrawer::mouseHoverXref() const {
return m_united_xref_text_rect.contains(m_mouse_hover_pos);
}
bool TerminalStripDrawer::needUpdate()
{
if (mouseHoverXref()) {
return true;
} else if (m_last_mouse_pos_in_xrefs_rect) {
return true;
}
return false;
}
/**
* @brief TerminalStripDrawer::hoveredXref
* @return the current terminal hovered by the mouse
* in the xref bounding rectangle
*/
hoverTerminal TerminalStripDrawer::hoveredXref() const
{
return m_hovered_xref;
}
qreal TerminalStripDrawer::height() const
{
if (m_pattern)
{
@@ -251,11 +349,11 @@ int TerminalStripDrawer::height() const
return 0;
}
int TerminalStripDrawer::width() const
qreal TerminalStripDrawer::width() const
{
if (m_pattern)
{
int width_{m_pattern->m_header_rect.width() + m_pattern->m_spacer_rect.width()};
if (m_pattern)
{
qreal width_{m_pattern->m_header_rect.width() + m_pattern->m_spacer_rect.width()};
if (m_strip)
{