抽离场景打开逻辑、添加编辑界面的左右拖动功能
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
#include "PicSceneLoader.h"
|
||||
#include "picscene.h"
|
||||
#include "pictextitem.h"
|
||||
#include "PicImageItem.h"
|
||||
#include "PicDateItem.h"
|
||||
#include "PicScheduleShiftItem.h"
|
||||
#include "piccodeitem.h"
|
||||
#include "PicCounterItem.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QXmlStreamAttributes>
|
||||
#include <QDebug>
|
||||
#include <QImage>
|
||||
#include <QPainter>
|
||||
#include <QScopedPointer>
|
||||
#include <cmath>
|
||||
|
||||
namespace {
|
||||
|
||||
PicTextItem* createSceneItem(SourceType sourceType)
|
||||
{
|
||||
switch (sourceType) {
|
||||
case IMAGE:
|
||||
return new PicImageItem();
|
||||
case DATETIME:
|
||||
return new PicDateItem();
|
||||
case SCHEDULE_SHIFT:
|
||||
return new PicScheduleShiftItem();
|
||||
case CODE:
|
||||
return new PicCodeItem();
|
||||
case COUNTER:
|
||||
return new PicCounterItem();
|
||||
case TEXT:
|
||||
case UNKNOWN:
|
||||
default:
|
||||
return new PicTextItem(nullptr, nullptr, sourceType);
|
||||
}
|
||||
}
|
||||
|
||||
SourceType sourceTypeFromAttrs(const QXmlStreamAttributes& attrs)
|
||||
{
|
||||
if (!attrs.hasAttribute("sourceType")) {
|
||||
return SourceType::UNKNOWN;
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
int value = attrs.value("sourceType").toInt(&ok);
|
||||
if (!ok) {
|
||||
return SourceType::UNKNOWN;
|
||||
}
|
||||
|
||||
if (value < SourceType::UNKNOWN || value > SourceType::COUNTER) {
|
||||
return SourceType::UNKNOWN;
|
||||
}
|
||||
|
||||
return static_cast<SourceType>(value);
|
||||
}
|
||||
|
||||
bool parseVbFileElement(QXmlStreamReader& reader, PicScene* scene)
|
||||
{
|
||||
float posX = 0.0f;
|
||||
float posY = 0.0f;
|
||||
bool condition = false;
|
||||
int catchStartValue = -1;
|
||||
int catchValue = -1;
|
||||
QXmlStreamAttributes itemAttrs;
|
||||
QString htmlCData;
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
QXmlStreamReader::TokenType token = reader.readNext();
|
||||
if (token == QXmlStreamReader::StartElement) {
|
||||
const QString elementName = reader.name().toString();
|
||||
if (elementName == "pointer_x") {
|
||||
posX = reader.readElementText().toDouble();
|
||||
} else if (elementName == "pointer_y") {
|
||||
posY = reader.readElementText().toDouble();
|
||||
} else if (elementName == "Condition") {
|
||||
condition = reader.readElementText().toInt() != 0;
|
||||
} else if (elementName == "CatchStartValue") {
|
||||
catchStartValue = reader.readElementText().toInt();
|
||||
} else if (elementName == "CatchValue") {
|
||||
catchValue = reader.readElementText().toInt();
|
||||
} else if (elementName == "itemAttrs") {
|
||||
itemAttrs = reader.attributes();
|
||||
reader.skipCurrentElement();
|
||||
} else if (elementName == "html_src") {
|
||||
reader.skipCurrentElement();
|
||||
} else {
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
} else if (reader.isCDATA()) {
|
||||
htmlCData += reader.text().toString();
|
||||
} else if (token == QXmlStreamReader::EndElement && reader.name() == "VBfile") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SourceType sourceType = sourceTypeFromAttrs(itemAttrs);
|
||||
PicTextItem* item = createSceneItem(sourceType);
|
||||
if (!item) {
|
||||
qWarning() << "PicSceneLoader: skip invalid VBfile item";
|
||||
return true;
|
||||
}
|
||||
|
||||
item->setAttrs(itemAttrs);
|
||||
item->setPos(posX, posY);
|
||||
item->SpecialConditions = condition;
|
||||
item->CatchCnt1StartValue = catchStartValue;
|
||||
item->CatchCnt1CurrValue = catchValue;
|
||||
|
||||
if (!htmlCData.isEmpty()) {
|
||||
item->setHtml(htmlCData);
|
||||
}
|
||||
|
||||
scene->addItem(item);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace PicSceneLoader {
|
||||
|
||||
PicScene* createSceneFromFile(const QString& xmlFilename)
|
||||
{
|
||||
QFile file(xmlFilename);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
qWarning() << "PicSceneLoader: failed to open" << xmlFilename << file.errorString();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QXmlStreamReader reader(&file);
|
||||
PicScene* scene = new PicScene();
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNext();
|
||||
if (reader.isStartElement() && reader.name() == "VBfiles") {
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == "VBfile") {
|
||||
if (!parseVbFileElement(reader, scene)) {
|
||||
delete scene;
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reader.hasError()) {
|
||||
qWarning() << "PicSceneLoader: XML parse error" << reader.errorString()
|
||||
<< "at" << reader.lineNumber() << ":" << reader.columnNumber();
|
||||
delete scene;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
QImage previewSceneFromFile(const QString &xmlFilename)
|
||||
{
|
||||
QScopedPointer<PicScene> scene(createSceneFromFile(xmlFilename));
|
||||
if (!scene) {
|
||||
return QImage();
|
||||
}
|
||||
|
||||
QRectF contentRect = scene->itemsBoundingRect();
|
||||
if (!contentRect.isValid() || contentRect.isEmpty()) {
|
||||
return QImage(1, 1, QImage::Format_ARGB32_Premultiplied);
|
||||
}
|
||||
|
||||
QSize imageSize(qMax<int>(1, int(std::ceil(contentRect.width()))),
|
||||
qMax<int>(1, int(std::ceil(contentRect.height()))));
|
||||
QImage image(imageSize, QImage::Format_ARGB32_Premultiplied);
|
||||
image.fill(Qt::transparent);
|
||||
|
||||
QPainter painter(&image);
|
||||
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||
painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
|
||||
|
||||
scene->render(&painter, QRectF(QPointF(0, 0), imageSize), contentRect);
|
||||
painter.end();
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
} // namespace PicSceneLoader
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef PICSCENELOADER_H
|
||||
#define PICSCENELOADER_H
|
||||
|
||||
#include <QImage>
|
||||
#include <QString>
|
||||
|
||||
class PicScene;
|
||||
|
||||
namespace PicSceneLoader {
|
||||
|
||||
PicScene* createSceneFromFile(const QString& xmlFilename);
|
||||
|
||||
QImage previewSceneFromFile(const QString& xmlFilename);
|
||||
|
||||
} // namespace PicSceneLoader
|
||||
|
||||
#endif // PICSCENELOADER_H
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "myview.h"
|
||||
#include <QWheelEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QScrollBar>
|
||||
#include "picscene.h"
|
||||
#include <QDebug>
|
||||
MyView::MyView(QWidget *parent) :
|
||||
@@ -44,6 +46,63 @@ void MyView::ZoomIn(void)
|
||||
//// rotate(90); //视图旋转顺时针90度
|
||||
//}
|
||||
|
||||
void MyView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
m_isPressing = true;
|
||||
const QPointF scenePos = mapToScene(event->pos());
|
||||
const bool hasSelectedItem = scene() && !scene()->selectedItems().isEmpty();
|
||||
m_pressOnItem = hasSelectedItem || (scene() && scene()->itemAt(scenePos, transform()) != nullptr);
|
||||
m_lastPanPoint = event->pos();
|
||||
}
|
||||
|
||||
QGraphicsView::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void MyView::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (m_isPressing && !m_pressOnItem && !m_isPanning) {
|
||||
const bool noSelectedItems = scene() && scene()->selectedItems().isEmpty();
|
||||
if (noSelectedItems) {
|
||||
QPoint delta = event->pos() - m_lastPanPoint;
|
||||
if (std::abs(delta.x()) >= MyView::PanStartDistance && std::abs(delta.x()) > std::abs(delta.y())) {
|
||||
m_isPanning = true;
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_isPanning) {
|
||||
int deltaX = event->pos().x() - m_lastPanPoint.x();
|
||||
if (deltaX != 0) {
|
||||
horizontalScrollBar()->setValue(horizontalScrollBar()->value() - deltaX);
|
||||
m_lastPanPoint = event->pos();
|
||||
}
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
QGraphicsView::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void MyView::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (m_isPanning && event->button() == Qt::LeftButton) {
|
||||
m_isPanning = false;
|
||||
m_isPressing = false;
|
||||
setCursor(Qt::ArrowCursor);
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
m_isPressing = false;
|
||||
m_pressOnItem = false;
|
||||
}
|
||||
|
||||
QGraphicsView::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void MyView::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
//event->accept();
|
||||
|
||||
+9
-3
@@ -14,15 +14,21 @@ public:
|
||||
//char getzoomRatio(){return zoomRatio;}
|
||||
private:
|
||||
char zoomRatio;
|
||||
bool m_isPanning = false;
|
||||
bool m_isPressing = false;
|
||||
bool m_pressOnItem = false;
|
||||
QPoint m_lastPanPoint;
|
||||
static constexpr int PanStartDistance = 8;
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
protected :
|
||||
// void wheelEvent(QWheelEvent *event);
|
||||
// void mousePressEvent(QMouseEvent *event);
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user