DiagramDesigner/diagramCavas/source/graphicsItem/pluginItemWrapper.cpp

452 lines
11 KiB
C++

// pluginItemWrapper.cpp
#include "graphicsItem/pluginItemWrapper.h"
#include "pluginManager/include/pluginManager.h"
#include <QDebug>
#include <QPainter>
#include <QStyleOptionGraphicsItem>
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();
}