// pluginItemWrapper.cpp #include "graphicsItem/pluginItemWrapper.h" #include "pluginManager/include/pluginManager.h" #include #include #include PluginItemWrapper::PluginItemWrapper(ICanvasItem *pluginItem, QGraphicsItem *parent) : GraphicsFunctionModelItem(parent) , m_pluginItem(pluginItem) { if (!m_pluginItem) { qWarning() << "PluginItemWrapper: pluginItem is null!"; return; } // 设置类型 m_Itemtype = GIT_PluginItem; // 设置初始名称 setName(m_pluginItem->displayName()); // 连接信号 connectSignals(); // 初始化缓存 updateCache(); // 更新坐标 updateCoordinate(); qDebug() << "PluginItemWrapper created for:" << m_pluginItem->typeId(); } PluginItemWrapper::~PluginItemWrapper() { // 删除插件项 if (m_pluginItem) { m_pluginItem->deleteLater(); } } GraphicsFunctionModelItem* PluginItemWrapper::clone() const { if (!m_pluginItem) { return nullptr; } // 获取场景中的PluginManager PluginManager *manager = PluginManager::instance(); if (!manager) { qWarning() << "PluginManager not available for cloning"; return nullptr; } // 获取插件类型 QString pluginType = m_pluginItem->typeId(); // 保存当前状态 QVariantMap state = saveState(); // 创建新的插件项 ICanvasItem *newPluginItem = manager->createItem(pluginType); if (!newPluginItem) { qWarning() << "Failed to create plugin item for cloning:" << pluginType; return nullptr; } // 恢复状态 if (!loadStateIntoPluginItem(newPluginItem, state)) { qWarning() << "Failed to restore state for cloned item"; delete newPluginItem; return nullptr; } // 创建新的包装器 PluginItemWrapper *clone = new PluginItemWrapper(newPluginItem, parentItem()); // 复制变换属性 clone->setPos(pos()); clone->setRotation(rotation()); clone->setScale(scale()); clone->setZValue(zValue()); // 复制其他属性 clone->copyPropertiesFrom(this); qDebug() << "Cloned plugin item:" << pluginType; return clone; } void PluginItemWrapper::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { if (!painter || !m_pluginItem) { return; } painter->save(); // 设置抗锯齿 painter->setRenderHint(QPainter::Antialiasing, true); // 让插件绘制 m_pluginItem->draw(painter, m_cachedBounds); // 如果选中,绘制控制框 if (option && (option->state & QStyle::State_Selected)) { painter->setPen(QPen(QColor(0, 120, 215), 1, Qt::DashLine)); painter->setBrush(Qt::NoBrush); // 绘制选中框 QRectF selectRect = m_cachedBounds.adjusted(-2, -2, 2, 2); painter->drawRect(selectRect); // 绘制控制点 const qreal handleSize = 6.0; QRectF handleRect(-handleSize/2, -handleSize/2, handleSize, handleSize); QBrush handleBrush(QColor(0, 120, 215)); QPen handlePen(Qt::white, 1); // 绘制8个控制点 QPointF corners[] = { m_cachedBounds.topLeft(), m_cachedBounds.topRight(), m_cachedBounds.bottomRight(), m_cachedBounds.bottomLeft(), QPointF(m_cachedBounds.center().x(), m_cachedBounds.top()), QPointF(m_cachedBounds.right(), m_cachedBounds.center().y()), QPointF(m_cachedBounds.center().x(), m_cachedBounds.bottom()), QPointF(m_cachedBounds.left(), m_cachedBounds.center().y()) }; for (const QPointF &corner : corners) { painter->save(); painter->translate(corner); painter->setPen(handlePen); painter->setBrush(handleBrush); painter->drawEllipse(handleRect); painter->restore(); } } painter->restore(); } QRectF PluginItemWrapper::boundingRect() const { qreal margin = 4.0; // 为控制点留出空间 return m_cachedBounds.adjusted(-margin, -margin, margin, margin); } QPainterPath PluginItemWrapper::shape() const { QPainterPath path; if (!m_pluginItem) { return path; } // 创建简单的矩形路径 // 插件可以提供更精确的形状,这里简化处理 path.addRect(m_cachedBounds); return path; } void PluginItemWrapper::updateCoordinate() { if (!m_pluginItem) { return; } // 更新基类属性 QRectF bounds = m_pluginItem->bounds(); m_dWidth = bounds.width(); m_dHeight = bounds.height(); // 更新包围框 m_boundingRect = bounds; // 更新变换 setTransformOriginPoint(bounds.center()); // 调用基类更新 GraphicsFunctionModelItem::updateCoordinate(); // 更新句柄位置 updateHandles(); } void PluginItemWrapper::resize(int handle, double dx, double dy, const QPointF &pos) { if (!m_pluginItem) { return; } QRectF bounds = m_pluginItem->bounds(); QRectF newBounds = bounds; // 根据控制点调整大小 switch (handle) { case H_leftTop: newBounds.setTopLeft(newBounds.topLeft() + QPointF(dx, dy)); break; case H_top: newBounds.setTop(newBounds.top() + dy); break; case H_rightTop: newBounds.setTopRight(newBounds.topRight() + QPointF(dx, dy)); break; case H_right: newBounds.setRight(newBounds.right() + dx); break; case H_rightBottom: newBounds.setBottomRight(newBounds.bottomRight() + QPointF(dx, dy)); break; case H_bottom: newBounds.setBottom(newBounds.bottom() + dy); break; case H_leftBottom: newBounds.setBottomLeft(newBounds.bottomLeft() + QPointF(dx, dy)); break; case H_left: newBounds.setLeft(newBounds.left() + dx); break; default: // 不是控制点,直接移动 move(QPointF(dx, dy)); return; } // 确保大小有效 if (newBounds.width() < 10) { newBounds.setWidth(10); } if (newBounds.height() < 10) { newBounds.setHeight(10); } if (newBounds.isValid() && newBounds != bounds) { m_pluginItem->setBounds(newBounds); } } void PluginItemWrapper::move(const QPointF &delta) { if (!m_pluginItem || delta.isNull()) { return; } QRectF bounds = m_pluginItem->bounds(); bounds.translate(delta); m_pluginItem->setBounds(bounds); } ICanvasItem* PluginItemWrapper::pluginItem() const { return m_pluginItem; } QVariant PluginItemWrapper::itemChange(GraphicsItemChange change, const QVariant &value) { if (!m_pluginItem) { return GraphicsFunctionModelItem::itemChange(change, value); } switch (change) { case ItemSelectedChange: // 选中状态变化 if (value.toBool()) { // 选中时的处理 setHandleVisible(true); } else { // 取消选中的处理 setHandleVisible(false); } break; case ItemPositionChange: { // 位置变化 QPointF newPos = value.toPointF(); QPointF delta = newPos - pos(); // 更新插件项的位置 QRectF bounds = m_pluginItem->bounds(); bounds.translate(delta); m_pluginItem->setBounds(bounds); return newPos; } case ItemRotationChange: // 旋转变化 // 插件项可能需要处理旋转 break; case ItemScaleChange: // 缩放变化 // 插件项可能需要处理缩放 break; case ItemZValueChange: // Z值变化 break; default: break; } return GraphicsFunctionModelItem::itemChange(change, value); } void PluginItemWrapper::updateCache() { if (m_pluginItem) { m_cachedBounds = m_pluginItem->bounds(); } } void PluginItemWrapper::connectSignals() { if (!m_pluginItem) { return; } // 使用旧式语法连接 connect(m_pluginItem, SIGNAL(boundsChanged(QRectF)), this, SLOT(onPluginBoundsChanged(QRectF))); connect(m_pluginItem, SIGNAL(propertyChanged(QString, QVariant)), this, SLOT(onPluginPropertyChanged(QString, QVariant))); } QVariantMap PluginItemWrapper::saveState() const { QVariantMap state; if (!m_pluginItem) { return state; } // 保存基本属性 state["type"] = m_pluginItem->typeId(); state["displayName"] = m_pluginItem->displayName(); // 保存几何信息 QRectF bounds = m_pluginItem->bounds(); state["x"] = bounds.x(); state["y"] = bounds.y(); state["width"] = bounds.width(); state["height"] = bounds.height(); // 保存插件特定属性 // 这里可以保存插件的关键属性 QStringList propertyKeys = {"fillColor", "borderColor", "borderWidth", "cornerRadius"}; for (const QString &key : propertyKeys) { QVariant value = m_pluginItem->property(key); if (value.isValid()) { state[key] = value; } } return state; } bool PluginItemWrapper::loadStateIntoPluginItem(ICanvasItem *pluginItem, const QVariantMap &state) const { if (!pluginItem) { return false; } // 设置几何信息 if (state.contains("x") && state.contains("y") && state.contains("width") && state.contains("height")) { QRectF bounds( state["x"].toReal(), state["y"].toReal(), state["width"].toReal(), state["height"].toReal() ); if (bounds.isValid()) { pluginItem->setBounds(bounds); } } // 设置插件属性 QStringList propertyKeys = {"fillColor", "borderColor", "borderWidth", "cornerRadius"}; for (const QString &key : propertyKeys) { if (state.contains(key)) { pluginItem->setProperty(key, state[key]); } } return true; } void PluginItemWrapper::copyPropertiesFrom(const PluginItemWrapper *source) { if (!source) { return; } // 复制基类属性 m_type = source->m_type; m_pen = source->m_pen; m_brush = source->m_brush; m_dWidth = source->m_dWidth; m_dHeight = source->m_dHeight; m_boundingRect = source->m_boundingRect; m_Itemtype = source->m_Itemtype; // 复制可见性和使能状态 setVisible(source->isVisible()); setEnabled(source->isEnabled()); // 复制工具提示 setToolTip(source->toolTip()); // 复制自定义数据 setData(0, source->data(0)); // 生成新的ID setItemId(QUuid::createUuid()); } void PluginItemWrapper::onPluginBoundsChanged(const QRectF &newBounds) { m_cachedBounds = newBounds; // 更新坐标 updateCoordinate(); // 通知变化 emit itemChanged(); } void PluginItemWrapper::onPluginPropertyChanged(const QString &key, const QVariant &value) { Q_UNUSED(key); Q_UNUSED(value); // 属性变化,需要重绘 update(); // 通知变化 emit itemChanged(); }