图元预览改为懒加载;添加帧缓存;修改图元预览渲染机制;固定渲染倍率*
parent
7e0e07292f
commit
beee94ebe0
|
@ -84,7 +84,7 @@ void EditorWidget::initFileMenu()
|
|||
auto* item = dynamic_cast<EditorWidgetItem*>(this->tabWidget->currentWidget());
|
||||
if (item != nullptr)
|
||||
{
|
||||
//item->save();
|
||||
item->save();
|
||||
}
|
||||
});
|
||||
connect(actionSaveAs, &QAction::triggered, this, [this] {
|
||||
|
|
|
@ -25,9 +25,9 @@ EditorWidgetItem::EditorWidgetItem(QString filePath,QWidget *parent) : QWidget(p
|
|||
qDebug() << elementInfoDisplayWidget;
|
||||
auto centralRefresh = [this]() {
|
||||
layerInfoDisplayWidget->refresh();
|
||||
elementInfoDisplayWidget->refresh();
|
||||
treeWidget->refresh();
|
||||
previewWindow->refresh();
|
||||
elementInfoDisplayWidget->lazyRefresh();
|
||||
};
|
||||
connect(previewWindow, &PreviewWindow::triggerCentralRefresh, centralRefresh);
|
||||
connect(layerInfoDisplayWidget, &InfoDisplayWidget::triggerCentralRefresh, centralRefresh);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <QFileDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QMessagebox>
|
||||
#include <QTimer>
|
||||
|
||||
ElementPoolWidget::ElementPoolWidget(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
|
@ -38,10 +39,15 @@ void ElementPoolWidget::setElementList(std::vector<GraphicElement*> elements) {
|
|||
pictureList->clear();
|
||||
this->elements = elements;
|
||||
for (int index = 0; index < elements.size(); index++) {
|
||||
QListWidgetItem* pItem = new QListWidgetItem(
|
||||
elements[index]->getPreview(QSize(iconWidth - 25, iconHeight - 25)),
|
||||
elements[index]->name);
|
||||
QListWidgetItem* pItem = new QListWidgetItem(elements[index]->name);
|
||||
QPainter* painter = new QPainter();
|
||||
QImage* image = new QImage(QSize(iconWidth - 12, iconHeight - 12), QImage::Format_ARGB32);
|
||||
image->fill(Qt::transparent);
|
||||
pItem->setIcon(QIcon(QPixmap::fromImage(*image)));
|
||||
pItem->setSizeHint(QSize(iconWidth, iconHeight));
|
||||
painter->begin(image);
|
||||
elements[index]->paintPreview(painter);
|
||||
painter->end();
|
||||
pictureList->insertItem(index, pItem);
|
||||
}
|
||||
if(elements.size() > 0)
|
||||
|
@ -66,15 +72,47 @@ void ElementPoolWidget::setElementManager(ElementManager* element)
|
|||
this->setElementList(this->elementManager->elements);
|
||||
}
|
||||
|
||||
void ElementPoolWidget::lazyRefresh()
|
||||
{
|
||||
if (!refreshWait) {
|
||||
refreshWait = true;
|
||||
QTimer::singleShot(1000, this, SLOT(refresh()));
|
||||
}
|
||||
}
|
||||
|
||||
void ElementPoolWidget::refresh() {
|
||||
this->setElementList(this->elementManager->elements);
|
||||
// update();
|
||||
refreshWait = false;
|
||||
if (elementManager != nullptr)
|
||||
{
|
||||
for (int i = 0; i < elements.size(); i++)
|
||||
{
|
||||
QListWidgetItem* pItem = pictureList->item(i);
|
||||
if (pItem == nullptr)
|
||||
{
|
||||
pItem = new QListWidgetItem(elements[i]->name);
|
||||
pictureList->insertItem(i, pItem);
|
||||
}
|
||||
QPainter* painter = new QPainter();
|
||||
QImage* image = new QImage(QSize(iconWidth - 12, iconHeight - 12), QImage::Format_ARGB32);
|
||||
image->fill(Qt::transparent);
|
||||
painter->begin(image);
|
||||
elements[i]->paintPreview(painter);
|
||||
painter->end();
|
||||
pItem->setIcon(QIcon(QPixmap::fromImage(*image)));
|
||||
pItem->setData(Qt::UserRole, QVariant::fromValue(image));
|
||||
pItem->setSizeHint(QSize(iconWidth, iconHeight));
|
||||
pictureList->insertItem(i, pItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ElementPoolWidget::refreshPicture(GraphicElement* element) {
|
||||
for (int i = 0; i < elements.size(); i++) {
|
||||
if (element == elements[i]) {
|
||||
pictureList->item(i)->setIcon(elements[i]->getPreview(QSize(iconWidth - 25, iconHeight - 25)));
|
||||
QPainter* painter = new QPainter();
|
||||
painter->begin(pictureList->item(i)->data(Qt::UserRole).value<QImage*>());
|
||||
elements[i]->paintPreview(painter);
|
||||
painter->end();
|
||||
// update();
|
||||
return;
|
||||
}
|
||||
|
@ -84,7 +122,10 @@ void ElementPoolWidget::refreshPicture(GraphicElement* element) {
|
|||
void ElementPoolWidget::refreshPictureByIndex(int index) {
|
||||
if (index >= 0 && index < elements.size())
|
||||
{
|
||||
pictureList->item(index)->setIcon(elements[index]->getPreview(QSize(iconWidth - 25, iconHeight - 25)));
|
||||
QPainter* painter = new QPainter();
|
||||
painter->begin(pictureList->item(index)->data(Qt::UserRole).value<QImage*>());
|
||||
elements[index]->paintPreview(painter);
|
||||
painter->end();
|
||||
// update();
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +159,6 @@ void ElementPoolWidget::popMenu(const QPoint& pos)
|
|||
});
|
||||
menu->addAction(QString::fromLocal8Bit("ɾ³ý"), this, [this, currentElement]() {
|
||||
this->elementManager->removeElement(currentElement);
|
||||
emit triggerCentralRefresh();
|
||||
});
|
||||
menu->actions().last()->setDisabled(currentElement->referencedCount > 0);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ private:
|
|||
QListWidget* pictureList;
|
||||
int iconWidth, iconHeight;
|
||||
ElementManager* elementManager;
|
||||
bool refreshWait = false;
|
||||
|
||||
public:
|
||||
int currentIndex = -1;
|
||||
|
@ -22,6 +23,7 @@ public:
|
|||
void setElementManager(ElementManager* element);
|
||||
~ElementPoolWidget();
|
||||
void enableEdit();
|
||||
void lazyRefresh();
|
||||
|
||||
signals:
|
||||
void elementSelected(GraphicElement* element);
|
||||
|
|
|
@ -45,7 +45,6 @@ void GroupElement::setSourceLayer(FolderLayerWrapper* sourceLayer)
|
|||
PixelPath GroupElement::getPaintObject() const
|
||||
{
|
||||
if (sourceLayer != nullptr) {
|
||||
sourceLayer->refresh();
|
||||
return sourceLayer->getCache();
|
||||
}
|
||||
else
|
||||
|
@ -113,8 +112,9 @@ void SimpleElement::paint(QPainter* painter, QTransform transform, const LayerSt
|
|||
maxScale = std::max(fabs(transform.m11() / cos(angle)), fabs(transform.m22() / cos(angle)));
|
||||
else
|
||||
maxScale = std::max(fabs(transform.m12() / sin(angle)), fabs(transform.m21() / sin(angle)));
|
||||
double pixelRatio = maxScale * QGuiApplication::primaryScreen()->devicePixelRatio();
|
||||
if (painterPath == painterPathPrev && styles.getHash() == stylesHashValue && pixelRatio == pixelRatioPrev)
|
||||
//double pixelRatio = maxScale * QGuiApplication::primaryScreen()->devicePixelRatio();
|
||||
double pixelRatio = 5;
|
||||
if (painterPath == painterPathPrev && styles.getHash() == stylesHashValue && fabs(pixelRatio - pixelRatioPrev) < 1e-3)
|
||||
{
|
||||
transform.translate(movPrev.x(), movPrev.y());
|
||||
painter->setTransform(transform.scale(1 / pixelRatio, 1 / pixelRatio));
|
||||
|
@ -153,31 +153,26 @@ bool GroupElement::isClosed() const
|
|||
}
|
||||
|
||||
|
||||
QPixmap SimpleElement::getPreview(QSize size)
|
||||
void SimpleElement::paintPreview(QPainter* painter)
|
||||
{
|
||||
QPixmap result(size + QSize(5, 5));
|
||||
QPainter painter(&result);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
painter.scale(size.width() / painterPath.boundingRect().width(), size.height() / painterPath.boundingRect().height());
|
||||
painter.drawPath(painterPath);
|
||||
return result;
|
||||
painter->save();
|
||||
painter->setWindow(painterPath.boundingRect().x() - 5, painterPath.boundingRect().y() - 5, (painterPath.boundingRect().width() + 10) * QGuiApplication::primaryScreen()->devicePixelRatio(), (painterPath.boundingRect().height() + 10) * QGuiApplication::primaryScreen()->devicePixelRatio());
|
||||
painter->drawPath(painterPath);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
QPixmap GroupElement::getPreview(QSize size)
|
||||
void GroupElement::paintPreview(QPainter* painter)
|
||||
{
|
||||
painter->save();
|
||||
auto cache = sourceLayer->getCache();
|
||||
QPixmap result(QSize(1024, 1024));
|
||||
QPainter painter(&result);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
sourceLayer->paint(&painter, QTransform(), true);
|
||||
painter.end();
|
||||
QRect rect(cache.getBoundingRect().toRect());
|
||||
rect.setTopLeft(rect.topLeft() - QPoint(5, 5));
|
||||
rect.setBottomRight(rect.bottomRight() + QPoint(5, 5));
|
||||
result = result.copy(rect);
|
||||
return result.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||
painter->setRenderHint(QPainter::SmoothPixmapTransform, true);
|
||||
painter->setWindow(cache.getBoundingRect().toRect().x() - 5, cache.getBoundingRect().toRect().y() - 5, (cache.getBoundingRect().toRect().width() + 10) * QGuiApplication::primaryScreen()->devicePixelRatio(), (cache.getBoundingRect().toRect().height() + 10) * QGuiApplication::primaryScreen()->devicePixelRatio());
|
||||
//painter->translate(-cache.getBoundingRect().toRect().x() - 5, -cache.getBoundingRect().toRect().y() - 5);
|
||||
//double maxScale = std::max(cache.getBoundingRect().toRect().width() + 10, cache.getBoundingRect().toRect().height() + 10) * QGuiApplication::primaryScreen()->devicePixelRatio();
|
||||
//painter->scale(1 / maxScale, 1/ maxScale);
|
||||
sourceLayer->paint(painter, QTransform(), true);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void GroupElement::collectReachable(std::set<LayerWrapper*>& set) const
|
||||
|
|
|
@ -20,6 +20,7 @@ class ComposedPainterPath;
|
|||
class GraphicElement
|
||||
{
|
||||
public:
|
||||
bool needRefresh = true;
|
||||
size_t referencedCount = 0;
|
||||
Renderer::ElementRenderer *renderer;
|
||||
QString name = "";
|
||||
|
@ -35,7 +36,7 @@ public:
|
|||
virtual PixelPath getPaintObject(const LayerStyleContainer& styles) const = 0;
|
||||
virtual void paint(QPainter* painter, QTransform transform, const LayerStyleContainer& styles) = 0;
|
||||
virtual bool isClosed() const = 0;
|
||||
virtual QPixmap getPreview(QSize size) = 0;
|
||||
virtual void paintPreview(QPainter* painter) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
@ -59,7 +60,7 @@ public:
|
|||
PixelPath getPaintObject(const LayerStyleContainer& styles) const override;
|
||||
void paint(QPainter* painter, QTransform transform, const LayerStyleContainer& styles) override;
|
||||
bool isClosed() const override;
|
||||
QPixmap getPreview(QSize size) override;
|
||||
void paintPreview(QPainter* painter) override;
|
||||
};
|
||||
|
||||
class GroupElement : public GraphicElement
|
||||
|
@ -77,10 +78,12 @@ public:
|
|||
void setSourceLayer(FolderLayerWrapper* sourceLayer);
|
||||
void paint(QPainter* painter, QTransform transform, const LayerStyleContainer& styles) override;
|
||||
bool isClosed() const override;
|
||||
QPixmap getPreview(QSize size) override;
|
||||
void paintPreview(QPainter* painter) override;
|
||||
void collectReachable(std::set<LayerWrapper*>& set) const;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(GraphicElement*)
|
||||
|
||||
//******************************** BitmapPath ********************************//
|
||||
|
||||
//using std::vector;
|
||||
|
|
|
@ -14,6 +14,7 @@ LayerWrapper *LayerManager::getRoot() const
|
|||
void LayerManager::paint(QPainter *painter, QSize size,LayerWrapper* selecetedLayer) const
|
||||
{
|
||||
painter->save();
|
||||
root->markNeedRefresh();
|
||||
root->getCache();
|
||||
root->paint(painter);
|
||||
painter->restore();
|
||||
|
|
|
@ -25,10 +25,10 @@ FolderLayerWrapper*LayerWrapper::getParent() const
|
|||
|
||||
PixelPath LayerWrapper::getCache(LayerWrapper* selectedLayer)
|
||||
{
|
||||
this->refresh(selectedLayer);
|
||||
if (selectedLayer == this)
|
||||
if (needRefresh)
|
||||
{
|
||||
this->cache.highLight();
|
||||
this->refresh(selectedLayer);
|
||||
needRefresh = false;
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
@ -461,3 +461,15 @@ void LayerWrapper::paintVisualBounding(QPainter* painter) const
|
|||
painter->drawRect(cache.getBoundingRect());
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void LayerWrapper::markNeedRefresh()
|
||||
{
|
||||
this->needRefresh = true;
|
||||
}
|
||||
|
||||
void FolderLayerWrapper::markNeedRefresh()
|
||||
{
|
||||
LayerWrapper::markNeedRefresh();
|
||||
for (auto& child : children)
|
||||
child->markNeedRefresh();
|
||||
}
|
|
@ -35,6 +35,7 @@ class LayerWrapper
|
|||
PixelPath cache;
|
||||
|
||||
public:
|
||||
bool needRefresh = true;
|
||||
QTreeWidgetItem* qTreeWidgetItem;
|
||||
bool selected;
|
||||
bool hidden;
|
||||
|
@ -77,6 +78,7 @@ class LayerWrapper
|
|||
virtual bool referencingGroupElement() const;
|
||||
virtual void paintVisualBounding(QPainter* painter) const;
|
||||
bool canApplyStyles() const;
|
||||
virtual void markNeedRefresh();
|
||||
};
|
||||
|
||||
class FolderLayerWrapper : public LayerWrapper
|
||||
|
@ -104,6 +106,7 @@ class FolderLayerWrapper : public LayerWrapper
|
|||
void refreshTreeItem() override;
|
||||
size_t referencedCount(bool excludeSelf = false) const override;
|
||||
bool deleteable(bool excludeSubTree = false) const override;
|
||||
void markNeedRefresh() override;
|
||||
};
|
||||
|
||||
class LeafLayerWrapper : public LayerWrapper
|
||||
|
|
|
@ -21,37 +21,51 @@ InfoDisplayWidget::InfoDisplayWidget(QWidget* parent) :QWidget(parent)
|
|||
ui.rotation->setLabel(("旋转角度"));
|
||||
ui.scaleX->setLabel(("水平缩放"));
|
||||
ui.scaleY->setLabel(("垂直缩放"));
|
||||
ui.rotation->setValidator(new QIntValidator(-10000, 10000, this));
|
||||
ui.rotation->setValidator(new QDoubleValidator(-10000, 10000, 6, this));
|
||||
ui.styleList->setDisabled(true);
|
||||
connect(ui.rotation, &QLineEdit::textChanged, [=](QString content) {
|
||||
if (fabs(content.toDouble() - this->displayLayer->property.rotation) < 1e-6)
|
||||
return;
|
||||
this->displayLayer->property.rotation = content.toDouble();
|
||||
emit triggerCentralRefresh();
|
||||
});
|
||||
ui.offsetX->setValidator(new QIntValidator(-10000, 10000, this));
|
||||
ui.offsetX->setValidator(new QDoubleValidator(-10000, 10000, 2, this));
|
||||
connect(ui.offsetX, &QLineEdit::textChanged, [=](QString content) {
|
||||
if (fabs(content.toDouble() - this->displayLayer->property.offset.x()) < 1e-6)
|
||||
return;
|
||||
this->displayLayer->property.offset = { content.toDouble(), this->displayLayer->property.offset.y() };
|
||||
emit triggerCentralRefresh();
|
||||
});
|
||||
ui.offsetY->setValidator(new QIntValidator(-10000, 10000, this));
|
||||
ui.offsetY->setValidator(new QDoubleValidator(-10000, 10000, 2, this));
|
||||
connect(ui.offsetY, &QLineEdit::textChanged, [=](QString content) {
|
||||
if (fabs(content.toDouble() - this->displayLayer->property.offset.y()) < 1e-6)
|
||||
return;
|
||||
this->displayLayer->property.offset = { this->displayLayer->property.offset.x(), content.toDouble() };
|
||||
emit triggerCentralRefresh();
|
||||
});
|
||||
ui.scaleX->setValidator(new QDoubleValidator(0, 1000, 4, this));
|
||||
ui.scaleX->setValidator(new QDoubleValidator(0, 10000, 6, this));
|
||||
connect(ui.scaleX, &QLineEdit::textChanged, [=](QString content) {
|
||||
if (fabs(content.toDouble() - this->displayLayer->property.scale.x()) < 1e-6)
|
||||
return;
|
||||
this->displayLayer->property.scale = { content.toDouble(), this->displayLayer->property.scale.y() };
|
||||
emit triggerCentralRefresh();
|
||||
});
|
||||
ui.scaleY->setValidator(new QDoubleValidator(0, 1000, 4, this));
|
||||
ui.scaleY->setValidator(new QDoubleValidator(0, 10000, 6, this));
|
||||
connect(ui.scaleY, &QLineEdit::textChanged, [=](QString content) {
|
||||
if (fabs(content.toDouble() - this->displayLayer->property.scale.y()) < 1e-6)
|
||||
return;
|
||||
this->displayLayer->property.scale = { this->displayLayer->property.scale.x(), content.toDouble() };
|
||||
emit triggerCentralRefresh();
|
||||
});
|
||||
connect(ui.flipX, &QtMaterialCheckBox::toggled, [=](bool state) {
|
||||
if (state == this->displayLayer->property.flipX)
|
||||
return;
|
||||
this->displayLayer->property.flipX = state;
|
||||
emit triggerCentralRefresh();
|
||||
});
|
||||
connect(ui.flipY, &QtMaterialCheckBox::toggled, [=](bool state) {
|
||||
if (state == this->displayLayer->property.flipY)
|
||||
return;
|
||||
this->displayLayer->property.flipY = state;
|
||||
emit triggerCentralRefresh();
|
||||
});
|
||||
|
|
|
@ -239,6 +239,7 @@ QAction* LayerTreeWidget::getPromoteUpAction()
|
|||
auto layer = pair.first;
|
||||
auto parent = pair.second;
|
||||
this->moveLayer(layer, parent);
|
||||
this->setCurrentItem(layer->qTreeWidgetItem);
|
||||
});
|
||||
optionList.append(option);
|
||||
}
|
||||
|
@ -255,6 +256,11 @@ QAction* LayerTreeWidget::getPromoteDownAction()
|
|||
std::vector<FolderLayerWrapper*> layers;
|
||||
auto layer = this->selectedItem->data(0, Qt::UserRole).value<LayerWrapper*>();
|
||||
auto parent = layer->getParent();
|
||||
if (parent == nullptr)
|
||||
{
|
||||
action->setEnabled(false);
|
||||
return action;
|
||||
}
|
||||
for (auto child : parent->children)
|
||||
{
|
||||
if (child.get() == layer || typeid(*child) != typeid(FolderLayerWrapper))
|
||||
|
@ -278,6 +284,7 @@ QAction* LayerTreeWidget::getPromoteDownAction()
|
|||
auto layer = pair.first;
|
||||
auto parent = pair.second;
|
||||
this->moveLayer(layer, parent);
|
||||
this->setCurrentItem(layer->qTreeWidgetItem);
|
||||
});
|
||||
optionList.append(option);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue