mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-23 07:04:14 +02:00
Draw the cables in the realistic style too
The strip seen from above drew no cable at all: it had no zone for one and no code to draw it, so a strip drawn realistically told nothing about where its cables go while the same strip drawn schematically did. The drawing itself was already shared between nothing -- it lived in one style only, so it is now Helpers::drawCables() with its cells, and both styles hand it the terminals they show. The realistic style collects one wire exit per level spread over the width of the terminal body, all of them leaving the strip at its bottom edge, and reserves the zone under the strip for them as soon as one terminal carries a cable, exactly like the schematic style does. tst_cabletarget checks the realistic style paints under the body of the strip when a terminal carries a cable, and drops that zone when it does not.
This commit is contained in:
@@ -522,6 +522,26 @@ struct BridgePoint
|
||||
qreal width{0};
|
||||
};
|
||||
|
||||
//True when at least one terminal of the strip carries a cable : the strip
|
||||
//then needs the zone drawn under it to let the cables out, like the
|
||||
//schematic style does.
|
||||
bool haveCable(const AbstractTerminalStripInterface *strip)
|
||||
{
|
||||
if (!strip) {
|
||||
return false;
|
||||
}
|
||||
for (const auto &physical_t : strip->physicalTerminal())
|
||||
{
|
||||
for (const auto &real_t : physical_t->realTerminals())
|
||||
{
|
||||
if (real_t && !real_t->cable().isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} //End anonymous namespace
|
||||
|
||||
QRectF boundingRect(const AbstractTerminalStripInterface *strip,
|
||||
@@ -535,7 +555,20 @@ QRectF boundingRect(const AbstractTerminalStripInterface *strip,
|
||||
}
|
||||
}
|
||||
const qreal s_{pattern.m_realistic_px_per_mm};
|
||||
return QRectF{0, 0, width_mm_ * s_, pattern.m_realistic_length_mm * s_};
|
||||
const qreal length_{pattern.m_realistic_length_mm * s_};
|
||||
|
||||
//The cables are drawn under the strip, in the zone the schematic
|
||||
//style reserves for them too
|
||||
qreal extra_bottom_{0};
|
||||
if (pattern.m_cable_wire_length > 0 && haveCable(strip))
|
||||
{
|
||||
//4 is the diameter of the circle at the end of the wires
|
||||
extra_bottom_ = pattern.m_cable_wire_length
|
||||
+ std::max<qreal>(0, pattern.m_cable_length)
|
||||
+ std::max<qreal>(0, pattern.m_cable_end_length)
|
||||
+ 4;
|
||||
}
|
||||
return QRectF{0, 0, width_mm_ * s_, length_ + extra_bottom_};
|
||||
}
|
||||
|
||||
void paint(QPainter *painter,
|
||||
@@ -595,6 +628,7 @@ void paint(QPainter *painter,
|
||||
}
|
||||
|
||||
QHash<QUuid, QVector<BridgePoint>> bridges_;
|
||||
QVector<Helpers::CableCell> cable_cells_;
|
||||
|
||||
for (const auto &g_ : geometry(&strip))
|
||||
{
|
||||
@@ -603,6 +637,24 @@ void paint(QPainter *painter,
|
||||
const auto first_{g_.reals.first()};
|
||||
const int levels_{static_cast<int>(g_.reals.size())};
|
||||
|
||||
//Cables (hoses) of this terminal : one wire exit by level, spread over
|
||||
//the width of the body, all of them leaving the strip at its bottom edge
|
||||
for (int k = 0 ; k < levels_ ; ++k)
|
||||
{
|
||||
const auto &real_t{g_.reals.at(k)};
|
||||
if (!real_t || real_t->cable().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
Helpers::CableCell cell_;
|
||||
cell_.x = x_ + w_ * (k + 0.5) / levels_;
|
||||
cell_.bottom = length_;
|
||||
cell_.cable = real_t->cable();
|
||||
cell_.wire = real_t->cableWire();
|
||||
cell_.shield = real_t->isShield();
|
||||
cell_.terminal = real_t;
|
||||
cable_cells_.append(cell_);
|
||||
}
|
||||
|
||||
//A terminal chosen in the catalog is drawn with its own clamp, so that a strip
|
||||
//mixing screw and spring terminals is drawn as it is. The spring-cage clamps
|
||||
//(opened with a screwdriver) are drawn like the push-in ones.
|
||||
@@ -793,6 +845,18 @@ void paint(QPainter *painter,
|
||||
|
||||
draw_end_stop();
|
||||
|
||||
//The cables under the strip : the wires of a cable join it, and the
|
||||
//cable ends together in the box naming where it goes -- drawn exactly
|
||||
//like the schematic style draws them, so both styles tell the same thing
|
||||
if (!cable_cells_.isEmpty())
|
||||
{
|
||||
painter->save();
|
||||
painter->setFont(pattern.font());
|
||||
painter->setPen(QPen(Qt::black, 0.5));
|
||||
Helpers::drawCables(painter, cable_cells_, pattern);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
|
||||
namespace TerminalStripDrawer {
|
||||
|
||||
//The cells of a cable drawing live with the helpers, so both drawing
|
||||
//styles build the same thing and pass it to Helpers::drawCables()
|
||||
using Helpers::CableCell;
|
||||
|
||||
/**
|
||||
* @brief TerminalStripDrawer::TerminalStripDrawer
|
||||
* @param strip
|
||||
@@ -259,20 +263,6 @@ void drawConnections(QPainter *painter, const QRectF &terminal_rect, qreal lengt
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The CableCell struct
|
||||
* What is needed to draw the cable under a terminal.
|
||||
*/
|
||||
struct CableCell
|
||||
{
|
||||
qreal x{0}; ///< x of the middle of the terminal, in the strip coordinates
|
||||
qreal bottom{0}; ///< y of the bottom of the terminal
|
||||
QString cable; ///< name of the cable (hose)
|
||||
QString wire; ///< color / number of the wire
|
||||
bool shield{false}; ///< true if the terminal is the shield of the cable
|
||||
QSharedPointer<AbstractRealTerminalInterface> terminal; ///< to ask where the cable goes
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief drawCables
|
||||
* Draw the cables under the terminals. Consecutive terminals who have the same cable name
|
||||
@@ -941,6 +931,11 @@ void Helpers::drawTypeSymbol(QPainter *painter, const QRectF &box,
|
||||
::TerminalStripDrawer::drawTypeSymbol(painter, box, type, led);
|
||||
}
|
||||
|
||||
void Helpers::drawCables(QPainter *painter, const QVector<CableCell> &cells,
|
||||
const TerminalStripLayoutPattern &pattern) {
|
||||
::TerminalStripDrawer::drawCables(painter, cells, pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TerminalStripDrawer::paint
|
||||
* @param painter
|
||||
@@ -1368,7 +1363,7 @@ void TerminalStripDrawer::paint(QPainter *painter)
|
||||
painter->setPen(cable_pen);
|
||||
painter->setFont(m_pattern->font());
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
drawCables(painter, cable_cells, *m_pattern);
|
||||
Helpers::drawCables(painter, cable_cells, *m_pattern);
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,22 @@ namespace TerminalStripDrawer
|
||||
//Symbol of the type of the terminal (fuse, diode, led...) scaled to fit in box
|
||||
void drawTypeSymbol(QPainter *painter, const QRectF &box,
|
||||
ElementData::TerminalType type, bool led);
|
||||
//What is needed to draw the cable under a terminal
|
||||
struct CableCell
|
||||
{
|
||||
qreal x{0}; ///< x of the middle of the terminal, in the strip coordinates
|
||||
qreal bottom{0}; ///< y of the bottom of the terminal
|
||||
QString cable; ///< name of the cable (hose)
|
||||
QString wire; ///< color / number of the wire
|
||||
bool shield{false}; ///< true if the terminal is the shield of the cable
|
||||
QSharedPointer<AbstractRealTerminalInterface> terminal; ///< to ask where the cable goes
|
||||
};
|
||||
//Draw the cables under the terminals, whichever style draws them :
|
||||
//consecutive terminals with the same cable share one cable, which ends
|
||||
//together in a short stub and a box naming where it goes (see drawCables()
|
||||
//in terminalstripdrawer.cpp for the whole drawing)
|
||||
void drawCables(QPainter *painter, const QVector<CableCell> &cells,
|
||||
const TerminalStripLayoutPattern &pattern);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
#include "qetapptest.h"
|
||||
|
||||
#include "TerminalStrip/GraphicsItem/realisticterminalstripdrawer.h"
|
||||
#include "TerminalStrip/GraphicsItem/trueterminalstrip.h"
|
||||
#include "TerminalStrip/physicalterminal.h"
|
||||
#include "TerminalStrip/realterminal.h"
|
||||
@@ -51,6 +52,10 @@
|
||||
the drawing -- the end zone the settings leave is what gives it the
|
||||
room, so three lines never end up squeezed into a tiny text.
|
||||
|
||||
Both drawing styles are covered: the schematic one and the
|
||||
realistic one (the strip seen from above), which paint the same
|
||||
cable through Helpers::drawCables().
|
||||
|
||||
fixtures/every_feature.qet has the strip X1 (elements 891b70f2 and
|
||||
4861e268) and the contact fc9cc920 wired to 891b70f2 by the
|
||||
conductor 8bd16d7a; the test gives the contact the Installation,
|
||||
@@ -169,6 +174,7 @@ private slots:
|
||||
void paintsWithTargetBox();
|
||||
void wireLabelStaysOutOfTheTerminal();
|
||||
void targetBoxKeepsTheDrawingFont();
|
||||
void realisticStyleDrawsTheCable();
|
||||
};
|
||||
|
||||
void tst_cabletarget::init()
|
||||
@@ -445,6 +451,75 @@ void tst_cabletarget::targetBoxKeepsTheDrawingFont()
|
||||
QVERIFY(lowest + 2 >= row);
|
||||
}
|
||||
|
||||
/**
|
||||
The realistic style draws the cable too. The strip seen from above
|
||||
reserves the zone under it when one of its terminals carries a
|
||||
cable, and the wires, the cable and the box naming where it goes
|
||||
are painted in it -- exactly what the schematic style draws, since
|
||||
both styles now share the same Helpers::drawCables().
|
||||
*/
|
||||
void tst_cabletarget::realisticStyleDrawsTheCable()
|
||||
{
|
||||
QVERIFY(wireCableToTheContact());
|
||||
|
||||
const auto strips_ = m_project->terminalStrip();
|
||||
QVERIFY(!strips_.isEmpty());
|
||||
const auto strip_ = QSharedPointer<TerminalStripDrawer::TrueTerminalStrip>{
|
||||
new TerminalStripDrawer::TrueTerminalStrip{strips_.first()}};
|
||||
TerminalStripLayoutPattern pattern_;
|
||||
|
||||
const auto bounds_of = [&strip_, &pattern_]() {
|
||||
return TerminalStripDrawer::Realistic::boundingRect(strip_.data(),
|
||||
pattern_);
|
||||
};
|
||||
const auto render = [&strip_, &pattern_](const QRectF &bounds) {
|
||||
QImage image{bounds.size().toSize() + QSize{4, 4},
|
||||
QImage::Format_ARGB32_Premultiplied};
|
||||
image.fill(Qt::transparent);
|
||||
QPainter painter{&image};
|
||||
painter.translate(-bounds.topLeft() + QPointF{2, 2});
|
||||
TerminalStripDrawer::Realistic::paint(
|
||||
&painter, *strip_, pattern_,
|
||||
TerminalStripLayoutPattern::DrawStyle::RealisticPushIn);
|
||||
return image;
|
||||
};
|
||||
|
||||
const QRectF with_bounds{bounds_of()};
|
||||
const QImage with_cable{render(with_bounds)};
|
||||
|
||||
//The body of the strip ends there : everything painted under it
|
||||
//belongs to the cable
|
||||
const qreal body_bottom{
|
||||
pattern_.m_realistic_length_mm * pattern_.m_realistic_px_per_mm};
|
||||
QVERIFY(with_bounds.height() > body_bottom);
|
||||
|
||||
int painted_{0};
|
||||
for (auto y = qRound(body_bottom) + 4 ; y + 4 < with_cable.height() ; ++y)
|
||||
{
|
||||
for (auto x = 0 ; x + 4 < with_cable.width() ; ++x)
|
||||
{
|
||||
if (with_cable.pixel(x, y) != qRgba(0, 0, 0, 0)) {
|
||||
++painted_;
|
||||
}
|
||||
}
|
||||
}
|
||||
//The wires and the cable are drawn in that zone
|
||||
QVERIFY(painted_ > 0);
|
||||
|
||||
//The same strip, its terminal carries no cable name any more
|
||||
Element *terminal_ = element(
|
||||
QStringLiteral("{891b70f2-2822-41c3-9f94-28efb448b5c4}"));
|
||||
QVERIFY(terminal_);
|
||||
ElementData terminal_data_{terminal_->elementData()};
|
||||
terminal_data_.m_informations.addValue(RealTerminal::cableInfoKey(),
|
||||
QString());
|
||||
terminal_->setElementData(terminal_data_);
|
||||
|
||||
//No cable to let out : the strip does not reserve the zone
|
||||
const QRectF without_bounds{bounds_of()};
|
||||
QVERIFY(without_bounds.height() < with_bounds.height());
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QStandardPaths::setTestModeEnabled(true);
|
||||
|
||||
Reference in New Issue
Block a user