Terminal strip item can be added to diagram

Initial commit about graphics item of a terminal strip, Work in
progress.
This commit is contained in:
joshua
2022-08-27 21:24:25 +02:00
parent d9a0b03e23
commit ff80453f2c
13 changed files with 751 additions and 3 deletions

View File

@@ -0,0 +1,49 @@
/*
Copyright 2006-2022 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "terminalstripitem.h"
#include "../../qetgraphicsitem/qgraphicsitemutility.h"
TerminalStripItem::TerminalStripItem(QPointer<TerminalStrip> strip, QGraphicsItem *parent) :
QetGraphicsItem{parent},
m_strip{strip},
m_drawer{strip}
{
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
setAcceptHoverEvents(true);
}
void TerminalStripItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option)
Q_UNUSED(widget)
m_drawer.paint(painter);
if (isSelected() || isHovered())
{
QGIUtility::drawBoundingRectSelection(this, painter);
}
}
QRectF TerminalStripItem::boundingRect() const
{
auto br_ = m_drawer.boundingRect();
br_.adjust(-5,-5,5,5);
return br_;
}

View File

@@ -0,0 +1,44 @@
/*
Copyright 2006-2022 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TERMINALSTRIPITEM_H
#define TERMINALSTRIPITEM_H
#include <QGraphicsObject>
#include "terminalstriplayoutpattern.h"
#include "../../qetgraphicsitem/qetgraphicsitem.h"
class TerminalStrip;
class TerminalStripItem : public QetGraphicsItem
{
Q_OBJECT
public:
TerminalStripItem(QPointer<TerminalStrip> strip, QGraphicsItem *parent = nullptr);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
QRectF boundingRect() const override;
private:
QPointer<TerminalStrip> m_strip;
TerminalStripDrawer m_drawer;
};
#endif // TERMINALSTRIPITEM_H

View File

@@ -0,0 +1,247 @@
/*
Copyright 2006-2022 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "terminalstriplayoutpattern.h"
#include "../physicalterminal.h"
#include "../realterminal.h"
#include "../terminalstrip.h"
#include <QPainter>
/**
* @brief TerminalStripDrawer::TerminalStripDrawer
* @param strip
* @param pattern
*/
TerminalStripDrawer::TerminalStripDrawer(QPointer<TerminalStrip> strip) :
m_strip(strip)
{}
/**
* @brief TerminalStripDrawer::paint
* @param painter
*/
void TerminalStripDrawer::paint(QPainter *painter)
{
if (m_strip)
{
//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);
pen_.setWidth(1);
auto brush_ = painter->brush();
brush_.setColor(Qt::white);
painter->setPen(pen_);
painter->setBrush(brush_);
//Draw header
painter->drawRect(m_pattern.m_header_rect);
//Draw the header text
painter->save();
if (m_pattern.m_header_text_orientation == Qt::Horizontal)
{
text_rect.setRect(0,m_pattern.m_header_rect.y(),m_pattern.m_header_rect.width(),m_pattern.m_header_rect.height());
}
else
{
painter->translate(m_pattern.m_header_rect.bottomLeft());
painter->rotate(270);
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());
painter->restore();
//Move painter pos to next drawing
painter->translate(m_pattern.m_header_rect.width(),0);
//Draw spacer
painter->drawRect(m_pattern.m_spacer_rect);
//Move painter pos to next drawing
painter->translate(m_pattern.m_spacer_rect.width(),0);
//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;
//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<RealTerminal>> real_terminal{physical_t->realTerminals()};
const auto real_t_count{real_terminal.size()};
const auto offset_{4 - real_t_count};
//Loop over real terminals
for (auto i=0 ; i<real_t_count ; ++i)
{
const auto index_ = offset_ + i;
if (index_ >= 4) {
break;
}
terminal_rect = m_pattern.m_terminal_rect[index_];
painter->drawRect(terminal_rect);
//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(), rect_.width());
}
const auto shared_real_terminal{real_terminal[i]};
painter->drawText(text_rect,
shared_real_terminal ? shared_real_terminal->label() : QLatin1String(),
terminals_text_option[index_]);
painter->restore();
//Move painter pos to next drawing
painter->translate(terminal_rect.width(),0);
}
}
painter->restore();
}
}
QRectF TerminalStripDrawer::boundingRect() const
{
return QRect{0, 0, width(), height()};;
}
int TerminalStripDrawer::height() const
{
auto height_{m_pattern.m_header_rect.y() + m_pattern.m_header_rect.height()};
height_ = std::max(height_, m_pattern.m_spacer_rect.y() + m_pattern.m_spacer_rect.height());
for (const auto &rect : m_pattern.m_terminal_rect) {
height_ = std::max(height_, rect.y() + rect.height());
}
return height_;
}
int TerminalStripDrawer::width() const
{
int width_{m_pattern.m_header_rect.width() + m_pattern.m_spacer_rect.width()};
if (m_strip)
{
//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<RealTerminal>> real_terminal{physical_t->realTerminals()};
const auto real_t_count{real_terminal.size()};
const auto offset_{4 - real_t_count};
//Loop over real terminals
for (auto i=0 ; i<real_t_count ; ++i)
{
const auto index_ = offset_ + i;
if (index_ >= 4) {
break;
}
width_ += m_pattern.m_terminal_rect[index_].width();
}
}
}
return width_;
}
TerminalStripLayoutPattern::TerminalStripLayoutPattern()
{
updateHeaderTextOption();
updateTerminalsTextOption();
}
void TerminalStripLayoutPattern::setHeaderTextAlignment(const Qt::Alignment &alignment)
{
m_header_text_alignment = alignment;
updateHeaderTextOption();
}
Qt::Alignment TerminalStripLayoutPattern::headerTextAlignment() const
{
return m_header_text_alignment;
}
QTextOption TerminalStripLayoutPattern::headerTextOption() const {
return m_header_text_option;
}
void TerminalStripLayoutPattern::setTerminalsTextAlignment(const QVector<Qt::Alignment> &alignment)
{
m_terminals_text_alignment = alignment;
updateTerminalsTextOption();
}
QVector<Qt::Alignment> TerminalStripLayoutPattern::terminalsTextAlignment() const
{
return m_terminals_text_alignment;
}
QVector<QTextOption> TerminalStripLayoutPattern::terminalsTextOption() const
{
return m_terminals_text_option;
}
void TerminalStripLayoutPattern::updateHeaderTextOption()
{
m_header_text_option.setAlignment(m_header_text_alignment);
m_header_text_option.setWrapMode(QTextOption::WordWrap);
}
void TerminalStripLayoutPattern::updateTerminalsTextOption()
{
if (m_terminals_text_option.size() ==
m_terminals_text_alignment.size())
{
for (auto i = 0 ; i<m_terminals_text_option.size() ; ++i)
{
m_terminals_text_option[i].setAlignment(m_terminals_text_alignment.at(i));
m_terminals_text_option[i].setWrapMode(QTextOption::WordWrap);
}
}
else {
qDebug() << "TerminalStripLayoutPattern::updateTerminalsTextOption() : Wrong vector size";
}
}

