Ejemplo n.º 1
0
QGraphicsItem*
GIFactory::createComponentGI(
    ComponentDescriptor* type) {

    qDebug() << "Generating Graphics item for" << type->text();

    // collect all the information
    QString componentName = type->text();

    QGraphicsItemGroup* parent = new QGraphicsItemGroup();

    // create all the partial items and calculate sizes

    unsigned int inSection_minWidth = 0;
    unsigned int outSection_minWidth = 0;
    unsigned int portSection_lineHeight = 0;

    QList<PortEntry> inPorts = QList<PortEntry>();
    QList<PortEntry> outPorts = QList<PortEntry>();
    for (PortDescriptor * port : type->ports()) {


        PortEntry portEntry = PortEntry(port, parent);
        unsigned int width = portEntry.textGraphics()->boundingRect().width() + 2 * TEXT_PADDING;
        unsigned int height = portEntry.textGraphics()->boundingRect().height() + 2 * TEXT_PADDING;

        // adjust the line height, if needed
        if (height > portSection_lineHeight) {
            portSection_lineHeight = height;
        }

        switch (port->direction()) {
        case model::enums::PortDirection::IN : {
            inPorts.append(portEntry);
            if (width > inSection_minWidth) {
                inSection_minWidth = width;
            }
        }
        break;

        case model::enums::PortDirection::OUT : {
            outPorts.append(portEntry);
            if (width > outSection_minWidth) {
                outSection_minWidth = width;
            }
        }
        break;
        default:
            continue; // do not handle other types.
        }

    }

    std::sort(inPorts.begin(), inPorts.end());
    std::sort(outPorts.begin(), outPorts.end());


    unsigned int portSection_height =
        inPorts.count() > outPorts.count() ?
        inPorts.count() * portSection_lineHeight :
        outPorts.count() * portSection_lineHeight;

    QGraphicsTextItem* text_compName = new QGraphicsTextItem(componentName, parent);
    parent->addToGroup(text_compName);

    unsigned int nameSection_minWidth = text_compName->boundingRect().width() + 2 * TEXT_PADDING;
    unsigned int nameSection_height = text_compName->boundingRect().height() + 2 * TEXT_PADDING;

    // adjust the total width
    unsigned int totalWidth  = 0;
    if (nameSection_minWidth > (inSection_minWidth + outSection_minWidth)) {
        totalWidth = nameSection_minWidth;
        if (inSection_minWidth > totalWidth / 2) { // extend outSection_minWidth
            outSection_minWidth = totalWidth - inSection_minWidth;
        } else if (outSection_minWidth > totalWidth / 2) { // extend inSection_minWidth
            inSection_minWidth = totalWidth - outSection_minWidth;
        } else { // stretch both to totalWidth / 2
            inSection_minWidth = totalWidth / 2;
            outSection_minWidth = totalWidth / 2;
        }
    } else { // adjust nameSection_minWidth
        totalWidth = inSection_minWidth + outSection_minWidth;
    }

    // now actually place all the stuff
    QBrush nameSectionBrush = QBrush(Qt::lightGray, Qt::SolidPattern);
    QBrush portSectionBrush = QBrush(Qt::white, Qt::SolidPattern);
    QPen pen = QPen(Qt::black, Qt::SolidLine);
    QPoint currentPos = QPoint(0, 0);

    // draw the rectangles
    QGraphicsRectItem* nameSection = new QGraphicsRectItem(
        currentPos.x(), currentPos.y(),
        totalWidth, nameSection_height, parent);
    nameSection->setBrush(nameSectionBrush);
    nameSection->setPen(pen);
    nameSection->setZValue(-1);
    parent->addToGroup(nameSection);

    currentPos.ry() += nameSection_height;
    QGraphicsRectItem* inSection = new QGraphicsRectItem(
        currentPos.x(), currentPos.y(),
        inSection_minWidth, portSection_height, parent);
    inSection->setBrush(portSectionBrush);
    inSection->setPen(pen);
    inSection->setZValue(-1);
    parent->addToGroup(inSection);

    currentPos.rx() += inSection_minWidth;
    QGraphicsRectItem* outSection = new QGraphicsRectItem(
        currentPos.x(), currentPos.y(),
        outSection_minWidth, portSection_height, parent);
    outSection->setBrush(portSectionBrush);
    outSection->setPen(pen);
    outSection->setZValue(-1);
    parent->addToGroup(outSection);

    // place the texts and set the port positions in the port descriptor
    text_compName->setPos((totalWidth - text_compName->boundingRect().width()) / 2,
                          /*0 + */ TEXT_PADDING);

    currentPos.setX(0);
    currentPos.setY(nameSection_height);
    for(PortEntry inIter : inPorts){
        inIter.textGraphics()->setPos(currentPos.x() + TEXT_PADDING, currentPos.y() + TEXT_PADDING);
        currentPos.ry() += portSection_lineHeight / 2;
        QPoint portPos = QPoint(currentPos.x() - PORT_DIAMETER, currentPos.y());
        inIter.descriptor()->setPosition(portPos);

        QGraphicsLineItem* lineToPort = new QGraphicsLineItem(QLineF(portPos, currentPos), parent);
        parent->addToGroup(lineToPort);
        currentPos.ry() += portSection_lineHeight / 2;
    }

    currentPos.setX(totalWidth);
    currentPos.setY(nameSection_height);
   for(PortEntry outIter : outPorts){
        outIter.textGraphics()->setPos(
            currentPos.x() - TEXT_PADDING - outIter.textGraphics()->boundingRect().width(),
            currentPos.y() + TEXT_PADDING);
        currentPos.ry() += portSection_lineHeight / 2;
        QPoint portPos = QPoint(currentPos.x() + PORT_DIAMETER, currentPos.y());
        outIter.descriptor()->setPosition(portPos);

        QGraphicsLineItem* lineToPort = new QGraphicsLineItem(QLineF(currentPos, portPos), parent);
        parent->addToGroup(lineToPort);
        currentPos.ry() += portSection_lineHeight / 2;
    }

    parent->setVisible(true);
    return parent;
}
Ejemplo n.º 2
-4
BoardScene::BoardScene(const SLFormat::Board* inBoard, QWidget* inParent)
    :QGraphicsScene(inParent), mBoard(inBoard)
{
    this->setSceneRect(0, 0, mBoard->size().x, mBoard->size().y);

    // background
    const unsigned activeLayer = mBoard->activeLayer();
    QBrush brush(gSettings().backgroundColor());
    QPen pen(brush.color());
    mBackground = this->addRect(this->sceneRect(), pen, brush);

    // ground planes (initially invisible)
    for (unsigned i = 0; i < SLFormat::Board::cNumberLayers; i++)
    {
        unsigned layer = gSettings().layerFromOrderNumber(i);
        if (mBoard->isGroundPlaneSupported(layer))
        {
            QGraphicsItemGroup* plane = new QGraphicsItemGroup;
            mGroundPlanes[layer] = plane;

            addItem(plane);
            plane->setVisible(false);

            auto rect = new QGraphicsRectItem(this->sceneRect());
            const QColor color = gSettings().groundPlaneLayerColor(layer);
            rect->setBrush(QBrush(color));
            rect->setPen(QPen(color));
            plane->addToGroup(rect);
        }
        else
        {
            mGroundPlanes[layer] = nullptr;
        }
    }

    // grid
    mGrid = new BoardGrid(mBoard);
    addItem(mGrid);

    // layers
    for (unsigned i = 0; i < SLFormat::Board::cNumberLayers; i++)
    {
        unsigned layer = gSettings().layerFromOrderNumber(i);
        mLayerGroups[layer] = new QGraphicsItemGroup;
        addItem(mLayerGroups[layer]);
    }

    mDrillHoles = new QGraphicsItemGroup;
    addItem(mDrillHoles);

    // components on layers
    for (auto comp : mBoard->components())
    {
        ComponentItem* item = ComponentFactory::createItem(comp);
        if (item)
        {
            unsigned layer = comp->layer();
            mLayerGroups[layer]->addToGroup(item->mainItem());
            if (mBoard->isGroundPlaneSupported(layer))
            {
                mGroundPlanes[layer]->addToGroup(item->groundPlaneItem());
            }
            mDrillHoles->addToGroup(item->drillItem());
        }
    }

    // show ground plane for active layer
    if (mBoard->isGroundPlaneEnabled(activeLayer))
    {
        assert(mGroundPlanes[activeLayer]);
        mGroundPlanes[activeLayer]->setVisible(true);
    }
}