Add silhouette image generator
parent
86e2075142
commit
52252b70af
|
@ -538,6 +538,9 @@ HEADERS += src/motionbuilder.h
|
||||||
SOURCES += src/statusbarlabel.cpp
|
SOURCES += src/statusbarlabel.cpp
|
||||||
HEADERS += src/statusbarlabel.h
|
HEADERS += src/statusbarlabel.h
|
||||||
|
|
||||||
|
SOURCES += src/silhouetteimagegenerator.cpp
|
||||||
|
HEADERS += src/silhouetteimagegenerator.h
|
||||||
|
|
||||||
SOURCES += src/main.cpp
|
SOURCES += src/main.cpp
|
||||||
|
|
||||||
HEADERS += src/version.h
|
HEADERS += src/version.h
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
#include "objectxml.h"
|
#include "objectxml.h"
|
||||||
#include "rigxml.h"
|
#include "rigxml.h"
|
||||||
#include "statusbarlabel.h"
|
#include "statusbarlabel.h"
|
||||||
|
#include "silhouetteimagegenerator.h"
|
||||||
|
|
||||||
int DocumentWindow::m_autoRecovered = false;
|
int DocumentWindow::m_autoRecovered = false;
|
||||||
|
|
||||||
|
@ -80,6 +81,22 @@ const std::map<DocumentWindow *, QUuid> &DocumentWindow::documentWindows()
|
||||||
return g_documentWindows;
|
return g_documentWindows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DocumentWindow::GraphicsViewEditTarget DocumentWindow::graphicsViewEditTarget()
|
||||||
|
{
|
||||||
|
return m_graphicsViewEditTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DocumentWindow::updateGraphicsViewEditTarget(GraphicsViewEditTarget target)
|
||||||
|
{
|
||||||
|
if (m_graphicsViewEditTarget == target)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_graphicsViewEditTarget = target;
|
||||||
|
if (GraphicsViewEditTarget::Bone == m_graphicsViewEditTarget)
|
||||||
|
generateSilhouetteImage();
|
||||||
|
emit graphicsViewEditTargetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
Document *DocumentWindow::document()
|
Document *DocumentWindow::document()
|
||||||
{
|
{
|
||||||
return m_document;
|
return m_document;
|
||||||
|
@ -520,12 +537,12 @@ DocumentWindow::DocumentWindow() :
|
||||||
connect(boneLabel, &StatusBarLabel::clicked, this, [=]() {
|
connect(boneLabel, &StatusBarLabel::clicked, this, [=]() {
|
||||||
boneLabel->setSelected(true);
|
boneLabel->setSelected(true);
|
||||||
shapeLabel->setSelected(false);
|
shapeLabel->setSelected(false);
|
||||||
// TODO:
|
updateGraphicsViewEditTarget(GraphicsViewEditTarget::Bone);
|
||||||
});
|
});
|
||||||
connect(shapeLabel, &StatusBarLabel::clicked, this, [=]() {
|
connect(shapeLabel, &StatusBarLabel::clicked, this, [=]() {
|
||||||
shapeLabel->setSelected(true);
|
shapeLabel->setSelected(true);
|
||||||
boneLabel->setSelected(false);
|
boneLabel->setSelected(false);
|
||||||
// TODO:
|
updateGraphicsViewEditTarget(GraphicsViewEditTarget::Shape);
|
||||||
});
|
});
|
||||||
|
|
||||||
/////////////////////// Status Bar End ////////////////////////////
|
/////////////////////// Status Bar End ////////////////////////////
|
||||||
|
@ -1354,6 +1371,9 @@ DocumentWindow::DocumentWindow() :
|
||||||
connect(m_document, &Document::scriptChanged, m_document, &Document::runScript);
|
connect(m_document, &Document::scriptChanged, m_document, &Document::runScript);
|
||||||
connect(m_document, &Document::scriptModifiedFromExternal, m_document, &Document::runScript);
|
connect(m_document, &Document::scriptModifiedFromExternal, m_document, &Document::runScript);
|
||||||
|
|
||||||
|
connect(m_document, &Document::skeletonChanged, this, &DocumentWindow::generateSilhouetteImage);
|
||||||
|
connect(m_graphicsWidget, &SkeletonGraphicsWidget::loadedTurnaroundImageChanged, this, &DocumentWindow::generateSilhouetteImage);
|
||||||
|
|
||||||
initShortCuts(this, m_graphicsWidget);
|
initShortCuts(this, m_graphicsWidget);
|
||||||
|
|
||||||
connect(this, &DocumentWindow::initialized, m_document, &Document::uiReady);
|
connect(this, &DocumentWindow::initialized, m_document, &Document::uiReady);
|
||||||
|
@ -2634,3 +2654,47 @@ ModelWidget *DocumentWindow::modelWidget()
|
||||||
{
|
{
|
||||||
return m_modelRenderWidget;
|
return m_modelRenderWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DocumentWindow::generateSilhouetteImage()
|
||||||
|
{
|
||||||
|
if (GraphicsViewEditTarget::Bone != m_graphicsViewEditTarget ||
|
||||||
|
nullptr != m_silhouetteImageGenerator) {
|
||||||
|
m_isSilhouetteImageObsolete = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_isSilhouetteImageObsolete = false;
|
||||||
|
|
||||||
|
const QImage *loadedTurnaroundImage = m_graphicsWidget->loadedTurnaroundImage();
|
||||||
|
if (nullptr == loadedTurnaroundImage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QThread *thread = new QThread;
|
||||||
|
|
||||||
|
Snapshot *snapshot = new Snapshot;
|
||||||
|
m_document->toSnapshot(snapshot);
|
||||||
|
|
||||||
|
m_silhouetteImageGenerator = new SilhouetteImageGenerator(loadedTurnaroundImage->width(),
|
||||||
|
loadedTurnaroundImage->height(), snapshot);
|
||||||
|
m_silhouetteImageGenerator->moveToThread(thread);
|
||||||
|
connect(thread, &QThread::started, m_silhouetteImageGenerator, &SilhouetteImageGenerator::process);
|
||||||
|
connect(m_silhouetteImageGenerator, &SilhouetteImageGenerator::finished, this, &DocumentWindow::silhouetteImageReady);
|
||||||
|
connect(m_silhouetteImageGenerator, &SilhouetteImageGenerator::finished, thread, &QThread::quit);
|
||||||
|
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
||||||
|
thread->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DocumentWindow::silhouetteImageReady()
|
||||||
|
{
|
||||||
|
QImage *image = m_silhouetteImageGenerator->takeResultImage();
|
||||||
|
if (nullptr != image)
|
||||||
|
image->save("test.png");
|
||||||
|
delete image;
|
||||||
|
|
||||||
|
delete m_silhouetteImageGenerator;
|
||||||
|
m_silhouetteImageGenerator = nullptr;
|
||||||
|
|
||||||
|
if (m_isSilhouetteImageObsolete)
|
||||||
|
generateSilhouetteImage();
|
||||||
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
class SkeletonGraphicsWidget;
|
class SkeletonGraphicsWidget;
|
||||||
class PartTreeWidget;
|
class PartTreeWidget;
|
||||||
class SpinnableAwesomeButton;
|
class SpinnableAwesomeButton;
|
||||||
|
class SilhouetteImageGenerator;
|
||||||
|
|
||||||
class DocumentWindow : public QMainWindow
|
class DocumentWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
|
@ -33,11 +34,19 @@ signals:
|
||||||
void uninialized();
|
void uninialized();
|
||||||
void waitingExportFinished(const QString &filename, bool isSuccessful);
|
void waitingExportFinished(const QString &filename, bool isSuccessful);
|
||||||
void mouseTargetVertexPositionChanged(const QVector3D &position);
|
void mouseTargetVertexPositionChanged(const QVector3D &position);
|
||||||
|
void graphicsViewEditTargetChanged();
|
||||||
public:
|
public:
|
||||||
|
enum class GraphicsViewEditTarget
|
||||||
|
{
|
||||||
|
Shape,
|
||||||
|
Bone
|
||||||
|
};
|
||||||
|
|
||||||
DocumentWindow();
|
DocumentWindow();
|
||||||
~DocumentWindow();
|
~DocumentWindow();
|
||||||
Document *document();
|
Document *document();
|
||||||
ModelWidget *modelWidget();
|
ModelWidget *modelWidget();
|
||||||
|
GraphicsViewEditTarget graphicsViewEditTarget();
|
||||||
static DocumentWindow *createDocumentWindow();
|
static DocumentWindow *createDocumentWindow();
|
||||||
static const std::map<DocumentWindow *, QUuid> &documentWindows();
|
static const std::map<DocumentWindow *, QUuid> &documentWindows();
|
||||||
static void showAcknowlegements();
|
static void showAcknowlegements();
|
||||||
|
@ -105,6 +114,9 @@ public slots:
|
||||||
void generatePartPreviewImages();
|
void generatePartPreviewImages();
|
||||||
void partPreviewImagesReady();
|
void partPreviewImagesReady();
|
||||||
void updateRegenerateIcon();
|
void updateRegenerateIcon();
|
||||||
|
void updateGraphicsViewEditTarget(GraphicsViewEditTarget target);
|
||||||
|
void generateSilhouetteImage();
|
||||||
|
void silhouetteImageReady();
|
||||||
private:
|
private:
|
||||||
void initLockButton(QPushButton *button);
|
void initLockButton(QPushButton *button);
|
||||||
void setCurrentFilename(const QString &filename);
|
void setCurrentFilename(const QString &filename);
|
||||||
|
@ -242,6 +254,10 @@ private:
|
||||||
SpinnableAwesomeButton *m_regenerateButton = nullptr;
|
SpinnableAwesomeButton *m_regenerateButton = nullptr;
|
||||||
|
|
||||||
QWidget *m_paintWidget = nullptr;
|
QWidget *m_paintWidget = nullptr;
|
||||||
|
|
||||||
|
GraphicsViewEditTarget m_graphicsViewEditTarget = GraphicsViewEditTarget::Shape;
|
||||||
|
bool m_isSilhouetteImageObsolete = false;
|
||||||
|
SilhouetteImageGenerator *m_silhouetteImageGenerator = nullptr;
|
||||||
public:
|
public:
|
||||||
static int m_autoRecovered;
|
static int m_autoRecovered;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QBrush>
|
||||||
|
#include "silhouetteimagegenerator.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
SilhouetteImageGenerator::SilhouetteImageGenerator(int width, int height, Snapshot *snapshot) :
|
||||||
|
m_width(width),
|
||||||
|
m_height(height),
|
||||||
|
m_snapshot(snapshot)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SilhouetteImageGenerator::~SilhouetteImageGenerator()
|
||||||
|
{
|
||||||
|
delete m_snapshot;
|
||||||
|
delete m_resultImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage *SilhouetteImageGenerator::takeResultImage()
|
||||||
|
{
|
||||||
|
QImage *resultImage = m_resultImage;
|
||||||
|
m_resultImage = nullptr;
|
||||||
|
return resultImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SilhouetteImageGenerator::generate()
|
||||||
|
{
|
||||||
|
if (m_width <= 0 || m_height <= 0 || nullptr == m_snapshot)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//float originX = valueOfKeyInMapOrEmpty(m_snapshot->canvas, "originX").toFloat();
|
||||||
|
//float originY = valueOfKeyInMapOrEmpty(m_snapshot->canvas, "originY").toFloat();
|
||||||
|
//float originZ = valueOfKeyInMapOrEmpty(m_snapshot->canvas, "originZ").toFloat();
|
||||||
|
|
||||||
|
delete m_resultImage;
|
||||||
|
m_resultImage = new QImage(m_width, m_height, QImage::Format_ARGB32);
|
||||||
|
m_resultImage->fill(QColor(0xE1, 0xD2, 0xBD));
|
||||||
|
|
||||||
|
struct NodeInfo
|
||||||
|
{
|
||||||
|
QVector3D position;
|
||||||
|
float radius;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<QString, NodeInfo> nodePositionMap;
|
||||||
|
for (const auto &node: m_snapshot->nodes) {
|
||||||
|
NodeInfo nodeInfo;
|
||||||
|
nodeInfo.position = QVector3D(valueOfKeyInMapOrEmpty(node.second, "x").toFloat(),
|
||||||
|
valueOfKeyInMapOrEmpty(node.second, "y").toFloat(),
|
||||||
|
valueOfKeyInMapOrEmpty(node.second, "z").toFloat());
|
||||||
|
nodeInfo.radius = valueOfKeyInMapOrEmpty(node.second, "radius").toFloat();
|
||||||
|
nodePositionMap.insert({node.first, nodeInfo});
|
||||||
|
}
|
||||||
|
|
||||||
|
QPainter painter;
|
||||||
|
painter.begin(m_resultImage);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
|
painter.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||||
|
|
||||||
|
painter.setPen(Qt::NoPen);
|
||||||
|
|
||||||
|
QBrush brush;
|
||||||
|
brush.setColor(QColor(0x88, 0x80, 0x73));
|
||||||
|
brush.setStyle(Qt::SolidPattern);
|
||||||
|
|
||||||
|
painter.setBrush(brush);
|
||||||
|
|
||||||
|
for (const auto &it: nodePositionMap) {
|
||||||
|
const auto &nodeInfo = it.second;
|
||||||
|
|
||||||
|
painter.drawEllipse((nodeInfo.position.x() - nodeInfo.radius) * m_height,
|
||||||
|
(nodeInfo.position.y() - nodeInfo.radius) * m_height,
|
||||||
|
nodeInfo.radius * m_height * 2.0,
|
||||||
|
nodeInfo.radius * m_height * 2.0);
|
||||||
|
|
||||||
|
painter.drawEllipse((nodeInfo.position.z() - nodeInfo.radius) * m_height,
|
||||||
|
(nodeInfo.position.y() - nodeInfo.radius) * m_height,
|
||||||
|
nodeInfo.radius * m_height * 2.0,
|
||||||
|
nodeInfo.radius * m_height * 2.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int round = 0; round < 2; ++round) {
|
||||||
|
if (1 == round)
|
||||||
|
painter.setCompositionMode(QPainter::CompositionMode_Multiply);
|
||||||
|
for (const auto &edge: m_snapshot->edges) {
|
||||||
|
QString partId = valueOfKeyInMapOrEmpty(edge.second, "partId");
|
||||||
|
QString fromNodeId = valueOfKeyInMapOrEmpty(edge.second, "from");
|
||||||
|
QString toNodeId = valueOfKeyInMapOrEmpty(edge.second, "to");
|
||||||
|
const auto &fromNodeInfo = nodePositionMap[fromNodeId];
|
||||||
|
const auto &toNodeInfo = nodePositionMap[toNodeId];
|
||||||
|
|
||||||
|
{
|
||||||
|
QVector3D pointerOut = QVector3D(0.0, 0.0, 1.0);
|
||||||
|
QVector3D direction = (QVector3D(toNodeInfo.position.x(), toNodeInfo.position.y(), 0.0) -
|
||||||
|
QVector3D(fromNodeInfo.position.x(), fromNodeInfo.position.y(), 0.0)).normalized();
|
||||||
|
QVector3D fromBaseDirection = QVector3D::crossProduct(pointerOut, direction);
|
||||||
|
QVector3D fromBaseRadius = fromBaseDirection * fromNodeInfo.radius;
|
||||||
|
QVector3D fromBaseFirstPoint = QVector3D(fromNodeInfo.position.x(), fromNodeInfo.position.y(), 0.0) - fromBaseRadius;
|
||||||
|
QVector3D fromBaseSecondPoint = QVector3D(fromNodeInfo.position.x(), fromNodeInfo.position.y(), 0.0) + fromBaseRadius;
|
||||||
|
QVector3D tobaseDirection = -fromBaseDirection;
|
||||||
|
QVector3D toBaseRadius = tobaseDirection * toNodeInfo.radius;
|
||||||
|
QVector3D toBaseFirstPoint = QVector3D(toNodeInfo.position.x(), toNodeInfo.position.y(), 0.0) - toBaseRadius;
|
||||||
|
QVector3D toBaseSecondPoint = QVector3D(toNodeInfo.position.x(), toNodeInfo.position.y(), 0.0) + toBaseRadius;
|
||||||
|
QPolygon polygon;
|
||||||
|
polygon.append(QPoint(fromBaseFirstPoint.x() * m_height, fromBaseFirstPoint.y() * m_height));
|
||||||
|
polygon.append(QPoint(fromBaseSecondPoint.x() * m_height, fromBaseSecondPoint.y() * m_height));
|
||||||
|
polygon.append(QPoint(toBaseFirstPoint.x() * m_height, toBaseFirstPoint.y() * m_height));
|
||||||
|
polygon.append(QPoint(toBaseSecondPoint.x() * m_height, toBaseSecondPoint.y() * m_height));
|
||||||
|
QPainterPath path;
|
||||||
|
path.addPolygon(polygon);
|
||||||
|
painter.fillPath(path, brush);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
QVector3D pointerOut = QVector3D(0.0, 0.0, 1.0);
|
||||||
|
QVector3D direction = (QVector3D(toNodeInfo.position.z(), toNodeInfo.position.y(), 0.0) -
|
||||||
|
QVector3D(fromNodeInfo.position.z(), fromNodeInfo.position.y(), 0.0)).normalized();
|
||||||
|
QVector3D fromBaseDirection = QVector3D::crossProduct(pointerOut, direction);
|
||||||
|
QVector3D fromBaseRadius = fromBaseDirection * fromNodeInfo.radius;
|
||||||
|
QVector3D fromBaseFirstPoint = QVector3D(fromNodeInfo.position.z(), fromNodeInfo.position.y(), 0.0) - fromBaseRadius;
|
||||||
|
QVector3D fromBaseSecondPoint = QVector3D(fromNodeInfo.position.z(), fromNodeInfo.position.y(), 0.0) + fromBaseRadius;
|
||||||
|
QVector3D tobaseDirection = -fromBaseDirection;
|
||||||
|
QVector3D toBaseRadius = tobaseDirection * toNodeInfo.radius;
|
||||||
|
QVector3D toBaseFirstPoint = QVector3D(toNodeInfo.position.z(), toNodeInfo.position.y(), 0.0) - toBaseRadius;
|
||||||
|
QVector3D toBaseSecondPoint = QVector3D(toNodeInfo.position.z(), toNodeInfo.position.y(), 0.0) + toBaseRadius;
|
||||||
|
QPolygon polygon;
|
||||||
|
polygon.append(QPoint(fromBaseFirstPoint.x() * m_height, fromBaseFirstPoint.y() * m_height));
|
||||||
|
polygon.append(QPoint(fromBaseSecondPoint.x() * m_height, fromBaseSecondPoint.y() * m_height));
|
||||||
|
polygon.append(QPoint(toBaseFirstPoint.x() * m_height, toBaseFirstPoint.y() * m_height));
|
||||||
|
polygon.append(QPoint(toBaseSecondPoint.x() * m_height, toBaseSecondPoint.y() * m_height));
|
||||||
|
QPainterPath path;
|
||||||
|
path.addPolygon(polygon);
|
||||||
|
painter.fillPath(path, brush);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
painter.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SilhouetteImageGenerator::process()
|
||||||
|
{
|
||||||
|
generate();
|
||||||
|
|
||||||
|
emit finished();
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef DUST3D_SILHOUETTE_IMAGE_GENERATOR_H
|
||||||
|
#define DUST3D_SILHOUETTE_IMAGE_GENERATOR_H
|
||||||
|
#include <QObject>
|
||||||
|
#include <QImage>
|
||||||
|
#include "snapshot.h"
|
||||||
|
|
||||||
|
class SilhouetteImageGenerator : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
SilhouetteImageGenerator(int width, int height, Snapshot *snapshot);
|
||||||
|
~SilhouetteImageGenerator();
|
||||||
|
QImage *takeResultImage();
|
||||||
|
void generate();
|
||||||
|
signals:
|
||||||
|
void finished();
|
||||||
|
public slots:
|
||||||
|
void process();
|
||||||
|
private:
|
||||||
|
int m_width = 0;
|
||||||
|
int m_height = 0;
|
||||||
|
QImage *m_resultImage = nullptr;
|
||||||
|
Snapshot *m_snapshot = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -760,12 +760,19 @@ void SkeletonGraphicsWidget::turnaroundImageReady()
|
||||||
}
|
}
|
||||||
delete m_turnaroundLoader;
|
delete m_turnaroundLoader;
|
||||||
m_turnaroundLoader = nullptr;
|
m_turnaroundLoader = nullptr;
|
||||||
|
|
||||||
|
emit loadedTurnaroundImageChanged();
|
||||||
|
|
||||||
if (m_turnaroundChanged) {
|
if (m_turnaroundChanged) {
|
||||||
updateTurnaround();
|
updateTurnaround();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QImage *SkeletonGraphicsWidget::loadedTurnaroundImage() const
|
||||||
|
{
|
||||||
|
return m_backgroundImage;
|
||||||
|
}
|
||||||
|
|
||||||
void SkeletonGraphicsWidget::updateCursor()
|
void SkeletonGraphicsWidget::updateCursor()
|
||||||
{
|
{
|
||||||
if (SkeletonDocumentEditMode::Add != m_document->editMode) {
|
if (SkeletonDocumentEditMode::Add != m_document->editMode) {
|
||||||
|
|
|
@ -516,6 +516,7 @@ signals:
|
||||||
void shortcutToggleRotation();
|
void shortcutToggleRotation();
|
||||||
void createGriddedPartsFromNodes(const std::set<QUuid> &nodeIds);
|
void createGriddedPartsFromNodes(const std::set<QUuid> &nodeIds);
|
||||||
void addPartByPolygons(const QPolygonF &mainProfile, const QPolygonF &sideProfile, const QSizeF &canvasSize);
|
void addPartByPolygons(const QPolygonF &mainProfile, const QPolygonF &sideProfile, const QSizeF &canvasSize);
|
||||||
|
void loadedTurnaroundImageChanged();
|
||||||
public:
|
public:
|
||||||
SkeletonGraphicsWidget(const SkeletonDocument *document);
|
SkeletonGraphicsWidget(const SkeletonDocument *document);
|
||||||
std::map<QUuid, std::pair<SkeletonGraphicsNodeItem *, SkeletonGraphicsNodeItem *>> nodeItemMap;
|
std::map<QUuid, std::pair<SkeletonGraphicsNodeItem *, SkeletonGraphicsNodeItem *>> nodeItemMap;
|
||||||
|
@ -547,6 +548,7 @@ public:
|
||||||
void setMainProfileOnly(bool mainProfileOnly);
|
void setMainProfileOnly(bool mainProfileOnly);
|
||||||
bool inputWheelEventFromOtherWidget(QWheelEvent *event);
|
bool inputWheelEventFromOtherWidget(QWheelEvent *event);
|
||||||
bool rotated();
|
bool rotated();
|
||||||
|
const QImage *loadedTurnaroundImage() const;
|
||||||
protected:
|
protected:
|
||||||
void mouseMoveEvent(QMouseEvent *event) override;
|
void mouseMoveEvent(QMouseEvent *event) override;
|
||||||
void wheelEvent(QWheelEvent *event) override;
|
void wheelEvent(QWheelEvent *event) override;
|
||||||
|
|
Loading…
Reference in New Issue