Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
/*
* LibrePCB - Professional EDA for everyone!
* Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors.
* https://librepcb.org/
*
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*******************************************************************************
* Includes
******************************************************************************/
#include "sgi_symbol.h"
#include "../../../graphics/circlegraphicsitem.h"
#include "../../../graphics/graphicslayer.h"
#include "../../../graphics/graphicslayerlist.h"
#include "../../../graphics/imagegraphicsitem.h"
#include "../../../graphics/origincrossgraphicsitem.h"
#include "../../../graphics/polygongraphicsitem.h"
#include "../schematicgraphicsscene.h"
#include <librepcb/core/library/sym/symbol.h>
#include <librepcb/core/project/project.h>
#include <librepcb/core/project/schematic/items/si_symbol.h>
#include <librepcb/core/utils/toolbox.h>
#include <librepcb/core/workspace/colorrole.h>
#include <QtCore>
#include <QtWidgets>
/*******************************************************************************
* Namespace
******************************************************************************/
namespace librepcb {
namespace editor {
/*******************************************************************************
* Constructors / Destructor
******************************************************************************/
SGI_Symbol::SGI_Symbol(
SI_Symbol& symbol, const GraphicsLayerList& layers,
std::shared_ptr<const SchematicGraphicsScene::Context> context) noexcept
: QGraphicsItemGroup(),
onEdited(*this),
mSymbol(symbol),
mContext(context),
mOnEditedSlot(*this, &SGI_Symbol::symbolEdited) {
setFlag(QGraphicsItem::ItemHasNoContents, true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
setZValue(SchematicGraphicsScene::ZValue_Symbols);
mOriginCrossGraphicsItem = std::make_shared<OriginCrossGraphicsItem>(this);
mOriginCrossGraphicsItem->setSize(UnsignedLength(1400000));
mOriginCrossGraphicsItem->setLayer(
layers.get(ColorRole::schematicReferences()));
// https://github.com/LibrePCB/LibrePCB/issues/1725
mOriginCrossGraphicsItem->setVisible(isSelected());
mShape.addRect(mOriginCrossGraphicsItem->boundingRect());
for (const auto& obj : mSymbol.getLibSymbol().getCircles()) {
auto i = std::make_shared<CircleGraphicsItem>(const_cast<Circle&>(obj),
layers, this);
i->setFlag(QGraphicsItem::ItemIsSelectable, true);
i->setFlag(QGraphicsItem::ItemStacksBehindParent, true);
if (obj.isGrabArea()) {
const qreal r = (obj.getDiameter() + obj.getLineWidth())->toPx() / 2;
QPainterPath path;
path.addEllipse(obj.getCenter().toPxQPointF(), r, r);
mShape |= path;
}
mCircleGraphicsItems.append(i);
}
for (const auto& obj : mSymbol.getLibSymbol().getPolygons()) {
auto i = std::make_shared<PolygonGraphicsItem>(const_cast<Polygon&>(obj),
layers, this);
i->setFlag(QGraphicsItem::ItemIsSelectable, true);
i->setFlag(QGraphicsItem::ItemStacksBehindParent, true);
if (obj.isGrabArea()) {
mShape |= Toolbox::shapeFromPath(obj.getPath().toQPainterPathPx(),
Qt::SolidLine, Qt::SolidPattern,
obj.getLineWidth());
}
mPolygonGraphicsItems.append(i);
}
for (const auto& obj :
const_cast<ImageList&>(mSymbol.getLibSymbol().getImages()).values()) {
auto i = std::make_shared<ImageGraphicsItem>(
mSymbol.getLibSymbol().getDirectory(), obj, layers, this);
i->setFlag(QGraphicsItem::ItemIsSelectable, true);
i->setFlag(QGraphicsItem::ItemStacksBehindParent, true);
mShape |= i->mapToParent(i->shape());
mImageGraphicsItems.append(i);
}
updateContext();
updatePosition();
updateRotationAndMirrored();
mSymbol.onEdited.attach(mOnEditedSlot);
}
SGI_Symbol::~SGI_Symbol() noexcept {
}
/*******************************************************************************
* General Methods
******************************************************************************/
void SGI_Symbol::updateContext() noexcept {
const GraphicsLayer::State state =
mContext->getLayerState(false, &mSymbol.getComponentInstance());
foreach (const auto& i, mCircleGraphicsItems) {
i->setState(state);
}
foreach (const auto& i, mPolygonGraphicsItems) {
i->setState(state);
}
// foreach (const auto& i, mImageGraphicsItems) {
// i->setState(state); // Not supported yet
// }
}
/*******************************************************************************
* Private Methods
******************************************************************************/
void SGI_Symbol::symbolEdited(const SI_Symbol& obj,
SI_Symbol::Event event) noexcept {
Q_UNUSED(obj);
switch (event) {
case SI_Symbol::Event::PositionChanged:
updatePosition();
break;
case SI_Symbol::Event::RotationChanged:
case SI_Symbol::Event::MirroredChanged:
updateRotationAndMirrored();
break;
default:
qWarning() << "Unhandled switch-case in SGI_Symbol::symbolEdited():"
<< static_cast<int>(event);
break;
}
}
void SGI_Symbol::updatePosition() noexcept {
setPos(mSymbol.getPosition().toPxQPointF());
onEdited.notify(Event::PositionChanged);
}
void SGI_Symbol::updateRotationAndMirrored() noexcept {
QTransform t;
t.rotate(-mSymbol.getRotation().toDeg());
if (mSymbol.getMirrored()) t.scale(qreal(-1), qreal(1));
setTransform(t);
}
QVariant SGI_Symbol::itemChange(GraphicsItemChange change,
const QVariant& value) noexcept {
if ((change == ItemSelectedHasChanged) && mOriginCrossGraphicsItem) {
// https://github.com/LibrePCB/LibrePCB/issues/1725
mOriginCrossGraphicsItem->setVisible(value.toBool());
mOriginCrossGraphicsItem->setSelected(value.toBool());
foreach (const auto& i, mCircleGraphicsItems) {
i->setSelected(value.toBool());
}
foreach (const auto& i, mPolygonGraphicsItems) {
i->setSelected(value.toBool());
}
onEdited.notify(Event::SelectionChanged);
}
return QGraphicsItem::itemChange(change, value);
}
/*******************************************************************************
* End of File
******************************************************************************/
} // namespace editor
} // namespace librepcb
bae9c0e4eThis file is pinned to the selected release. Download the original to open it in your design tool.