diff --git a/ArchitectureColoredPainting/EditorWidgetItem.ui b/ArchitectureColoredPainting/EditorWidgetItem.ui index 93811f0..aea28b0 100644 --- a/ArchitectureColoredPainting/EditorWidgetItem.ui +++ b/ArchitectureColoredPainting/EditorWidgetItem.ui @@ -6,8 +6,8 @@ 0 0 - 1124 - 1010 + 1473 + 1103 @@ -56,7 +56,20 @@ - + + + + 1080 + 1080 + + + + + 1080 + 1080 + + + diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetItem.cpp b/ArchitectureColoredPainting/src/Editor/EditorWidgetItem.cpp index 01ca5b3..0a3f01b 100644 --- a/ArchitectureColoredPainting/src/Editor/EditorWidgetItem.cpp +++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetItem.cpp @@ -14,6 +14,8 @@ EditorWidgetItem::EditorWidgetItem(QString filePath,QWidget *parent) : QWidget(p elementInfoDisplayWidget = dynamic_cast(tabWidget->widget(1)); qDebug() << layerInfoDisplayWidget; qDebug() << elementInfoDisplayWidget; + connect(previewWindow, &PreviewWindow::layerInfoChanged, layerInfoDisplayWidget, &InfoDisplayWidget::triggerSelfRefresh); + connect(treeWidget, &LayerTreeWidget::displayLayerChange, previewWindow, &PreviewWindow::currentLayerChanged); connect(treeWidget, &LayerTreeWidget::requireRefreshElementWidget, elementInfoDisplayWidget, &ElementPoolWidget::refresh); connect(layerInfoDisplayWidget, &InfoDisplayWidget::requireRefreshElementWidget, elementInfoDisplayWidget, &ElementPoolWidget::refresh); connect(treeWidget, &LayerTreeWidget::displayLayerChange, this, &EditorWidgetItem::onLayerChange); @@ -57,7 +59,11 @@ EditorWidgetItem::~EditorWidgetItem() void EditorWidgetItem::paintEvent(QPaintEvent *event) { + QPainter painter(this); + // 设置画刷的颜色为灰色,并填充整个窗口区域 + painter.setBrush(Qt::gray); + painter.drawRect(this->rect()); } void EditorWidgetItem::onLayerChange(LayerWrapper *layer) diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp index 0c7bf52..9602f2d 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp @@ -47,6 +47,7 @@ PixelPath SimpleElement::getPaintObject(std::vector> PixelPath result; Renderer::ElementStyleStrokeDemo demo(2); auto [img, mov] = renderer->drawElement(painterPath, demo, 1.0); + //qDebug() << mov; //qDebug() << img << " ------"; result.addImage(img, mov); //result.addPath(painterPath); @@ -82,4 +83,28 @@ QJsonObject GraphicElement::toJson() const QJsonObject result; result.insert("name", name); return result; +} + +void SimpleElement::paint(QPainter* painter, QTransform transform, vector> styles) +{ + painter->save(); + painter->setTransform(transform); + if (styles.empty()) + { + painter->drawPath(painterPath); + } + else + { + // TODO:应用style + Renderer::ElementStyleStrokeDemo demo(2); + auto [img, mov] = renderer->drawElement(painterPath, demo, 1.0); + painter->drawImage(mov, img); + } + + painter->restore(); +} + +void GroupElement::paint(QPainter* painter, QTransform transform, vector> styles) +{ + sourceLayer->paint(painter, transform); } \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.h b/ArchitectureColoredPainting/src/Editor/GraphicElement.h index c0b3c09..577f7db 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.h +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.h @@ -28,6 +28,7 @@ public: virtual QJsonObject toJson() const; virtual PixelPath getPaintObject() const = 0; virtual PixelPath getPaintObject(std::vector>*) const = 0; + virtual void paint(QPainter* painter, QTransform transform, std::vector> styles) = 0; }; class SimpleElement : public GraphicElement @@ -44,6 +45,7 @@ public: ~SimpleElement() = default; PixelPath getPaintObject() const override; PixelPath getPaintObject(std::vector>*) const override; + void paint(QPainter* painter, QTransform transform, std::vector> styles) override; }; class GroupElement : public GraphicElement @@ -58,6 +60,7 @@ public: PixelPath getPaintObject() const override; PixelPath getPaintObject(std::vector>*) const override; void setSourceLayer(FolderLayerWrapper* sourceLayer); + void paint(QPainter* painter, QTransform transform, std::vector> styles) override; }; //******************************** BitmapPath ********************************// diff --git a/ArchitectureColoredPainting/src/Editor/LayerManager.cpp b/ArchitectureColoredPainting/src/Editor/LayerManager.cpp index a9b73b8..06f0170 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerManager.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerManager.cpp @@ -11,10 +11,10 @@ LayerWrapper *LayerManager::getRoot() const { return root; } -void LayerManager::paint(QPainter *painter, QSize size) const +void LayerManager::paint(QPainter *painter, QSize size,LayerWrapper* selecetedLayer) const { - auto p = root->getCache().resizedPixel(size); - painter->drawPixmap(0, 0, p); + root->getCache(); + root->paint(painter); } bool LayerManager::singleSelectedCheck() const { diff --git a/ArchitectureColoredPainting/src/Editor/LayerManager.h b/ArchitectureColoredPainting/src/Editor/LayerManager.h index 390cfed..6f065fc 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerManager.h +++ b/ArchitectureColoredPainting/src/Editor/LayerManager.h @@ -32,7 +32,7 @@ class LayerManager LayerManager() = default; LayerManager(QJsonObject source, ElementManager* elementManager); QJsonObject toJson() const; - void paint(QPainter *painter, QSize size) const; + void paint(QPainter *painter, QSize size, LayerWrapper* selecetedLayer=nullptr) const; bool rename(QString newName) const; bool combine() const; // bool seperate() const; diff --git a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp index c149185..d5f28e7 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp @@ -23,9 +23,13 @@ FolderLayerWrapper*LayerWrapper::getParent() const return this == nullptr ? nullptr : this->parent; } -PixelPath LayerWrapper::getCache() +PixelPath LayerWrapper::getCache(LayerWrapper* selectedLayer) { - this->refresh(); + this->refresh(selectedLayer); + if (selectedLayer == this) + { + this->cache.highLight(); + } return cache; } @@ -42,6 +46,7 @@ LayerWrapper::LayerWrapper(QJsonObject json, FolderLayerWrapper*parent, ElementM property.scale = {transformJson.value("scale").toObject().value("x").toDouble(), transformJson.value("scale").toObject().value("y").toDouble()}; property.rotation = {transformJson.value("rotation").toDouble()}; + selected = false; } FolderLayerWrapper::FolderLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent) @@ -75,35 +80,52 @@ LeafLayerWrapper::LeafLayerWrapper(QJsonObject json, ElementManager *elementMana int elementIndex = json.value("element").toInt(); wrappedElement = elementManager->getElementById(elementIndex); } -void LayerWrapper::SimpleProperty::apply(PixelPath&cache) const + +void LayerWrapper::SimpleProperty::apply(PixelPath&cache) +{ + transform.reset(); + double centerX = cache.getBoundingRect().center().x(); + double centerY = cache.getBoundingRect().center().y(); + //qDebug() << name << " " << cache.boundingRect().center(); + //qDebug() << name << " " << cache.boundingRect(); + transform.translate(centerX, centerY); + transform.translate(offset.x(), offset.y()); + transform.rotate(rotation); + transform.scale(scale.x(), scale.y()); + transform.translate(-centerX, -centerY); + cache = cache.trans(transform); +} + +QTransform LayerWrapper::getTransform() { QTransform trans; double centerX = cache.getBoundingRect().center().x(); double centerY = cache.getBoundingRect().center().y(); //qDebug() << name << " " << cache.boundingRect().center(); //qDebug() << name << " " << cache.boundingRect(); - trans.translate(offset.x(), offset.y()); - trans.translate(-centerX, -centerY); - trans.rotate(rotation); - trans.scale(scale.x(), scale.y()); trans.translate(centerX, centerY); - cache = cache.trans(trans); + trans.translate(property.offset.x(), property.offset.y()); + trans.rotate(property.rotation); + trans.scale(property.scale.x(), property.scale.y()); + trans.translate(-centerX, -centerY); + return trans; } -void LayerWrapper::refresh() + +void LayerWrapper::refresh(LayerWrapper* layer) { property.apply(cache); } -void FolderLayerWrapper::refresh() +void FolderLayerWrapper::refresh(LayerWrapper* layer) { cache.clear(); for (auto& child : children) { - cache.addPath(child.get()->getCache()); + cache.addPath(child.get()->getCache(layer)); } LayerWrapper::refresh(); } -void LeafLayerWrapper::refresh() +void LeafLayerWrapper::refresh(LayerWrapper* layer) { cache.clear(); if (wrappedElement != nullptr) @@ -227,4 +249,37 @@ int FolderLayerWrapper::getReferencedBy()const return this->elementManager->getLayerReferencedBy(this); else return -1; +} + +void LayerWrapper::paint(QPainter* painter, QTransform transform) +{ + if (this->selected) + { + painter->save(); + painter->setTransform(transform); + painter->setPen(QPen(Qt::gray, 2)); + painter->setPen(Qt::DashLine); + painter->drawRect(cache.getBoundingRect()); + painter->restore(); + } +} + +void FolderLayerWrapper::paint(QPainter* painter, QTransform transform) +{ + LayerWrapper::paint(painter, transform); + transform = property.transform * transform; + qDebug() << transform; + for (auto& child : children) + child->paint(painter, transform); +} + +void LeafLayerWrapper::paint(QPainter* painter, QTransform transform) +{ + LayerWrapper::paint(painter, transform); + transform = property.transform * transform; + qDebug() << transform; + if (wrappedElement != nullptr) + { + wrappedElement->paint(painter, transform, styles); + } } \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/LayerWrapper.h b/ArchitectureColoredPainting/src/Editor/LayerWrapper.h index 84e7cab..7df5d13 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerWrapper.h +++ b/ArchitectureColoredPainting/src/Editor/LayerWrapper.h @@ -35,6 +35,7 @@ class LayerWrapper public: QTreeWidgetItem* qTreeWidgetItem; + bool selected; struct SimpleProperty { QString name = ""; @@ -43,17 +44,20 @@ class LayerWrapper double rotation = 0; bool flipHorizontally = 0; bool flipVertically = 0; + QTransform transform; // TODO: 将QPainterPath改为BitmapPath - void apply(PixelPath&cache) const; + void apply(PixelPath&cache); } property; virtual void setParent(FolderLayerWrapper*newParent); - virtual void refresh(); + virtual void refresh(LayerWrapper* layer = nullptr); virtual QTreeWidgetItem* getQTreeItem(); // TODO: 将QPainterPath改为BitmapPath/QImage,或者直接将其删除,绘制时直接使用BitmapPath的paint方法 - virtual PixelPath getCache(); + virtual PixelPath getCache(LayerWrapper* selectedLayer=nullptr); + QTransform getTransform(); FolderLayerWrapper*getParent() const; // invoke by manager, then invoke parent's applyStyles LayerWrapper(QJsonObject json, FolderLayerWrapper*parent, ElementManager* elementManager=nullptr); LayerWrapper() = default; + virtual void paint(QPainter* painter, QTransform transform=QTransform()); // TODO : export Function // virtual LayerWrapper *addChild() = 0; // Leaf Child Only // virtual LayerWrapper *addParent() = 0; // Folder Parent Only @@ -75,7 +79,7 @@ class FolderLayerWrapper : public LayerWrapper public: ~FolderLayerWrapper() = default; - void refresh() override; + void refresh(LayerWrapper* layer=nullptr) override; FolderLayerWrapper() = default; FolderLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent); void addChild(shared_ptr child); @@ -86,6 +90,7 @@ class FolderLayerWrapper : public LayerWrapper QTreeWidgetItem* getQTreeItem() override; QJsonObject toJson() const override; int getReferencedBy()const; + void paint(QPainter* painter, QTransform transform = QTransform()) override; }; class LeafLayerWrapper : public LayerWrapper @@ -97,10 +102,11 @@ class LeafLayerWrapper : public LayerWrapper public: ~LeafLayerWrapper() = default; - void refresh() override; + void refresh(LayerWrapper* layer = nullptr) override; LeafLayerWrapper() = default; LeafLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent); QJsonObject toJson() const override; + void paint(QPainter* painter, QTransform transform = QTransform()) override; }; Q_DECLARE_METATYPE(LayerWrapper *) diff --git a/ArchitectureColoredPainting/src/Editor/PixelPath.cpp b/ArchitectureColoredPainting/src/Editor/PixelPath.cpp index 447f8aa..89f4bbc 100644 --- a/ArchitectureColoredPainting/src/Editor/PixelPath.cpp +++ b/ArchitectureColoredPainting/src/Editor/PixelPath.cpp @@ -102,4 +102,19 @@ QPixmap PixelPath::getDetail()const qDebug() << rect; result = pixmap.copy(rect); return result; +} + +void PixelPath::highLight() +{ + // 创建一个QPainter对象,关联到QPixmap对象 + QPainter painter(&pixmap); + + // 设置画笔的颜色、宽度和样式 + painter.setPen(QPen(Qt::black, 1, Qt::DashLine)); + + // 绘制一个矩形,指定左上角和右下角的坐标 + painter.drawRect(boundingRect); + + // 结束绘制 + painter.end(); } \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/PixelPath.h b/ArchitectureColoredPainting/src/Editor/PixelPath.h index 33268db..a764ce8 100644 --- a/ArchitectureColoredPainting/src/Editor/PixelPath.h +++ b/ArchitectureColoredPainting/src/Editor/PixelPath.h @@ -26,4 +26,5 @@ public: PixelPath trans(QTransform& mat)const; QPixmap resizedPixel(QSize size)const; QPixmap getDetail()const; + void highLight(); }; \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/PreviewWindow.cpp b/ArchitectureColoredPainting/src/Editor/PreviewWindow.cpp index 0db3c48..485977d 100644 --- a/ArchitectureColoredPainting/src/Editor/PreviewWindow.cpp +++ b/ArchitectureColoredPainting/src/Editor/PreviewWindow.cpp @@ -2,6 +2,7 @@ PreviewWindow::PreviewWindow(QWidget *parent) : QOpenGLWidget(parent) { + this->setFixedSize(QSize(1080, 1080)); this->renderer = Renderer::ElementRenderer::instance(); QSurfaceFormat surfaceFormat; surfaceFormat.setSamples(16); @@ -10,6 +11,7 @@ PreviewWindow::PreviewWindow(QWidget *parent) : QOpenGLWidget(parent) painter->setRenderHint(QPainter::SmoothPixmapTransform); painter->setRenderHint(QPainter::HighQualityAntialiasing); layerManager = nullptr; + currentLayer = nullptr; } void PreviewWindow::initialize(LayerManager *layerManager,QSize windowSize) @@ -46,7 +48,7 @@ void PreviewWindow::paintGL() painter->begin(this); painter->setRenderHint(QPainter::Antialiasing); painter->setRenderHint(QPainter::HighQualityAntialiasing); - layerManager->paint(painter,this->size()); + layerManager->paint(painter,this->size(),currentLayer); painter->end(); } @@ -56,4 +58,48 @@ void PreviewWindow::resizeGL(int w, int h) Renderer::ElementRenderer* const PreviewWindow::getRenderer()const { return this->renderer; +} + +void PreviewWindow::currentLayerChanged(LayerWrapper* layer) +{ + this->currentLayer = layer; +} + +void PreviewWindow::refresh() +{ + this->repaint(); +} + +void PreviewWindow::mousePressEvent(QMouseEvent* event) +{ + // 当鼠标按下时,记录当前的位置 + m_lastPos = event->pos(); +} + +void PreviewWindow::mouseMoveEvent(QMouseEvent* event) +{ + // 当鼠标移动时,计算移动的距离,并根据需要更新图形的状态 + int dx = event->x() - m_lastPos.x(); + int dy = event->y() - m_lastPos.y(); + if (currentLayer != nullptr) { + if (event->buttons() & Qt::LeftButton) { + // 如果按下的是左键,那么平移图形 + currentLayer->property.offset.setX(currentLayer->property.offset.x() + dx); + currentLayer->property.offset.setY(currentLayer->property.offset.y() + dy); + qDebug() << dx << "----" << dy; + } + else if (event->buttons() & Qt::RightButton) { + // 如果按下的是右键,那么旋转图形 + qreal angle = dx; + currentLayer->property.rotation += angle; + } + } + // 更新上一次的位置 + m_lastPos = event->pos(); + this->repaint(); +} + +void PreviewWindow::mouseReleaseEvent(QMouseEvent* event) +{ + emit layerInfoChanged(); } \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/PreviewWindow.h b/ArchitectureColoredPainting/src/Editor/PreviewWindow.h index 9a0a4bc..66f4a52 100644 --- a/ArchitectureColoredPainting/src/Editor/PreviewWindow.h +++ b/ArchitectureColoredPainting/src/Editor/PreviewWindow.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include "../Renderer/Preview/ElementRenderer.h" @@ -19,7 +20,13 @@ class PreviewWindow : public QOpenGLWidget, protected QOpenGLFunctions LayerManager *layerManager; Renderer::ElementRenderer* renderer; QSize logicalSize; - + QRectF viewportRect; + LayerWrapper* currentLayer; + QPointF m_lastPos; + void mousePressEvent(QMouseEvent* event) override; + void mouseMoveEvent(QMouseEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; + public: PreviewWindow(QWidget *parent = nullptr); void initialize(LayerManager *layerManager, QSize windowSize = QSize(1920, 1080)); @@ -28,4 +35,11 @@ class PreviewWindow : public QOpenGLWidget, protected QOpenGLFunctions void paintGL() override; void resizeGL(int w, int h) override; Renderer::ElementRenderer* const getRenderer()const; + + public slots: + void currentLayerChanged(LayerWrapper*); + void refresh(); + + signals: + void layerInfoChanged(); }; diff --git a/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.cpp b/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.cpp index 1889d70..1e84c88 100644 --- a/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.cpp +++ b/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.cpp @@ -12,11 +12,19 @@ LayerTreeWidget::LayerTreeWidget(QWidget *parent) this->setHeaderLabel("Layer Content"); connect(this, &QTreeWidget::customContextMenuRequested, this, &LayerTreeWidget::popMenu); connect(this, &QTreeWidget::currentItemChanged, [=](QTreeWidgetItem *currentItem) { + if (this->selectedItem != nullptr) { + this->selectedItem->data(0, Qt::UserRole).value()->selected = false; + } this->selectedItem = currentItem; - if(this->selectedItem !=nullptr) - emit displayLayerChange(this->selectedItem->data(0, Qt::UserRole).value()); - else - emit displayLayerChange(nullptr); + if (this->selectedItem != nullptr) { + auto layer = this->selectedItem->data(0, Qt::UserRole).value(); + layer->selected = true; + emit displayLayerChange(layer); + } + else { + emit displayLayerChange(nullptr); + } + emit requireRefreshPreview(); }); // connect(this, &QTreeWidget::itemDoubleClicked, this, &LayerTreeWidget::onItemDoubleClicked); } diff --git a/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.h b/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.h index ca784fd..e7472dd 100644 --- a/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.h +++ b/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.h @@ -20,7 +20,7 @@ class LayerTreeWidget : public QTreeWidget // void mouseDoubleClickEvent(QMouseEvent *event) override; // void onItemDoubleClicked(QTreeWidgetItem *item, int column = 0); - signals: +signals: void displayLayerChange(LayerWrapper *); void requireRefreshPreview(); void requireRefreshElementWidget();