src/linetypes/object.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 186
922662adb72a
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 <QPointF>
#include <QString>
#include <QStringView>
#include "main.h"
#include "colors.h"
#include "gl/common.h"
#include "linetypes/propertygenerics.h"

class Model;

namespace ldraw
{
	struct GetPolygonsContext;
	class Object;
	class ColoredObject;
	class Empty;
	class UnhandledProperty;
}

class DocumentManager;

struct ldraw::GetPolygonsContext
{
	::ModelId modelId;
	::DocumentManager* documents;
};

class ldraw::Object
{
public:
	enum class SetPropertyResult
	{
		Success = 0,
		PropertyNotHandled
	};
	/**
	 * @brief Enumerates different object types
	 */
	enum class Type
	{
		Empty,
		Comment,
		MetaCommand,
		ErrorLine,
		SubfileReference,
		EdgeLine,
		ConditionalEdge,
		Triangle,
		Quadrilateral,
		CircularPrimitive,
	};
	friend bool handled(SetPropertyResult result)
	{
		return result == SetPropertyResult::Success;
	}
	class BadPointIndex : public std::exception
	{
	};
	Object();
	Object(const Object&) = delete;
	virtual ~Object();
	const id_t id;
	virtual bool hasColor() const;
	virtual QVariant getProperty(Property id) const;
	template<ldraw::Property property>
	PropertyType<property> getProperty() const;
	template<ldraw::Property property>
	SetPropertyResult setProperty(const PropertyType<property>& value);
	SetPropertyResult setProperty(const PropertyKeyValue& pair);
	virtual QString textRepresentation() const = 0;
	virtual QBrush textRepresentationForeground() const;
	virtual QBrush textRepresentationBackground() const;
	virtual QFont textRepresentationFont() const;
	virtual void getPolygons(std::vector<gl::Polygon>& polygons, GetPolygonsContext* context) const;
	virtual void invert(GetPolygonsContext*) {}
	virtual int numPoints() const { return 0; }
	virtual const glm::vec3& getPoint(int index) const;
	virtual QDataStream& serialize(QDataStream& stream) const;
	virtual QDataStream& deserialize(QDataStream& stream);
	virtual Type typeIdentifier() const = 0;
	virtual QString toLDrawCode() const = 0;
	virtual QString iconName() const;
	virtual QString typeName() const = 0;

protected:
	template<Property property, typename Function>
	void handle(SetPropertyResult* result, const PropertyKeyValue& pair, Function function);
	virtual void setProperty(SetPropertyResult* result, const PropertyKeyValue& pair);
};

/**
 * @brief Tests whether the object is exactly of the specified type
 * @tparam R Type of LDraw line type object to test for
 * @param object Object to test
 * @returns whether the type of the object specified by @c id is the same type as R. Returns false if it is a subclass.
 */
template<typename R>
bool isA(const ldraw::Object* object)
{
	const std::type_info& a = typeid(*object);
	const std::type_info& b = typeid(R);
	return a == b;
}

template<ldraw::Property property>
ldraw::Object::SetPropertyResult ldraw::Object::setProperty(const ldraw::PropertyType<property>& value)
{
	SetPropertyResult result = SetPropertyResult::PropertyNotHandled;
	this->setProperty(&result, PropertyKeyValue{property, QVariant::fromValue(value)});
	return result;
}

template<ldraw::Property property, typename Function>
void ldraw::Object::handle(SetPropertyResult* result, const PropertyKeyValue& pair, Function function)
{
	if (pair.key == property)
	{
		function(pair.value.value<ldraw::PropertyType<property>>());
		*result = SetPropertyResult::Success;
	}
}

template<ldraw::Property property>
ldraw::PropertyType<property> ldraw::Object::getProperty() const
{
	return this->getProperty(property).value<ldraw::PropertyType<property>>();
}

class ldraw::ColoredObject : public Object
{
public:
	ColoredObject(const Color colorIndex = ldraw::MAIN_COLOR);
	bool hasColor() const override final;
	QVariant getProperty(Property id) const override;
	QDataStream &serialize(QDataStream& stream) const override;
	QDataStream& deserialize(QDataStream& stream) override;
	Color colorIndex = ldraw::MAIN_COLOR;
protected:
	void setProperty(SetPropertyResult* result, const PropertyKeyValue& pair) override;
};

/**
 * @brief Represents an empty line.
 */
class ldraw::Empty : public Object
{
	QString textRepresentation() const override;
	Type typeIdentifier() const override;
	QString toLDrawCode() const override;
	QString typeName() const override;
};

mercurial