View File

@@ -0,0 +1,130 @@
/*
Copyright 2006-2022 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TERMINALSTRIPLAYOUTPATTERN_H
#define TERMINALSTRIPLAYOUTPATTERN_H
#include <QPointer>
#include <QSize>
#include <QTextOption>
#include <QVector>
#include <QRect>
class QPainter;
class TerminalStrip;
/**
* @brief The TerminalStripLayoutPattern class
* A class with all values used to define how a terminal strip must be drawn.
* Most of the value are public, some values are private and have getter / setter
* because when these values change we need to compute the change.
*
* The values with name '_y_offset' mean offset is relating to the top
* of the QGraphicsItem used to display the terminal strip.
*
* The terminal strip can display up to 4 terminal level,
* the value used for multilevel terminal are stored in several QVector (m_terminal_y_offset, m_terminal_height, m_bridge_point_y_offset).
* The order of the values are from the most back terminal to the front terminal.
*/
class TerminalStripLayoutPattern
{
public:
TerminalStripLayoutPattern();
//Header of terminal strip
QRect m_header_rect{0,30,50,130};
Qt::Orientation m_header_text_orientation{Qt::Horizontal};
void setHeaderTextAlignment(const Qt::Alignment &alignment);
Qt::Alignment headerTextAlignment() const;
QTextOption headerTextOption() const;
//Spacer between the header and the terminals
QRect m_spacer_rect{0, 50, 10, 90};
//Terminals
QVector<QRect> m_terminal_rect
{
QRect{0, 0, 20, 190},
QRect{0, 10, 20, 170},
QRect{0, 20, 20, 150},
QRect{0, 30, 20, 130}
};
void setTerminalsTextAlignment(const QVector<Qt::Alignment> &alignment);
QVector<Qt::Alignment> terminalsTextAlignment() const;
QVector<QTextOption> terminalsTextOption() const;
QVector<QRect> m_terminals_text_rect
{
QRect{0,35,20,50},
QRect{0,35,20,50},
QRect{0,35,20,50},
QRect{0,35,20,50}
};
QVector<Qt::Orientation> m_terminals_text_orientation
{
Qt::Vertical,
Qt::Vertical,
Qt::Vertical,
Qt::Vertical
};
int m_bridge_point_d{5};
QVector<int> m_bridge_point_y_offset{50,70,90,110};
private:
void updateHeaderTextOption();
void updateTerminalsTextOption();
private:
Qt::Alignment m_header_text_alignment{Qt::AlignCenter};
QTextOption m_header_text_option;
QVector<Qt::Alignment> m_terminals_text_alignment
{
Qt::AlignRight | Qt::AlignVCenter,
Qt::AlignRight | Qt::AlignVCenter,
Qt::AlignRight | Qt::AlignVCenter,
Qt::AlignRight | Qt::AlignVCenter
};
QVector<QTextOption> m_terminals_text_option
{
QTextOption(),
QTextOption(),
QTextOption(),
QTextOption()
};
};
class TerminalStripDrawer
{
public:
TerminalStripDrawer(QPointer<TerminalStrip> strip);
void paint(QPainter *painter);
QRectF boundingRect() const;
private:
int height() const;
int width() const;
private:
QPointer<TerminalStrip> m_strip;
TerminalStripLayoutPattern m_pattern;
};
#endif // TERMINALSTRIPLAYOUTPATTERN_H