src/ui/canvas.h

Wed, 25 May 2022 20:36:34 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Wed, 25 May 2022 20:36:34 +0300
changeset 199
6988973515d2
parent 198
eb9d900dc79a
child 200
ca23936b455b
permissions
-rw-r--r--

Fix pick() picking from weird places on the screen with high DPI scaling

glReadPixels reads data from the frame buffer, which contains data after
high DPI scaling, so any reads to that need to take this scaling into account

#pragma once
#include <QPainter>
#include <QBrush>
#include <QPen>
#include "gl/partrenderer.h"
#include "gl/gridprogram.h"
#include "gl/axesprogram.h"
#include "gl/vertexprogram.h"

enum EditingMode
{
	SelectMode,
	DrawMode
};

struct DrawState
{
	std::vector<glm::vec3> polygon;
	std::vector<glm::vec3> previewPolygon;
	glm::vec3 previewPoint;
	bool isconcave = false;
	EditingMode mode = SelectMode;
};
class Canvas : public PartRenderer
{
	Q_OBJECT
public:
	using OverpaintCallback = std::function<void(Canvas*, QPainter*)>;
	Canvas(
		Model* model,
		Document* document,
		DocumentManager* documents,
		const ldraw::ColorTable& colorTable,
		QWidget* parent = nullptr);
	void setOverpaintCallback(OverpaintCallback fn);
	void drawWorldPoint(QPainter* painter, const glm::vec3& worldPoint) const;
	void drawWorldPolyline(QPainter* painter, const std::vector<glm::vec3>& points);
	void drawWorldPolygon(QPainter* painter, const std::vector<glm::vec3>& points);
	Winding worldPolygonWinding(const std::vector<glm::vec3>& points) const;
	const std::optional<glm::vec3>& getWorldPosition() const;
	const QSet<ldraw::id_t> selectedObjects() const;
	const glm::mat4& getGridMatrix() const;
	void closeShape();
	glm::vec3 cameraVector() const;
	std::optional<glm::vec3> worldPosition;
	DrawState* drawState = nullptr;
public Q_SLOTS:
	void handleSelectionChange(const QSet<ldraw::id_t>& selectedIds, const QSet<ldraw::id_t>& deselectedIds);
	void rebuildVertices(Document *document);
	void setGridMatrix(const glm::mat4 &newMatrix);
protected:
	void mouseMoveEvent(QMouseEvent* event) override;
	void mousePressEvent(QMouseEvent* event) override;
	void mouseReleaseEvent(QMouseEvent* event) override;
	void initializeGL() override;
	void paintGL() override;
Q_SIGNALS:
	void newStatusText(const QString& newStatusText);
	void mouseClick(QMouseEvent* event);
	void mouseMove(QMouseEvent* event);
private:
	bool isGridPerpendicularToScreen(float threshold) const;
	QVector<QPointF> convertWorldPointsToScreenPoints(const std::vector<glm::vec3>& worldPoints) const;
	Q_SLOT void updateCanvasRenderPreferences();
	void renderAxesLabels(QPainter& painter);
	std::optional<GridProgram> gridProgram;
	std::optional<AxesProgram> axesProgram;
	std::optional<VertexProgram> vertexProgram;
	glm::mat4 gridMatrix;
	geom::Plane gridPlane;
	int totalMouseMove = 0;
	bool isDark = true;
	QSet<ldraw::id_t> selection;
	OverpaintCallback overpaintCallback = nullptr;
	Document* document;
};

void adjustGridToView(Canvas* canvas);

mercurial