Add metallic and roughness settings for part

Part deform painter got removed. Experiment color painter introduced, but not enabled yet.
master
huxingyi 2020-10-18 14:33:15 +09:30
parent 5da1a7f6f2
commit d6f6fb6cdf
158 changed files with 14571 additions and 373 deletions

View File

@ -1346,3 +1346,21 @@ https://www.reddit.com/r/gamedev/comments/5iuf3h/i_am_writting_a_3d_monster_mode
** **
****************************************************************************/ ****************************************************************************/
</pre> </pre>
<h1>Qt-Color-Widgets</h1>
<pre>
Linking this library statically or dynamically with other modules is making a
combined work based on this library. Thus, the terms and conditions of the
GNU Lesser General Public License version 3 cover the whole combination.
As a special exception, the copyright holders of this library give you
permission to combine this library with independent
modules to produce an executable, and to copy and distribute the resulting
executable under terms of any of the GNU General Public licenses, as published
by the Free Software Foundation, provided that you also meet,
for each linked independent module, the terms and conditions of the license of
that module. An independent module is a module which is not derived from or
based on this library. If you modify this library, you may extend this
exception to your version of the library, but you are not obliged to do so.
If you do not wish to do so, delete this exception statement from your version.
</pre>

View File

@ -132,6 +132,7 @@ DEFINES += NOMINMAX
include(thirdparty/QtAwesome/QtAwesome/QtAwesome.pri) include(thirdparty/QtAwesome/QtAwesome/QtAwesome.pri)
include(thirdparty/qtsingleapplication/src/qtsingleapplication.pri) include(thirdparty/qtsingleapplication/src/qtsingleapplication.pri)
include(thirdparty/Qt-Color-Widgets/color_widgets.pri)
INCLUDEPATH += src INCLUDEPATH += src
@ -443,8 +444,11 @@ HEADERS += src/intnumberwidget.h
SOURCES += src/imagepreviewwidget.cpp SOURCES += src/imagepreviewwidget.cpp
HEADERS += src/imagepreviewwidget.h HEADERS += src/imagepreviewwidget.h
SOURCES += src/mousepicker.cpp SOURCES += src/vertexcolorpainter.cpp
HEADERS += src/mousepicker.h HEADERS += src/vertexcolorpainter.h
SOURCES += src/voxelgrid.cpp
HEADERS += src/voxelgrid.h
SOURCES += src/paintmode.cpp SOURCES += src/paintmode.cpp
HEADERS += src/paintmode.h HEADERS += src/paintmode.h

View File

@ -573,16 +573,16 @@ void main()
lights[0].type = TYPE_POINT; lights[0].type = TYPE_POINT;
lights[0].position = firstLightPos; lights[0].position = firstLightPos;
lights[0].color = vec3(1.0, 1.0, 1.0); lights[0].color = vec3(1.0, 1.0, 1.0);
lights[0].intensity = 3.0; lights[0].intensity = 1.0;
lights[0].constantAttenuation = 0.0; lights[0].constantAttenuation = 1.0;
lights[0].linearAttenuation = 0.0; lights[0].linearAttenuation = 0.0;
lights[0].quadraticAttenuation = 0.0; lights[0].quadraticAttenuation = 0.0025;
// Fill light // Fill light
lights[1].type = TYPE_POINT; lights[1].type = TYPE_POINT;
lights[1].position = secondLightPos; lights[1].position = secondLightPos;
lights[1].color = vec3(1.0, 1.0, 1.0); lights[1].color = vec3(1.0, 1.0, 1.0);
lights[1].intensity = 1.0; lights[1].intensity = 0.1;
lights[1].constantAttenuation = 0.0; lights[1].constantAttenuation = 0.0;
lights[1].linearAttenuation = 0.0; lights[1].linearAttenuation = 0.0;
lights[1].quadraticAttenuation = 0.0; lights[1].quadraticAttenuation = 0.0;
@ -591,7 +591,7 @@ void main()
lights[2].type = TYPE_POINT; lights[2].type = TYPE_POINT;
lights[2].position = thirdLightPos; lights[2].position = thirdLightPos;
lights[2].color = vec3(1.0, 1.0, 1.0); lights[2].color = vec3(1.0, 1.0, 1.0);
lights[2].intensity = 0.5; lights[2].intensity = 0.05;
lights[2].constantAttenuation = 0.0; lights[2].constantAttenuation = 0.0;
lights[2].linearAttenuation = 0.0; lights[2].linearAttenuation = 0.0;
lights[2].quadraticAttenuation = 0.0; lights[2].quadraticAttenuation = 0.0;
@ -635,8 +635,8 @@ void main()
ambientOcclusion = texture(metalnessRoughnessAmbientOcclusionMapId, vertTexCoord).r; ambientOcclusion = texture(metalnessRoughnessAmbientOcclusionMapId, vertTexCoord).r;
} }
roughness = min(0.99, roughness);
if (environmentIrradianceMapEnabled != 1) { if (environmentIrradianceMapEnabled != 1) {
roughness = min(0.99, roughness);
metalness = min(0.99, metalness); metalness = min(0.99, metalness);
} }

View File

@ -17,7 +17,6 @@
#include "motionsgenerator.h" #include "motionsgenerator.h"
#include "skeletonside.h" #include "skeletonside.h"
#include "scriptrunner.h" #include "scriptrunner.h"
#include "mousepicker.h"
#include "imageforever.h" #include "imageforever.h"
#include "contourtopartconverter.h" #include "contourtopartconverter.h"
@ -41,10 +40,12 @@ Document::Document() :
rigType(RigType::None), rigType(RigType::None),
weldEnabled(true), weldEnabled(true),
polyCount(PolyCount::Original), polyCount(PolyCount::Original),
brushColor(Qt::white),
// private // private
m_isResultMeshObsolete(false), m_isResultMeshObsolete(false),
m_meshGenerator(nullptr), m_meshGenerator(nullptr),
m_resultMesh(nullptr), m_resultMesh(nullptr),
m_paintedMesh(nullptr),
m_resultMeshCutFaceTransforms(nullptr), m_resultMeshCutFaceTransforms(nullptr),
m_resultMeshNodesCutFaces(nullptr), m_resultMeshNodesCutFaces(nullptr),
m_isMeshGenerationSucceed(true), m_isMeshGenerationSucceed(true),
@ -73,11 +74,12 @@ Document::Document() :
m_nextMeshGenerationId(1), m_nextMeshGenerationId(1),
m_scriptRunner(nullptr), m_scriptRunner(nullptr),
m_isScriptResultObsolete(false), m_isScriptResultObsolete(false),
m_mousePicker(nullptr), m_vertexColorPainter(nullptr),
m_isMouseTargetResultObsolete(false), m_isMouseTargetResultObsolete(false),
m_paintMode(PaintMode::None), m_paintMode(PaintMode::None),
m_mousePickRadius(0.2), m_mousePickRadius(0.05),
m_saveNextPaintSnapshot(false) m_saveNextPaintSnapshot(false),
m_vertexColorVoxelGrid(nullptr)
{ {
connect(&Preferences::instance(), &Preferences::partColorChanged, this, &Document::applyPreferencePartColorChange); connect(&Preferences::instance(), &Preferences::partColorChanged, this, &Document::applyPreferencePartColorChange);
connect(&Preferences::instance(), &Preferences::flatShadingChanged, this, &Document::applyPreferenceFlatShadingChange); connect(&Preferences::instance(), &Preferences::flatShadingChanged, this, &Document::applyPreferenceFlatShadingChange);
@ -103,6 +105,7 @@ void Document::applyPreferenceTextureSizeChange()
Document::~Document() Document::~Document()
{ {
delete m_resultMesh; delete m_resultMesh;
delete m_paintedMesh;
delete m_resultMeshCutFaceTransforms; delete m_resultMeshCutFaceTransforms;
delete m_resultMeshNodesCutFaces; delete m_resultMeshNodesCutFaces;
delete m_postProcessedOutcome; delete m_postProcessedOutcome;
@ -1029,7 +1032,7 @@ void Document::setPaintMode(PaintMode mode)
m_paintMode = mode; m_paintMode = mode;
emit paintModeChanged(); emit paintModeChanged();
doPickMouseTarget(); paintVertexColors();
} }
void Document::joinNodeAndNeiborsToGroup(std::vector<QUuid> *group, QUuid nodeId, std::set<QUuid> *visitMap, QUuid noUseEdgeId) void Document::joinNodeAndNeiborsToGroup(std::vector<QUuid> *group, QUuid nodeId, std::set<QUuid> *visitMap, QUuid noUseEdgeId)
@ -1170,6 +1173,10 @@ void Document::toSnapshot(Snapshot *snapshot, const std::set<QUuid> &limitNodeId
part["color"] = partIt.second.color.name(QColor::HexArgb); part["color"] = partIt.second.color.name(QColor::HexArgb);
if (partIt.second.colorSolubilityAdjusted()) if (partIt.second.colorSolubilityAdjusted())
part["colorSolubility"] = QString::number(partIt.second.colorSolubility); part["colorSolubility"] = QString::number(partIt.second.colorSolubility);
if (partIt.second.metalnessAdjusted())
part["metalness"] = QString::number(partIt.second.metalness);
if (partIt.second.roughnessAdjusted())
part["roughness"] = QString::number(partIt.second.roughness);
if (partIt.second.deformThicknessAdjusted()) if (partIt.second.deformThicknessAdjusted())
part["deformThickness"] = QString::number(partIt.second.deformThickness); part["deformThickness"] = QString::number(partIt.second.deformThickness);
if (partIt.second.deformWidthAdjusted()) if (partIt.second.deformWidthAdjusted())
@ -1590,6 +1597,12 @@ void Document::addFromSnapshot(const Snapshot &snapshot, enum SnapshotSource sou
const auto &colorSolubilityIt = partKv.second.find("colorSolubility"); const auto &colorSolubilityIt = partKv.second.find("colorSolubility");
if (colorSolubilityIt != partKv.second.end()) if (colorSolubilityIt != partKv.second.end())
part.colorSolubility = colorSolubilityIt->second.toFloat(); part.colorSolubility = colorSolubilityIt->second.toFloat();
const auto &metalnessIt = partKv.second.find("metalness");
if (metalnessIt != partKv.second.end())
part.metalness = metalnessIt->second.toFloat();
const auto &roughnessIt = partKv.second.find("roughness");
if (roughnessIt != partKv.second.end())
part.roughness = roughnessIt->second.toFloat();
const auto &deformThicknessIt = partKv.second.find("deformThickness"); const auto &deformThicknessIt = partKv.second.find("deformThickness");
if (deformThicknessIt != partKv.second.end()) if (deformThicknessIt != partKv.second.end())
part.setDeformThickness(deformThicknessIt->second.toFloat()); part.setDeformThickness(deformThicknessIt->second.toFloat());
@ -1905,6 +1918,14 @@ Model *Document::takeResultMesh()
return resultMesh; return resultMesh;
} }
Model *Document::takePaintedMesh()
{
if (nullptr == m_paintedMesh)
return nullptr;
Model *paintedMesh = new Model(*m_paintedMesh);
return paintedMesh;
}
bool Document::isMeshGenerationSucceed() bool Document::isMeshGenerationSucceed()
{ {
return m_isMeshGenerationSucceed; return m_isMeshGenerationSucceed;
@ -2205,12 +2226,12 @@ void Document::pickMouseTarget(const QVector3D &nearPosition, const QVector3D &f
m_mouseRayNear = nearPosition; m_mouseRayNear = nearPosition;
m_mouseRayFar = farPosition; m_mouseRayFar = farPosition;
doPickMouseTarget(); paintVertexColors();
} }
void Document::doPickMouseTarget() void Document::paintVertexColors()
{ {
if (nullptr != m_mousePicker) { if (nullptr != m_vertexColorPainter) {
m_isMouseTargetResultObsolete = true; m_isMouseTargetResultObsolete = true;
return; return;
} }
@ -2225,44 +2246,41 @@ void Document::doPickMouseTarget()
//qDebug() << "Mouse picking.."; //qDebug() << "Mouse picking..";
QThread *thread = new QThread; QThread *thread = new QThread;
m_mousePicker = new MousePicker(*m_currentOutcome, m_mouseRayNear, m_mouseRayFar); m_vertexColorPainter = new VertexColorPainter(*m_currentOutcome, m_mouseRayNear, m_mouseRayFar);
m_vertexColorPainter->setBrushColor(brushColor);
std::map<QUuid, QUuid> paintImages; m_vertexColorPainter->setBrushMetalness(brushMetalness);
for (const auto &it: partMap) { m_vertexColorPainter->setBrushRoughness(brushRoughness);
if (!it.second.deformMapImageId.isNull()) {
paintImages[it.first] = it.second.deformMapImageId;
}
}
if (SkeletonDocumentEditMode::Paint == editMode) { if (SkeletonDocumentEditMode::Paint == editMode) {
m_mousePicker->setPaintImages(paintImages); if (nullptr == m_vertexColorVoxelGrid) {
m_mousePicker->setPaintMode(m_paintMode); m_vertexColorVoxelGrid = new VoxelGrid<PaintColor>();
m_mousePicker->setRadius(m_mousePickRadius); }
m_mousePicker->setMaskNodeIds(m_mousePickMaskNodeIds); m_vertexColorPainter->setVoxelGrid(m_vertexColorVoxelGrid);
m_vertexColorPainter->setPaintMode(m_paintMode);
m_vertexColorPainter->setRadius(m_mousePickRadius);
m_vertexColorPainter->setMaskNodeIds(m_mousePickMaskNodeIds);
} }
m_mousePicker->moveToThread(thread); m_vertexColorPainter->moveToThread(thread);
connect(thread, &QThread::started, m_mousePicker, &MousePicker::process); connect(thread, &QThread::started, m_vertexColorPainter, &VertexColorPainter::process);
connect(m_mousePicker, &MousePicker::finished, this, &Document::mouseTargetReady); connect(m_vertexColorPainter, &VertexColorPainter::finished, this, &Document::vertexColorsReady);
connect(m_mousePicker, &MousePicker::finished, thread, &QThread::quit); connect(m_vertexColorPainter, &VertexColorPainter::finished, thread, &QThread::quit);
connect(thread, &QThread::finished, thread, &QThread::deleteLater); connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start(); thread->start();
} }
void Document::mouseTargetReady() void Document::vertexColorsReady()
{ {
m_mouseTargetPosition = m_mousePicker->targetPosition(); m_mouseTargetPosition = m_vertexColorPainter->targetPosition();
const auto &changedPartIds = m_mousePicker->changedPartIds();
for (const auto &it: m_mousePicker->resultPaintImages()) { Model *model = m_vertexColorPainter->takePaintedModel();
const auto &partId = it.first; if (nullptr != model) {
if (changedPartIds.find(partId) == changedPartIds.end()) delete m_paintedMesh;
continue; m_paintedMesh = model;
const auto &imageId = it.second; emit paintedMeshChanged();
m_intermediatePaintImageIds.insert(imageId);
setPartDeformMapImageId(partId, imageId);
} }
delete m_mousePicker; delete m_vertexColorPainter;
m_mousePicker = nullptr; m_vertexColorPainter = nullptr;
if (!m_isMouseTargetResultObsolete && m_saveNextPaintSnapshot) { if (!m_isMouseTargetResultObsolete && m_saveNextPaintSnapshot) {
m_saveNextPaintSnapshot = false; m_saveNextPaintSnapshot = false;
@ -3064,6 +3082,36 @@ void Document::setPartColorSolubility(QUuid partId, float solubility)
emit skeletonChanged(); emit skeletonChanged();
} }
void Document::setPartMetalness(QUuid partId, float metalness)
{
auto part = partMap.find(partId);
if (part == partMap.end()) {
qDebug() << "Part not found:" << partId;
return;
}
if (qFuzzyCompare(part->second.metalness, metalness))
return;
part->second.metalness = metalness;
part->second.dirty = true;
emit partMetalnessChanged(partId);
emit skeletonChanged();
}
void Document::setPartRoughness(QUuid partId, float roughness)
{
auto part = partMap.find(partId);
if (part == partMap.end()) {
qDebug() << "Part not found:" << partId;
return;
}
if (qFuzzyCompare(part->second.roughness, roughness))
return;
part->second.roughness = roughness;
part->second.dirty = true;
emit partRoughnessChanged(partId);
emit skeletonChanged();
}
void Document::setPartHollowThickness(QUuid partId, float hollowThickness) void Document::setPartHollowThickness(QUuid partId, float hollowThickness)
{ {
auto part = partMap.find(partId); auto part = partMap.find(partId);
@ -4086,19 +4134,11 @@ void Document::startPaint(void)
void Document::stopPaint(void) void Document::stopPaint(void)
{ {
if (m_mousePicker || m_isMouseTargetResultObsolete) { if (m_vertexColorPainter || m_isMouseTargetResultObsolete) {
m_saveNextPaintSnapshot = true; m_saveNextPaintSnapshot = true;
return; return;
} }
saveSnapshot(); //saveSnapshot();
for (const auto &it: partMap) {
m_intermediatePaintImageIds.erase(it.second.deformMapImageId);
}
for (const auto &it: m_intermediatePaintImageIds) {
//qDebug() << "Remove intermediate image:" << it;
ImageForever::remove(it);
}
m_intermediatePaintImageIds.clear();
} }
void Document::setMousePickMaskNodeIds(const std::set<QUuid> &nodeIds) void Document::setMousePickMaskNodeIds(const std::set<QUuid> &nodeIds)

View File

@ -31,11 +31,12 @@
#include "proceduralanimation.h" #include "proceduralanimation.h"
#include "componentlayer.h" #include "componentlayer.h"
#include "clothforce.h" #include "clothforce.h"
#include "voxelgrid.h"
#include "vertexcolorpainter.h"
class MaterialPreviewsGenerator; class MaterialPreviewsGenerator;
class MotionsGenerator; class MotionsGenerator;
class ScriptRunner; class ScriptRunner;
class MousePicker;
class HistoryItem class HistoryItem
{ {
@ -437,6 +438,7 @@ signals:
void edgeReversed(QUuid edgeId); void edgeReversed(QUuid edgeId);
void partPreviewChanged(QUuid partId); void partPreviewChanged(QUuid partId);
void resultMeshChanged(); void resultMeshChanged();
void paintedMeshChanged();
void turnaroundChanged(); void turnaroundChanged();
void editModeChanged(); void editModeChanged();
void paintModeChanged(); void paintModeChanged();
@ -466,6 +468,8 @@ signals:
void partChamferStateChanged(QUuid partId); void partChamferStateChanged(QUuid partId);
void partTargetChanged(QUuid partId); void partTargetChanged(QUuid partId);
void partColorSolubilityChanged(QUuid partId); void partColorSolubilityChanged(QUuid partId);
void partMetalnessChanged(QUuid partId);
void partRoughnessChanged(QUuid partId);
void partHollowThicknessChanged(QUuid partId); void partHollowThicknessChanged(QUuid partId);
void partCountershadeStateChanged(QUuid partId); void partCountershadeStateChanged(QUuid partId);
void partGridStateChanged(QUuid partId); void partGridStateChanged(QUuid partId);
@ -537,6 +541,9 @@ public: // need initialize
RigType rigType; RigType rigType;
bool weldEnabled; bool weldEnabled;
PolyCount polyCount; PolyCount polyCount;
QColor brushColor;
float brushMetalness = Model::m_defaultMetalness;
float brushRoughness = Model::m_defaultRoughness;
public: public:
Document(); Document();
~Document(); ~Document();
@ -576,6 +583,7 @@ public:
const Pose *findPose(QUuid poseId) const; const Pose *findPose(QUuid poseId) const;
const Motion *findMotion(QUuid motionId) const; const Motion *findMotion(QUuid motionId) const;
Model *takeResultMesh(); Model *takeResultMesh();
Model *takePaintedMesh();
bool isMeshGenerationSucceed(); bool isMeshGenerationSucceed();
Model *takeResultTextureMesh(); Model *takeResultTextureMesh();
Model *takeResultRigWeightMesh(); Model *takeResultRigWeightMesh();
@ -646,8 +654,8 @@ public slots:
void generateMotions(); void generateMotions();
void motionsReady(); void motionsReady();
void pickMouseTarget(const QVector3D &nearPosition, const QVector3D &farPosition); void pickMouseTarget(const QVector3D &nearPosition, const QVector3D &farPosition);
void doPickMouseTarget(); void paintVertexColors();
void mouseTargetReady(); void vertexColorsReady();
void setPartLockState(QUuid partId, bool locked); void setPartLockState(QUuid partId, bool locked);
void setPartVisibleState(QUuid partId, bool visible); void setPartVisibleState(QUuid partId, bool visible);
void setPartSubdivState(QUuid partId, bool subdived); void setPartSubdivState(QUuid partId, bool subdived);
@ -668,6 +676,8 @@ public slots:
void setPartChamferState(QUuid partId, bool chamfered); void setPartChamferState(QUuid partId, bool chamfered);
void setPartTarget(QUuid partId, PartTarget target); void setPartTarget(QUuid partId, PartTarget target);
void setPartColorSolubility(QUuid partId, float solubility); void setPartColorSolubility(QUuid partId, float solubility);
void setPartMetalness(QUuid partId, float metalness);
void setPartRoughness(QUuid partId, float roughness);
void setPartHollowThickness(QUuid partId, float hollowThickness); void setPartHollowThickness(QUuid partId, float hollowThickness);
void setPartCountershaded(QUuid partId, bool countershaded); void setPartCountershaded(QUuid partId, bool countershaded);
void setComponentCombineMode(QUuid componentId, CombineMode combineMode); void setComponentCombineMode(QUuid componentId, CombineMode combineMode);
@ -774,6 +784,7 @@ private: // need initialize
bool m_isResultMeshObsolete; bool m_isResultMeshObsolete;
MeshGenerator *m_meshGenerator; MeshGenerator *m_meshGenerator;
Model *m_resultMesh; Model *m_resultMesh;
Model *m_paintedMesh;
std::map<QUuid, StrokeMeshBuilder::CutFaceTransform> *m_resultMeshCutFaceTransforms; std::map<QUuid, StrokeMeshBuilder::CutFaceTransform> *m_resultMeshCutFaceTransforms;
std::map<QUuid, std::map<QString, QVector2D>> *m_resultMeshNodesCutFaces; std::map<QUuid, std::map<QString, QVector2D>> *m_resultMeshNodesCutFaces;
bool m_isMeshGenerationSucceed; bool m_isMeshGenerationSucceed;
@ -805,11 +816,12 @@ private: // need initialize
std::map<QString, std::map<QString, QString>> m_mergedVariables; std::map<QString, std::map<QString, QString>> m_mergedVariables;
ScriptRunner *m_scriptRunner; ScriptRunner *m_scriptRunner;
bool m_isScriptResultObsolete; bool m_isScriptResultObsolete;
MousePicker *m_mousePicker; VertexColorPainter *m_vertexColorPainter;
bool m_isMouseTargetResultObsolete; bool m_isMouseTargetResultObsolete;
PaintMode m_paintMode; PaintMode m_paintMode;
float m_mousePickRadius; float m_mousePickRadius;
bool m_saveNextPaintSnapshot; bool m_saveNextPaintSnapshot;
VoxelGrid<PaintColor> *m_vertexColorVoxelGrid;
private: private:
static unsigned long m_maxSnapshot; static unsigned long m_maxSnapshot;
std::deque<HistoryItem> m_undoItems; std::deque<HistoryItem> m_undoItems;
@ -823,7 +835,6 @@ private:
QString m_scriptConsoleLog; QString m_scriptConsoleLog;
QString m_script; QString m_script;
std::set<QUuid> m_mousePickMaskNodeIds; std::set<QUuid> m_mousePickMaskNodeIds;
std::set<QUuid> m_intermediatePaintImageIds;
}; };
#endif #endif

View File

@ -162,7 +162,8 @@ DocumentWindow::DocumentWindow() :
m_exportPreviewWidget(nullptr), m_exportPreviewWidget(nullptr),
m_preferencesWidget(nullptr), m_preferencesWidget(nullptr),
m_isLastMeshGenerationSucceed(true), m_isLastMeshGenerationSucceed(true),
m_currentUpdatedMeshId(0) m_currentUpdatedMeshId(0),
m_colorWheelWidget(nullptr)
{ {
QObject::connect((QtSingleApplication *)QGuiApplication::instance(), QObject::connect((QtSingleApplication *)QGuiApplication::instance(),
&QtSingleApplication::messageReceived, this, [this](const QString &message) { &QtSingleApplication::messageReceived, this, [this](const QString &message) {
@ -201,9 +202,9 @@ DocumentWindow::DocumentWindow() :
//markerButton->setToolTip(tr("Marker pen")); //markerButton->setToolTip(tr("Marker pen"));
//Theme::initAwesomeButton(markerButton); //Theme::initAwesomeButton(markerButton);
QPushButton *paintButton = new QPushButton(QChar(fa::paintbrush)); //QPushButton *paintButton = new QPushButton(QChar(fa::paintbrush));
paintButton->setToolTip(tr("Paint brush")); //paintButton->setToolTip(tr("Paint brush"));
Theme::initAwesomeButton(paintButton); //Theme::initAwesomeButton(paintButton);
//QPushButton *dragButton = new QPushButton(QChar(fa::handrocko)); //QPushButton *dragButton = new QPushButton(QChar(fa::handrocko));
//dragButton->setToolTip(tr("Enter drag mode")); //dragButton->setToolTip(tr("Enter drag mode"));
@ -269,6 +270,10 @@ DocumentWindow::DocumentWindow() :
updateRegenerateIconAndTips(regenerateButton, m_document->isMeshGenerationSucceed()); updateRegenerateIconAndTips(regenerateButton, m_document->isMeshGenerationSucceed());
generatePartPreviewImages(); generatePartPreviewImages();
}); });
connect(m_document, &Document::paintedMeshChanged, [=]() {
auto paintedMesh = m_document->takePaintedMesh();
m_modelRenderWidget->updateMesh(paintedMesh);
});
connect(m_document, &Document::postProcessing, this, [=]() { connect(m_document, &Document::postProcessing, this, [=]() {
regenerateButton->showSpinner(true); regenerateButton->showSpinner(true);
}); });
@ -287,7 +292,7 @@ DocumentWindow::DocumentWindow() :
toolButtonLayout->addWidget(addButton); toolButtonLayout->addWidget(addButton);
toolButtonLayout->addWidget(selectButton); toolButtonLayout->addWidget(selectButton);
//toolButtonLayout->addWidget(markerButton); //toolButtonLayout->addWidget(markerButton);
toolButtonLayout->addWidget(paintButton); //toolButtonLayout->addWidget(paintButton);
//toolButtonLayout->addWidget(dragButton); //toolButtonLayout->addWidget(dragButton);
toolButtonLayout->addWidget(zoomInButton); toolButtonLayout->addWidget(zoomInButton);
toolButtonLayout->addWidget(zoomOutButton); toolButtonLayout->addWidget(zoomOutButton);
@ -392,16 +397,80 @@ DocumentWindow::DocumentWindow() :
setTabPosition(Qt::RightDockWidgetArea, QTabWidget::East); setTabPosition(Qt::RightDockWidgetArea, QTabWidget::East);
QDockWidget *partTreeDocker = new QDockWidget(tr("Parts"), this); QDockWidget *partsDocker = new QDockWidget(tr("Parts"), this);
partTreeDocker->setAllowedAreas(Qt::RightDockWidgetArea); partsDocker->setAllowedAreas(Qt::RightDockWidgetArea);
m_partTreeWidget = new PartTreeWidget(m_document, partTreeDocker); m_colorWheelWidget = new color_widgets::ColorWheel(nullptr);
partTreeDocker->setWidget(m_partTreeWidget); m_colorWheelWidget->setContentsMargins(0, 5, 0, 5);
addDockWidget(Qt::RightDockWidgetArea, partTreeDocker); m_colorWheelWidget->hide();
//connect(partTreeDocker, &QDockWidget::topLevelChanged, [=](bool topLevel) { m_document->brushColor = m_colorWheelWidget->color();
// Q_UNUSED(topLevel); connect(m_colorWheelWidget, &color_widgets::ColorWheel::colorChanged, this, [=](QColor color) {
// for (const auto &part: m_document->partMap) m_document->brushColor = color;
// m_partTreeWidget->partPreviewChanged(part.first); });
//});
FloatNumberWidget *metalnessWidget = new FloatNumberWidget;
metalnessWidget->setSliderFixedWidth(Theme::sidebarPreferredWidth * 0.4);
metalnessWidget->setItemName(tr("Metallic"));
metalnessWidget->setRange(0.0, 1.0);
metalnessWidget->setValue(m_document->brushMetalness);
connect(metalnessWidget, &FloatNumberWidget::valueChanged, [=](float value) {
m_document->brushMetalness = value;
});
QPushButton *metalnessEraser = new QPushButton(QChar(fa::eraser));
Theme::initAwesomeToolButtonWithoutFont(metalnessEraser);
connect(metalnessEraser, &QPushButton::clicked, [=]() {
metalnessWidget->setValue(Model::m_defaultMetalness);
});
QHBoxLayout *metalnessLayout = new QHBoxLayout;
metalnessLayout->addWidget(metalnessEraser);
metalnessLayout->addWidget(metalnessWidget);
FloatNumberWidget *roughnessWidget = new FloatNumberWidget;
roughnessWidget->setSliderFixedWidth(Theme::sidebarPreferredWidth * 0.35);
roughnessWidget->setItemName(tr("Roughness"));
roughnessWidget->setRange(0.0, 1.0);
roughnessWidget->setValue(m_document->brushRoughness);
connect(roughnessWidget, &FloatNumberWidget::valueChanged, [=](float value) {
m_document->brushRoughness = value;
});
QPushButton *roughnessEraser = new QPushButton(QChar(fa::eraser));
Theme::initAwesomeToolButtonWithoutFont(roughnessEraser);
connect(roughnessEraser, &QPushButton::clicked, [=]() {
roughnessWidget->setValue(Model::m_defaultRoughness);
});
QHBoxLayout *roughnessLayout = new QHBoxLayout;
roughnessLayout->addWidget(roughnessEraser);
roughnessLayout->addWidget(roughnessWidget);
QWidget *metalnessAndRoughnessWidget = new QWidget;
QVBoxLayout *metalnessAndRoughnessLayout = new QVBoxLayout;
metalnessAndRoughnessLayout->addLayout(metalnessLayout);
metalnessAndRoughnessLayout->addLayout(roughnessLayout);
metalnessAndRoughnessWidget->setLayout(metalnessAndRoughnessLayout);
metalnessAndRoughnessWidget->hide();
connect(m_document, &Document::editModeChanged, this, [=]() {
m_colorWheelWidget->setVisible(SkeletonDocumentEditMode::Paint == m_document->editMode);
metalnessAndRoughnessWidget->setVisible(SkeletonDocumentEditMode::Paint == m_document->editMode);
});
m_partTreeWidget = new PartTreeWidget(m_document, nullptr);
QWidget *partsWidget = new QWidget(partsDocker);
QVBoxLayout *partsLayout = new QVBoxLayout;
partsLayout->setContentsMargins(0, 0, 0, 0);
partsLayout->addWidget(m_colorWheelWidget);
partsLayout->addWidget(metalnessAndRoughnessWidget);
partsLayout->addWidget(m_partTreeWidget);
partsWidget->setLayout(partsLayout);
partsDocker->setWidget(partsWidget);
addDockWidget(Qt::RightDockWidgetArea, partsDocker);
QDockWidget *materialDocker = new QDockWidget(tr("Materials"), this); QDockWidget *materialDocker = new QDockWidget(tr("Materials"), this);
materialDocker->setAllowedAreas(Qt::RightDockWidgetArea); materialDocker->setAllowedAreas(Qt::RightDockWidgetArea);
@ -453,13 +522,13 @@ DocumentWindow::DocumentWindow() :
scriptDocker->setWidget(scriptWidget); scriptDocker->setWidget(scriptWidget);
addDockWidget(Qt::RightDockWidgetArea, scriptDocker); addDockWidget(Qt::RightDockWidgetArea, scriptDocker);
tabifyDockWidget(partTreeDocker, materialDocker); tabifyDockWidget(partsDocker, materialDocker);
tabifyDockWidget(materialDocker, rigDocker); tabifyDockWidget(materialDocker, rigDocker);
tabifyDockWidget(rigDocker, poseDocker); tabifyDockWidget(rigDocker, poseDocker);
tabifyDockWidget(poseDocker, motionDocker); tabifyDockWidget(poseDocker, motionDocker);
tabifyDockWidget(motionDocker, scriptDocker); tabifyDockWidget(motionDocker, scriptDocker);
partTreeDocker->raise(); partsDocker->raise();
QHBoxLayout *mainLayout = new QHBoxLayout; QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->setSpacing(0); mainLayout->setSpacing(0);
@ -829,8 +898,8 @@ DocumentWindow::DocumentWindow() :
m_showPartsListAction = new QAction(tr("Parts"), this); m_showPartsListAction = new QAction(tr("Parts"), this);
connect(m_showPartsListAction, &QAction::triggered, [=]() { connect(m_showPartsListAction, &QAction::triggered, [=]() {
partTreeDocker->show(); partsDocker->show();
partTreeDocker->raise(); partsDocker->raise();
}); });
m_windowMenu->addAction(m_showPartsListAction); m_windowMenu->addAction(m_showPartsListAction);
@ -955,9 +1024,9 @@ DocumentWindow::DocumentWindow() :
// m_document->setEditMode(SkeletonDocumentEditMode::Mark); // m_document->setEditMode(SkeletonDocumentEditMode::Mark);
//}); //});
connect(paintButton, &QPushButton::clicked, [=]() { //connect(paintButton, &QPushButton::clicked, [=]() {
m_document->setEditMode(SkeletonDocumentEditMode::Paint); // m_document->setEditMode(SkeletonDocumentEditMode::Paint);
}); //});
//connect(dragButton, &QPushButton::clicked, [=]() { //connect(dragButton, &QPushButton::clicked, [=]() {
// m_document->setEditMode(SkeletonDocumentEditMode::Drag); // m_document->setEditMode(SkeletonDocumentEditMode::Drag);
@ -992,8 +1061,8 @@ DocumentWindow::DocumentWindow() :
m_partListDockerVisibleSwitchConnection = connect(m_document, &Document::skeletonChanged, [=]() { m_partListDockerVisibleSwitchConnection = connect(m_document, &Document::skeletonChanged, [=]() {
if (m_graphicsWidget->hasItems()) { if (m_graphicsWidget->hasItems()) {
if (partTreeDocker->isHidden()) if (partsDocker->isHidden())
partTreeDocker->show(); partsDocker->show();
disconnect(m_partListDockerVisibleSwitchConnection); disconnect(m_partListDockerVisibleSwitchConnection);
} }
}); });
@ -1147,6 +1216,8 @@ DocumentWindow::DocumentWindow() :
connect(m_document, &Document::partHollowThicknessChanged, m_partTreeWidget, &PartTreeWidget::partHollowThicknessChanged); connect(m_document, &Document::partHollowThicknessChanged, m_partTreeWidget, &PartTreeWidget::partHollowThicknessChanged);
connect(m_document, &Document::partMaterialIdChanged, m_partTreeWidget, &PartTreeWidget::partMaterialIdChanged); connect(m_document, &Document::partMaterialIdChanged, m_partTreeWidget, &PartTreeWidget::partMaterialIdChanged);
connect(m_document, &Document::partColorSolubilityChanged, m_partTreeWidget, &PartTreeWidget::partColorSolubilityChanged); connect(m_document, &Document::partColorSolubilityChanged, m_partTreeWidget, &PartTreeWidget::partColorSolubilityChanged);
connect(m_document, &Document::partMetalnessChanged, m_partTreeWidget, &PartTreeWidget::partMetalnessChanged);
connect(m_document, &Document::partRoughnessChanged, m_partTreeWidget, &PartTreeWidget::partRoughnessChanged);
connect(m_document, &Document::partCountershadeStateChanged, m_partTreeWidget, &PartTreeWidget::partCountershadeStateChanged); connect(m_document, &Document::partCountershadeStateChanged, m_partTreeWidget, &PartTreeWidget::partCountershadeStateChanged);
connect(m_document, &Document::partTargetChanged, m_partTreeWidget, &PartTreeWidget::partXmirrorStateChanged); connect(m_document, &Document::partTargetChanged, m_partTreeWidget, &PartTreeWidget::partXmirrorStateChanged);

View File

@ -21,6 +21,7 @@
#include "normalanddepthmapsgenerator.h" #include "normalanddepthmapsgenerator.h"
#include "autosaver.h" #include "autosaver.h"
#include "partpreviewimagesgenerator.h" #include "partpreviewimagesgenerator.h"
#include "QtColorWidgets/ColorWheel"
class SkeletonGraphicsWidget; class SkeletonGraphicsWidget;
class PartTreeWidget; class PartTreeWidget;
@ -116,6 +117,7 @@ private:
bool m_isLastMeshGenerationSucceed; bool m_isLastMeshGenerationSucceed;
quint64 m_currentUpdatedMeshId; quint64 m_currentUpdatedMeshId;
QStringList m_waitingForExportToFilenames; QStringList m_waitingForExportToFilenames;
color_widgets::ColorWheel *m_colorWheelWidget;
private: private:
QString m_currentFilename; QString m_currentFilename;

View File

@ -34,6 +34,11 @@ FloatNumberWidget::FloatNumberWidget(QWidget *parent, bool singleLine) :
} }
} }
void FloatNumberWidget::setSliderFixedWidth(float width)
{
m_slider->setFixedWidth(width);
}
void FloatNumberWidget::updateValueLabel(float value) void FloatNumberWidget::updateValueLabel(float value)
{ {
QString valueString = QString().sprintf("%.2f", value); QString valueString = QString().sprintf("%.2f", value);

View File

@ -9,10 +9,11 @@ class FloatNumberWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit FloatNumberWidget(QWidget *parent = nullptr, bool singleLine=true); explicit FloatNumberWidget(QWidget *parent=nullptr, bool singleLine=true);
void setRange(float min, float max); void setRange(float min, float max);
float value() const; float value() const;
void setItemName(const QString &name); void setItemName(const QString &name);
void setSliderFixedWidth(float width);
public slots: public slots:
void increaseValue(); void increaseValue();

View File

@ -416,6 +416,16 @@ MeshCombiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdString,
if (!colorSolubilityString.isEmpty()) if (!colorSolubilityString.isEmpty())
colorSolubility = colorSolubilityString.toFloat(); colorSolubility = colorSolubilityString.toFloat();
float metalness = 0;
QString metalnessString = valueOfKeyInMapOrEmpty(part, "metalness");
if (!metalnessString.isEmpty())
metalness = metalnessString.toFloat();
float roughness = 1.0;
QString roughnessString = valueOfKeyInMapOrEmpty(part, "roughness");
if (!roughnessString.isEmpty())
roughness = roughnessString.toFloat();
QUuid fillMeshFileId; QUuid fillMeshFileId;
QString fillMeshString = valueOfKeyInMapOrEmpty(part, "fillMesh"); QString fillMeshString = valueOfKeyInMapOrEmpty(part, "fillMesh");
if (!fillMeshString.isEmpty()) { if (!fillMeshString.isEmpty()) {
@ -538,6 +548,8 @@ MeshCombiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdString,
outcomeNode.materialId = materialId; outcomeNode.materialId = materialId;
outcomeNode.countershaded = countershaded; outcomeNode.countershaded = countershaded;
outcomeNode.colorSolubility = colorSolubility; outcomeNode.colorSolubility = colorSolubility;
outcomeNode.metalness = metalness;
outcomeNode.roughness = roughness;
outcomeNode.boneMark = nodeInfo.boneMark; outcomeNode.boneMark = nodeInfo.boneMark;
if (!__mirroredByPartId.isEmpty()) if (!__mirroredByPartId.isEmpty())
outcomeNode.mirroredByPartId = QUuid(__mirroredByPartId); outcomeNode.mirroredByPartId = QUuid(__mirroredByPartId);

View File

@ -5,8 +5,6 @@
#include "model.h" #include "model.h"
#include "version.h" #include "version.h"
#define MAX_VERTICES_PER_FACE 100
float Model::m_defaultMetalness = 0.0; float Model::m_defaultMetalness = 0.0;
float Model::m_defaultRoughness = 1.0; float Model::m_defaultRoughness = 1.0;

View File

@ -156,18 +156,22 @@ void ModelMeshBinder::paint(ModelShaderProgram *program)
(m_hasMetalnessMap || m_hasRoughnessMap || m_hasAmbientOcclusionMap)) (m_hasMetalnessMap || m_hasRoughnessMap || m_hasAmbientOcclusionMap))
m_metalnessRoughnessAmbientOcclusionMap = new QOpenGLTexture(*m_mesh->metalnessRoughnessAmbientOcclusionImage()); m_metalnessRoughnessAmbientOcclusionMap = new QOpenGLTexture(*m_mesh->metalnessRoughnessAmbientOcclusionImage());
delete m_environmentIrradianceMap; //delete m_environmentIrradianceMap;
m_environmentIrradianceMap = nullptr; //m_environmentIrradianceMap = nullptr;
delete m_environmentSpecularMap; //delete m_environmentSpecularMap;
m_environmentSpecularMap = nullptr; //m_environmentSpecularMap = nullptr;
if (program->isCoreProfile() && if (program->isCoreProfile() &&
m_environmentLightEnabled && m_environmentLightEnabled/* &&
(m_hasMetalnessMap || m_hasRoughnessMap)) { (m_hasMetalnessMap || m_hasRoughnessMap)*/) {
DdsFileReader irradianceFile(":/resources/cedar_bridge_irradiance.dds"); if (nullptr == m_environmentIrradianceMap) {
m_environmentIrradianceMap = irradianceFile.createOpenGLTexture(); DdsFileReader irradianceFile(":/resources/cedar_bridge_irradiance.dds");
m_environmentIrradianceMap = irradianceFile.createOpenGLTexture();
}
DdsFileReader specularFile(":/resources/cedar_bridge_specular.dds"); if (nullptr == m_environmentSpecularMap) {
m_environmentSpecularMap = specularFile.createOpenGLTexture(); DdsFileReader specularFile(":/resources/cedar_bridge_specular.dds");
m_environmentSpecularMap = specularFile.createOpenGLTexture();
}
} }
{ {

View File

@ -1,217 +0,0 @@
#include <QDebug>
#include <QQuaternion>
#include <QRadialGradient>
#include <QBrush>
#include <QPainter>
#include <QGuiApplication>
#include "mousepicker.h"
#include "util.h"
#include "imageforever.h"
MousePicker::MousePicker(const Outcome &outcome, const QVector3D &mouseRayNear, const QVector3D &mouseRayFar) :
m_outcome(outcome),
m_mouseRayNear(mouseRayNear),
m_mouseRayFar(mouseRayFar)
{
}
const std::set<QUuid> &MousePicker::changedPartIds()
{
return m_changedPartIds;
}
void MousePicker::setPaintMode(PaintMode paintMode)
{
m_paintMode = paintMode;
}
void MousePicker::setMaskNodeIds(const std::set<QUuid> &nodeIds)
{
m_mousePickMaskNodeIds = nodeIds;
}
void MousePicker::setRadius(float radius)
{
m_radius = radius;
}
MousePicker::~MousePicker()
{
}
bool MousePicker::calculateMouseModelPosition(QVector3D &mouseModelPosition)
{
bool foundPosition = false;
auto ray = (m_mouseRayNear - m_mouseRayFar).normalized();
float minDistance2 = std::numeric_limits<float>::max();
for (size_t i = 0; i < m_outcome.triangles.size(); ++i) {
const auto &triangleIndices = m_outcome.triangles[i];
std::vector<QVector3D> triangle = {
m_outcome.vertices[triangleIndices[0]],
m_outcome.vertices[triangleIndices[1]],
m_outcome.vertices[triangleIndices[2]],
};
const auto &triangleNormal = m_outcome.triangleNormals[i];
if (QVector3D::dotProduct(triangleNormal, ray) <= 0)
continue;
QVector3D intersection;
if (intersectSegmentAndTriangle(m_mouseRayNear, m_mouseRayFar,
triangle,
triangleNormal,
&intersection)) {
float distance2 = (intersection - m_mouseRayNear).lengthSquared();
if (distance2 < minDistance2) {
mouseModelPosition = intersection;
minDistance2 = distance2;
foundPosition = true;
}
}
}
return foundPosition;
}
void MousePicker::pick()
{
if (!calculateMouseModelPosition(m_targetPosition))
return;
if (PaintMode::None == m_paintMode)
return;
float distance2 = m_radius * m_radius;
for (const auto &map: m_outcome.paintMaps) {
for (const auto &node: map.paintNodes) {
if (!m_mousePickMaskNodeIds.empty() && m_mousePickMaskNodeIds.find(node.originNodeId) == m_mousePickMaskNodeIds.end())
continue;
size_t intersectedNum = 0;
QVector3D sumOfDirection;
QVector3D referenceDirection = (m_targetPosition - node.origin).normalized();
float sumOfRadius = 0;
for (const auto &vertexPosition: node.vertices) {
// >0.866 = <30 degrees
auto direction = (vertexPosition - node.origin).normalized();
if (QVector3D::dotProduct(referenceDirection, direction) > 0.866 &&
(vertexPosition - m_targetPosition).lengthSquared() <= distance2) {
float distance = vertexPosition.distanceToPoint(m_targetPosition);
float radius = (m_radius - distance) / node.radius;
sumOfRadius += radius;
sumOfDirection += direction * radius;
++intersectedNum;
}
}
if (intersectedNum > 0) {
float paintRadius = sumOfRadius / intersectedNum;
QVector3D paintDirection = sumOfDirection.normalized();
float degrees = angleInRangle360BetweenTwoVectors(node.baseNormal, paintDirection, node.direction);
float offset = (float)node.order / map.paintNodes.size();
m_changedPartIds.insert(map.partId);
paintToImage(map.partId, offset, degrees / 360.0, paintRadius, PaintMode::Push == m_paintMode);
}
}
}
}
void MousePicker::process()
{
pick();
emit finished();
}
void MousePicker::paintToImage(const QUuid &partId, float x, float y, float radius, bool inverted)
{
QUuid oldImageId;
QImage image(72, 36, QImage::Format_Grayscale8);
image.fill(QColor(127, 127, 127));
const auto &findImageId = m_paintImages.find(partId);
if (findImageId != m_paintImages.end()) {
const QImage *oldImage = ImageForever::get(findImageId->second);
if (nullptr != oldImage) {
if (oldImage->size() == image.size() &&
oldImage->format() == image.format()) {
image = *oldImage;
}
}
}
float destX = image.width() * x;
float destY = image.height() * y;
float destRadius = image.height() * radius;
{
QRadialGradient gradient(destX, destY, destRadius / 2);
if (inverted) {
gradient.setColorAt(0, QColor(0, 0, 0, 3));
gradient.setColorAt(1, Qt::transparent);
} else {
gradient.setColorAt(0, QColor(255, 255, 255, 3));
gradient.setColorAt(1, Qt::transparent);
}
QBrush brush(gradient);
QPainter paint(&image);
paint.setRenderHint(QPainter::HighQualityAntialiasing);
paint.setBrush(brush);
paint.setPen(Qt::NoPen);
paint.drawEllipse(destX - destRadius / 2, destY - destRadius / 2, destRadius, destRadius);
}
QUuid imageId = ImageForever::add(&image);
m_paintImages[partId] = imageId;
}
const QVector3D &MousePicker::targetPosition()
{
return m_targetPosition;
}
bool MousePicker::intersectSegmentAndPlane(const QVector3D &segmentPoint0, const QVector3D &segmentPoint1,
const QVector3D &pointOnPlane, const QVector3D &planeNormal,
QVector3D *intersection)
{
auto u = segmentPoint1 - segmentPoint0;
auto w = segmentPoint0 - pointOnPlane;
auto d = QVector3D::dotProduct(planeNormal, u);
auto n = QVector3D::dotProduct(-planeNormal, w);
if (qAbs(d) < 0.00000001)
return false;
auto s = n / d;
if (s < 0 || s > 1 || qIsNaN(s) || qIsInf(s))
return false;
if (nullptr != intersection)
*intersection = segmentPoint0 + s * u;
return true;
}
bool MousePicker::intersectSegmentAndTriangle(const QVector3D &segmentPoint0, const QVector3D &segmentPoint1,
const std::vector<QVector3D> &triangle,
const QVector3D &triangleNormal,
QVector3D *intersection)
{
QVector3D possibleIntersection;
if (!intersectSegmentAndPlane(segmentPoint0, segmentPoint1,
triangle[0], triangleNormal, &possibleIntersection)) {
return false;
}
auto ray = (segmentPoint0 - segmentPoint1).normalized();
std::vector<QVector3D> normals;
for (size_t i = 0; i < 3; ++i) {
size_t j = (i + 1) % 3;
normals.push_back(QVector3D::normal(possibleIntersection, triangle[i], triangle[j]));
}
if (QVector3D::dotProduct(normals[0], ray) <= 0)
return false;
if (QVector3D::dotProduct(normals[0], normals[1]) <= 0)
return false;
if (QVector3D::dotProduct(normals[0], normals[2]) <= 0)
return false;
if (nullptr != intersection)
*intersection = possibleIntersection;
return true;
}
void MousePicker::setPaintImages(const std::map<QUuid, QUuid> &paintImages)
{
m_paintImages = paintImages;
}
const std::map<QUuid, QUuid> &MousePicker::resultPaintImages()
{
return m_paintImages;
}

View File

@ -1,52 +0,0 @@
#ifndef DUST3D_MOUSE_PICKER_H
#define DUST3D_MOUSE_PICKER_H
#include <QObject>
#include <QVector3D>
#include <vector>
#include <map>
#include <set>
#include "outcome.h"
#include "paintmode.h"
class MousePicker : public QObject
{
Q_OBJECT
public:
MousePicker(const Outcome &outcome, const QVector3D &mouseRayNear, const QVector3D &mouseRayFar);
void setRadius(float radius);
void setPaintImages(const std::map<QUuid, QUuid> &paintImages);
void setPaintMode(PaintMode paintMode);
void setMaskNodeIds(const std::set<QUuid> &nodeIds);
const std::map<QUuid, QUuid> &resultPaintImages();
const std::set<QUuid> &changedPartIds();
~MousePicker();
const QVector3D &targetPosition();
signals:
void finished();
public slots:
void process();
void pick();
private:
float m_radius = 0.0;
std::map<QUuid, QUuid> m_paintImages;
PaintMode m_paintMode = PaintMode::None;
std::set<QUuid> m_changedPartIds;
std::set<QUuid> m_mousePickMaskNodeIds;
bool m_enablePaint = false;
Outcome m_outcome;
QVector3D m_mouseRayNear;
QVector3D m_mouseRayFar;
QVector3D m_targetPosition;
static bool intersectSegmentAndPlane(const QVector3D &segmentPoint0, const QVector3D &segmentPoint1,
const QVector3D &pointOnPlane, const QVector3D &planeNormal,
QVector3D *intersection=nullptr);
static bool intersectSegmentAndTriangle(const QVector3D &segmentPoint0, const QVector3D &segmentPoint1,
const std::vector<QVector3D> &triangle,
const QVector3D &triangleNormal,
QVector3D *intersection=nullptr);
bool calculateMouseModelPosition(QVector3D &mouseModelPosition);
void paintToImage(const QUuid &partId, float x, float y, float radius, bool inverted=false);
};
#endif

View File

@ -19,6 +19,8 @@ struct OutcomeNode
float radius = 0; float radius = 0;
QColor color; QColor color;
float colorSolubility = 0; float colorSolubility = 0;
float metalness = 0;
float roughness = 1.0;
QUuid materialId; QUuid materialId;
bool countershaded = false; bool countershaded = false;
QUuid mirrorFromPartId; QUuid mirrorFromPartId;

View File

@ -28,6 +28,7 @@ void PartPreviewImagesGenerator::generate()
m_offscreenRender->setZRotation(0); m_offscreenRender->setZRotation(0);
m_offscreenRender->setEyePosition(QVector3D(0, 0, -4.0)); m_offscreenRender->setEyePosition(QVector3D(0, 0, -4.0));
m_offscreenRender->enableEnvironmentLight();
m_offscreenRender->setRenderPurpose(0); m_offscreenRender->setRenderPurpose(0);
for (auto &it: m_partPreviews) { for (auto &it: m_partPreviews) {
if (it.second.isCutFace) { if (it.second.isCutFace) {

View File

@ -1442,6 +1442,28 @@ void PartTreeWidget::partColorSolubilityChanged(QUuid partId)
widget->updateColorButton(); widget->updateColorButton();
} }
void PartTreeWidget::partMetalnessChanged(QUuid partId)
{
auto item = m_partItemMap.find(partId);
if (item == m_partItemMap.end()) {
qDebug() << "Part item not found:" << partId;
return;
}
PartWidget *widget = (PartWidget *)itemWidget(item->second, 0);
widget->updateColorButton();
}
void PartTreeWidget::partRoughnessChanged(QUuid partId)
{
auto item = m_partItemMap.find(partId);
if (item == m_partItemMap.end()) {
qDebug() << "Part item not found:" << partId;
return;
}
PartWidget *widget = (PartWidget *)itemWidget(item->second, 0);
widget->updateColorButton();
}
void PartTreeWidget::partCountershadeStateChanged(QUuid partId) void PartTreeWidget::partCountershadeStateChanged(QUuid partId)
{ {
auto item = m_partItemMap.find(partId); auto item = m_partItemMap.find(partId);

View File

@ -79,6 +79,8 @@ public slots:
void partHollowThicknessChanged(QUuid partId); void partHollowThicknessChanged(QUuid partId);
void partMaterialIdChanged(QUuid partId); void partMaterialIdChanged(QUuid partId);
void partColorSolubilityChanged(QUuid partId); void partColorSolubilityChanged(QUuid partId);
void partMetalnessChanged(QUuid partId);
void partRoughnessChanged(QUuid partId);
void partCountershadeStateChanged(QUuid partId); void partCountershadeStateChanged(QUuid partId);
void partChecked(QUuid partId); void partChecked(QUuid partId);
void partUnchecked(QUuid partId); void partUnchecked(QUuid partId);

View File

@ -177,6 +177,8 @@ PartWidget::PartWidget(const Document *document, QUuid partId) :
connect(this, &PartWidget::setPartColorState, m_document, &Document::setPartColorState); connect(this, &PartWidget::setPartColorState, m_document, &Document::setPartColorState);
connect(this, &PartWidget::setPartMaterialId, m_document, &Document::setPartMaterialId); connect(this, &PartWidget::setPartMaterialId, m_document, &Document::setPartMaterialId);
connect(this, &PartWidget::setPartColorSolubility, m_document, &Document::setPartColorSolubility); connect(this, &PartWidget::setPartColorSolubility, m_document, &Document::setPartColorSolubility);
connect(this, &PartWidget::setPartMetalness, m_document, &Document::setPartMetalness);
connect(this, &PartWidget::setPartRoughness, m_document, &Document::setPartRoughness);
connect(this, &PartWidget::setPartHollowThickness, m_document, &Document::setPartHollowThickness); connect(this, &PartWidget::setPartHollowThickness, m_document, &Document::setPartHollowThickness);
connect(this, &PartWidget::setPartCountershaded, m_document, &Document::setPartCountershaded); connect(this, &PartWidget::setPartCountershaded, m_document, &Document::setPartCountershaded);
connect(this, &PartWidget::checkPart, m_document, &Document::checkPart); connect(this, &PartWidget::checkPart, m_document, &Document::checkPart);
@ -469,10 +471,57 @@ void PartWidget::showColorSettingPopup(const QPoint &pos)
colorSolubilityLayout->addWidget(colorSolubilityEraser); colorSolubilityLayout->addWidget(colorSolubilityEraser);
colorSolubilityLayout->addWidget(colorSolubilityWidget); colorSolubilityLayout->addWidget(colorSolubilityWidget);
FloatNumberWidget *metalnessWidget = new FloatNumberWidget;
metalnessWidget->setItemName(tr("Metallic"));
metalnessWidget->setRange(0.0, 1.0);
metalnessWidget->setValue(part->metalness);
connect(metalnessWidget, &FloatNumberWidget::valueChanged, [=](float value) {
emit setPartMetalness(m_partId, value);
emit groupOperationAdded();
});
QPushButton *metalnessEraser = new QPushButton(QChar(fa::eraser));
initToolButton(metalnessEraser);
connect(metalnessEraser, &QPushButton::clicked, [=]() {
metalnessWidget->setValue(0.0);
emit groupOperationAdded();
});
QHBoxLayout *metalnessLayout = new QHBoxLayout;
metalnessLayout->addWidget(metalnessEraser);
metalnessLayout->addWidget(metalnessWidget);
FloatNumberWidget *roughnessWidget = new FloatNumberWidget;
roughnessWidget->setItemName(tr("Roughness"));
roughnessWidget->setRange(0.0, 1.0);
roughnessWidget->setValue(part->roughness);
connect(roughnessWidget, &FloatNumberWidget::valueChanged, [=](float value) {
emit setPartRoughness(m_partId, value);
emit groupOperationAdded();
});
QPushButton *roughnessEraser = new QPushButton(QChar(fa::eraser));
initToolButton(roughnessEraser);
connect(roughnessEraser, &QPushButton::clicked, [=]() {
roughnessWidget->setValue(1.0);
emit groupOperationAdded();
});
QHBoxLayout *roughnessLayout = new QHBoxLayout;
roughnessLayout->addWidget(roughnessEraser);
roughnessLayout->addWidget(roughnessWidget);
QVBoxLayout *mainLayout = new QVBoxLayout; QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addLayout(colorLayout); mainLayout->addLayout(colorLayout);
mainLayout->addLayout(colorTransparencyLayout); mainLayout->addLayout(colorTransparencyLayout);
mainLayout->addLayout(colorSolubilityLayout); mainLayout->addLayout(colorSolubilityLayout);
mainLayout->addWidget(Theme::createHorizontalLineWidget());
mainLayout->addLayout(metalnessLayout);
mainLayout->addLayout(roughnessLayout);
if (m_document->materialIdList.empty()) { if (m_document->materialIdList.empty()) {
InfoLabel *infoLabel = new InfoLabel; InfoLabel *infoLabel = new InfoLabel;
@ -861,10 +910,16 @@ void PartWidget::updateColorButton()
qDebug() << "Part not found:" << m_partId; qDebug() << "Part not found:" << m_partId;
return; return;
} }
if (part->hasColor || part->materialAdjusted() || part->colorSolubilityAdjusted() || part->countershaded) if (part->hasColor ||
part->materialAdjusted() ||
part->colorSolubilityAdjusted() ||
part->countershaded ||
part->metalnessAdjusted() ||
part->roughnessAdjusted()) {
updateButton(m_colorButton, QChar(fa::eyedropper), true, part->hasColorFunction()); updateButton(m_colorButton, QChar(fa::eyedropper), true, part->hasColorFunction());
else } else {
updateButton(m_colorButton, QChar(fa::eyedropper), false, part->hasColorFunction()); updateButton(m_colorButton, QChar(fa::eyedropper), false, part->hasColorFunction());
}
} }
void PartWidget::updateCutRotationButton() void PartWidget::updateCutRotationButton()

View File

@ -28,6 +28,8 @@ signals:
void setPartCutFaceLinkedId(QUuid partId, QUuid linkedId); void setPartCutFaceLinkedId(QUuid partId, QUuid linkedId);
void setPartMaterialId(QUuid partId, QUuid materialId); void setPartMaterialId(QUuid partId, QUuid materialId);
void setPartColorSolubility(QUuid partId, float colorSolubility); void setPartColorSolubility(QUuid partId, float colorSolubility);
void setPartMetalness(QUuid partId, float metalness);
void setPartRoughness(QUuid partId, float roughness);
void setPartHollowThickness(QUuid partId, float hollowThickness); void setPartHollowThickness(QUuid partId, float hollowThickness);
void setPartCountershaded(QUuid partId, bool countershaded); void setPartCountershaded(QUuid partId, bool countershaded);
void movePartUp(QUuid partId); void movePartUp(QUuid partId);

View File

@ -27,7 +27,7 @@ void initShortCuts(QWidget *widget, SkeletonGraphicsWidget *graphicsWidget)
defineKey(Qt::CTRL + Qt::Key_C, &SkeletonGraphicsWidget::shortcutCopy); defineKey(Qt::CTRL + Qt::Key_C, &SkeletonGraphicsWidget::shortcutCopy);
defineKey(Qt::CTRL + Qt::Key_V, &SkeletonGraphicsWidget::shortcutPaste); defineKey(Qt::CTRL + Qt::Key_V, &SkeletonGraphicsWidget::shortcutPaste);
defineKey(Qt::Key_S, &SkeletonGraphicsWidget::shortcutSelectMode); defineKey(Qt::Key_S, &SkeletonGraphicsWidget::shortcutSelectMode);
defineKey(Qt::Key_D, &SkeletonGraphicsWidget::shortcutPaintMode); //defineKey(Qt::Key_D, &SkeletonGraphicsWidget::shortcutPaintMode);
defineKey(Qt::ALT + Qt::Key_Minus, &SkeletonGraphicsWidget::shortcutZoomRenderedModelByMinus10); defineKey(Qt::ALT + Qt::Key_Minus, &SkeletonGraphicsWidget::shortcutZoomRenderedModelByMinus10);
defineKey(Qt::Key_Minus, &SkeletonGraphicsWidget::shortcutZoomSelectedByMinus1); defineKey(Qt::Key_Minus, &SkeletonGraphicsWidget::shortcutZoomSelectedByMinus1);
defineKey(Qt::ALT + Qt::Key_Equal, &SkeletonGraphicsWidget::shortcutZoomRenderedModelBy10); defineKey(Qt::ALT + Qt::Key_Equal, &SkeletonGraphicsWidget::shortcutZoomRenderedModelBy10);

View File

@ -177,6 +177,8 @@ public:
QUuid materialId; QUuid materialId;
PartTarget target; PartTarget target;
float colorSolubility; float colorSolubility;
float metalness;
float roughness;
float deformMapScale; float deformMapScale;
QUuid deformMapImageId; QUuid deformMapImageId;
float hollowThickness; float hollowThickness;
@ -204,6 +206,8 @@ public:
cutFace(CutFace::Quad), cutFace(CutFace::Quad),
target(PartTarget::Model), target(PartTarget::Model),
colorSolubility(0.0), colorSolubility(0.0),
metalness(0.0),
roughness(1.0),
deformMapScale(1.0), deformMapScale(1.0),
hollowThickness(0.0), hollowThickness(0.0),
countershaded(false), countershaded(false),
@ -334,6 +338,14 @@ public:
{ {
return fabs(colorSolubility - 0.0) >= 0.01; return fabs(colorSolubility - 0.0) >= 0.01;
} }
bool metalnessAdjusted() const
{
return fabs(metalness - 0.0) >= 0.01;
}
bool roughnessAdjusted() const
{
return fabs(roughness - 1.0) >= 0.01;
}
bool cutRotationAdjusted() const bool cutRotationAdjusted() const
{ {
return fabs(cutRotation - 0.0) >= 0.01; return fabs(cutRotation - 0.0) >= 0.01;

View File

@ -248,6 +248,8 @@ void TextureGenerator::generate()
std::map<QUuid, QColor> partColorMap; std::map<QUuid, QColor> partColorMap;
std::map<std::pair<QUuid, QUuid>, const OutcomeNode *> nodeMap; std::map<std::pair<QUuid, QUuid>, const OutcomeNode *> nodeMap;
std::map<QUuid, float> partColorSolubilityMap; std::map<QUuid, float> partColorSolubilityMap;
std::map<QUuid, float> partMetalnessMap;
std::map<QUuid, float> partRoughnessMap;
for (const auto &item: m_outcome->nodes) { for (const auto &item: m_outcome->nodes) {
if (!m_hasTransparencySettings) { if (!m_hasTransparencySettings) {
if (!qFuzzyCompare(1.0, item.color.alphaF())) if (!qFuzzyCompare(1.0, item.color.alphaF()))
@ -256,6 +258,8 @@ void TextureGenerator::generate()
nodeMap.insert({{item.partId, item.nodeId}, &item}); nodeMap.insert({{item.partId, item.nodeId}, &item});
partColorMap.insert({item.partId, item.color}); partColorMap.insert({item.partId, item.color});
partColorSolubilityMap.insert({item.partId, item.colorSolubility}); partColorSolubilityMap.insert({item.partId, item.colorSolubility});
partMetalnessMap.insert({item.partId, item.metalness});
partRoughnessMap.insert({item.partId, item.roughness});
} }
auto createImageBeginTime = countTimeConsumed.elapsed(); auto createImageBeginTime = countTimeConsumed.elapsed();
@ -339,6 +343,56 @@ void TextureGenerator::generate()
} }
} }
for (const auto &it: partUvRects) {
const auto &partId = it.first;
const auto &rects = it.second;
auto findMetalnessResult = partMetalnessMap.find(partId);
if (findMetalnessResult != partMetalnessMap.end()) {
if (qFuzzyCompare(findMetalnessResult->second, (float)0.0))
continue;
const auto &color = QColor(findMetalnessResult->second * 255,
findMetalnessResult->second * 255,
findMetalnessResult->second * 255);
QBrush brush(color);
float fillExpandSize = 2;
for (const auto &rect: rects) {
QRectF translatedRect = {
rect.left() * TextureGenerator::m_textureSize - fillExpandSize,
rect.top() * TextureGenerator::m_textureSize - fillExpandSize,
rect.width() * TextureGenerator::m_textureSize + fillExpandSize * 2,
rect.height() * TextureGenerator::m_textureSize + fillExpandSize * 2
};
textureMetalnessPainter.fillRect(translatedRect, brush);
hasMetalnessMap = true;
}
}
}
for (const auto &it: partUvRects) {
const auto &partId = it.first;
const auto &rects = it.second;
auto findRoughnessResult = partRoughnessMap.find(partId);
if (findRoughnessResult != partRoughnessMap.end()) {
if (qFuzzyCompare(findRoughnessResult->second, (float)1.0))
continue;
const auto &color = QColor(findRoughnessResult->second * 255,
findRoughnessResult->second * 255,
findRoughnessResult->second * 255);
QBrush brush(color);
float fillExpandSize = 2;
for (const auto &rect: rects) {
QRectF translatedRect = {
rect.left() * TextureGenerator::m_textureSize - fillExpandSize,
rect.top() * TextureGenerator::m_textureSize - fillExpandSize,
rect.width() * TextureGenerator::m_textureSize + fillExpandSize * 2,
rect.height() * TextureGenerator::m_textureSize + fillExpandSize * 2
};
textureRoughnessPainter.fillRect(translatedRect, brush);
hasRoughnessMap = true;
}
}
}
auto drawTexture = [&](const std::map<QUuid, std::pair<QPixmap, QPixmap>> &map, QPainter &painter, bool useAlpha) { auto drawTexture = [&](const std::map<QUuid, std::pair<QPixmap, QPixmap>> &map, QPainter &painter, bool useAlpha) {
for (const auto &it: partUvRects) { for (const auto &it: partUvRects) {
const auto &partId = it.first; const auto &partId = it.first;
@ -629,8 +683,10 @@ void TextureGenerator::generate()
} }
hasNormalMap = !m_partNormalTextureMap.empty(); hasNormalMap = !m_partNormalTextureMap.empty();
hasMetalnessMap = !m_partMetalnessTextureMap.empty(); if (!m_partMetalnessTextureMap.empty())
hasRoughnessMap = !m_partRoughnessTextureMap.empty(); hasMetalnessMap = true;
if (!m_partRoughnessTextureMap.empty())
hasRoughnessMap = true;
hasAmbientOcclusionMap = !m_partAmbientOcclusionTextureMap.empty(); hasAmbientOcclusionMap = !m_partAmbientOcclusionTextureMap.empty();
auto paintTextureEndTime = countTimeConsumed.elapsed(); auto paintTextureEndTime = countTimeConsumed.elapsed();

View File

@ -25,7 +25,7 @@ QString TextureTypeToDispName(TextureType type) \
case TextureType::Normal: \ case TextureType::Normal: \
return QObject::tr("Normal Map"); \ return QObject::tr("Normal Map"); \
case TextureType::Metalness: \ case TextureType::Metalness: \
return QObject::tr("Metalness"); \ return QObject::tr("Metallic"); \
case TextureType::Roughness: \ case TextureType::Roughness: \
return QObject::tr("Roughness"); \ return QObject::tr("Roughness"); \
case TextureType::AmbientOcclusion: \ case TextureType::AmbientOcclusion: \

View File

@ -510,3 +510,87 @@ void saveAsObj(const char *filename, const std::vector<QVector3D> &vertices,
stream << endl; stream << endl;
} }
} }
bool intersectSegmentAndPlane(const QVector3D &segmentPoint0, const QVector3D &segmentPoint1,
const QVector3D &pointOnPlane, const QVector3D &planeNormal,
QVector3D *intersection)
{
auto u = segmentPoint1 - segmentPoint0;
auto w = segmentPoint0 - pointOnPlane;
auto d = QVector3D::dotProduct(planeNormal, u);
auto n = QVector3D::dotProduct(-planeNormal, w);
if (qAbs(d) < 0.00000001)
return false;
auto s = n / d;
if (s < 0 || s > 1 || qIsNaN(s) || qIsInf(s))
return false;
if (nullptr != intersection)
*intersection = segmentPoint0 + s * u;
return true;
}
bool intersectSegmentAndTriangle(const QVector3D &segmentPoint0, const QVector3D &segmentPoint1,
const std::vector<QVector3D> &triangle,
const QVector3D &triangleNormal,
QVector3D *intersection)
{
QVector3D possibleIntersection;
if (!intersectSegmentAndPlane(segmentPoint0, segmentPoint1,
triangle[0], triangleNormal, &possibleIntersection)) {
return false;
}
auto ray = (segmentPoint0 - segmentPoint1).normalized();
std::vector<QVector3D> normals;
for (size_t i = 0; i < 3; ++i) {
size_t j = (i + 1) % 3;
normals.push_back(QVector3D::normal(possibleIntersection, triangle[i], triangle[j]));
}
if (QVector3D::dotProduct(normals[0], ray) <= 0)
return false;
if (QVector3D::dotProduct(normals[0], normals[1]) <= 0)
return false;
if (QVector3D::dotProduct(normals[0], normals[2]) <= 0)
return false;
if (nullptr != intersection)
*intersection = possibleIntersection;
return true;
}
bool intersectRayAndPolyhedron(const QVector3D &rayNear,
const QVector3D &rayFar,
const std::vector<QVector3D> &vertices,
const std::vector<std::vector<size_t>> &triangles,
const std::vector<QVector3D> &triangleNormals,
QVector3D *intersection)
{
bool foundPosition = false;
auto ray = (rayNear - rayFar).normalized();
float minDistance2 = std::numeric_limits<float>::max();
for (size_t i = 0; i < triangles.size(); ++i) {
const auto &triangleIndices = triangles[i];
std::vector<QVector3D> triangle = {
vertices[triangleIndices[0]],
vertices[triangleIndices[1]],
vertices[triangleIndices[2]],
};
const auto &triangleNormal = triangleNormals[i];
if (QVector3D::dotProduct(triangleNormal, ray) <= 0)
continue;
QVector3D point;
if (intersectSegmentAndTriangle(rayNear, rayFar,
triangle,
triangleNormal,
&point)) {
float distance2 = (point - rayNear).lengthSquared();
if (distance2 < minDistance2) {
if (nullptr != intersection)
*intersection = point;
minDistance2 = distance2;
foundPosition = true;
}
}
}
return foundPosition;
}

View File

@ -47,5 +47,18 @@ void subdivideFace2D(std::vector<QVector2D> *face);
QVector3D choosenBaseAxis(const QVector3D &layoutDirection); QVector3D choosenBaseAxis(const QVector3D &layoutDirection);
void saveAsObj(const char *filename, const std::vector<QVector3D> &vertices, void saveAsObj(const char *filename, const std::vector<QVector3D> &vertices,
const std::vector<std::vector<size_t>> &faces); const std::vector<std::vector<size_t>> &faces);
bool intersectSegmentAndPlane(const QVector3D &segmentPoint0, const QVector3D &segmentPoint1,
const QVector3D &pointOnPlane, const QVector3D &planeNormal,
QVector3D *intersection=nullptr);
bool intersectSegmentAndTriangle(const QVector3D &segmentPoint0, const QVector3D &segmentPoint1,
const std::vector<QVector3D> &triangle,
const QVector3D &triangleNormal,
QVector3D *intersection=nullptr);
bool intersectRayAndPolyhedron(const QVector3D &rayNear,
const QVector3D &rayFar,
const std::vector<QVector3D> &vertices,
const std::vector<std::vector<size_t>> &triangles,
const std::vector<QVector3D> &triangleNormals,
QVector3D *intersection=nullptr);
#endif #endif

227
src/vertexcolorpainter.cpp Normal file
View File

@ -0,0 +1,227 @@
#include <QDebug>
#include <QQuaternion>
#include <QRadialGradient>
#include <QBrush>
#include <QPainter>
#include <QGuiApplication>
#include "vertexcolorpainter.h"
#include "util.h"
#include "imageforever.h"
const int VertexColorPainter::m_gridSize = 4096;
PaintColor operator+(const PaintColor &first, const PaintColor &second)
{
float total = first.alphaF() + second.alphaF();
if (qFuzzyIsNull(total))
return PaintColor(255, 255, 255, 255);
float remaining = second.alphaF() / total;
float rate = 1.0 - remaining;
PaintColor color(first.red() * rate + second.red() * remaining,
first.green() * rate + second.green() * remaining,
first.blue() * rate + second.blue() * remaining);
color.metalness = first.metalness * rate + second.metalness * remaining;
color.roughness = first.roughness * rate + second.roughness * remaining;
return color;
}
PaintColor operator-(const PaintColor &first, const PaintColor &second)
{
PaintColor color = first;
color.setAlphaF(std::max(color.alphaF() - second.alphaF(), 0.0));
return color;
}
VertexColorPainter::VertexColorPainter(const Outcome &m_outcome, const QVector3D &mouseRayNear, const QVector3D &mouseRayFar) :
m_outcome(m_outcome),
m_mouseRayNear(mouseRayNear),
m_mouseRayFar(mouseRayFar)
{
}
Model *VertexColorPainter::takePaintedModel()
{
Model *paintedModel = m_model;
m_model = nullptr;
return paintedModel;
}
void VertexColorPainter::setVoxelGrid(VoxelGrid<PaintColor> *voxelGrid)
{
m_voxelGrid = voxelGrid;
m_voxelGrid->setNullValue(PaintColor(255, 255, 255, 255));
}
void VertexColorPainter::setPaintMode(PaintMode paintMode)
{
m_paintMode = paintMode;
}
void VertexColorPainter::setMaskNodeIds(const std::set<QUuid> &nodeIds)
{
m_mousePickMaskNodeIds = nodeIds;
}
void VertexColorPainter::setRadius(float radius)
{
m_radius = radius;
}
void VertexColorPainter::setBrushColor(const QColor &color)
{
m_brushColor = color;
}
void VertexColorPainter::setBrushMetalness(float value)
{
m_brushMetalness = value;
}
void VertexColorPainter::setBrushRoughness(float value)
{
m_brushRoughness = value;
}
VertexColorPainter::~VertexColorPainter()
{
delete m_model;
}
bool VertexColorPainter::calculateMouseModelPosition(QVector3D &mouseModelPosition)
{
return intersectRayAndPolyhedron(m_mouseRayNear,
m_mouseRayFar,
m_outcome.vertices,
m_outcome.triangles,
m_outcome.triangleNormals,
&mouseModelPosition);
}
void VertexColorPainter::paintToVoxelGrid()
{
int voxelX = toVoxelLength(m_targetPosition.x());
int voxelY = toVoxelLength(m_targetPosition.y());
int voxelZ = toVoxelLength(m_targetPosition.z());
int voxelRadius = toVoxelLength(m_radius);
int range2 = voxelRadius * voxelRadius;
PaintColor paintColor(m_brushColor);
paintColor.metalness = m_brushMetalness;
paintColor.roughness = m_brushRoughness;
m_voxelGrid->add(voxelX, voxelY, voxelZ, paintColor);
for (int i = -voxelRadius; i <= voxelRadius; ++i) {
qint8 x = voxelX + i;
int i2 = i * i;
for (int j = -voxelRadius; j <= voxelRadius; ++j) {
qint8 y = voxelY + j;
int j2 = j * j;
for (int k = -voxelRadius; k <= voxelRadius; ++k) {
qint8 z = voxelZ + k;
int k2 = k * k;
int dist2 = i2 + j2 + k2;
if (dist2 <= range2) {
int dist = std::sqrt(dist2);
float alpha = 1.0 - (float)dist / voxelRadius;
qDebug() << "alpha:" << alpha;
PaintColor color = paintColor;
color.setAlphaF(alpha);
m_voxelGrid->add(x, y, z, color);
}
}
}
}
}
void VertexColorPainter::createPaintedModel()
{
std::vector<PaintColor> vertexColors(m_outcome.vertices.size());
for (size_t i = 0; i < m_outcome.vertices.size(); ++i) {
const auto &position = m_outcome.vertices[i];
int voxelX = toVoxelLength(position.x());
int voxelY = toVoxelLength(position.y());
int voxelZ = toVoxelLength(position.z());
vertexColors[i] = m_voxelGrid->query(voxelX, voxelY, voxelZ);
}
int triangleVertexCount = m_outcome.triangles.size() * 3;
ShaderVertex *triangleVertices = new ShaderVertex[triangleVertexCount];
int destIndex = 0;
const auto triangleVertexNormals = m_outcome.triangleVertexNormals();
const auto triangleVertexUvs = m_outcome.triangleVertexUvs();
const auto triangleTangents = m_outcome.triangleTangents();
const QVector3D defaultNormal = QVector3D(0, 0, 0);
const QVector2D defaultUv = QVector2D(0, 0);
const QVector3D defaultTangent = QVector3D(0, 0, 0);
for (size_t i = 0; i < m_outcome.triangles.size(); ++i) {
for (auto j = 0; j < 3; j++) {
int vertexIndex = m_outcome.triangles[i][j];
const auto &vertexColor = &vertexColors[vertexIndex];
const QVector3D *srcVert = &m_outcome.vertices[vertexIndex];
const QVector3D *srcNormal = &defaultNormal;
if (triangleVertexNormals)
srcNormal = &(*triangleVertexNormals)[i][j];
const QVector2D *srcUv = &defaultUv;
if (triangleVertexUvs)
srcUv = &(*triangleVertexUvs)[i][j];
const QVector3D *srcTangent = &defaultTangent;
if (triangleTangents)
srcTangent = &(*triangleTangents)[i];
ShaderVertex *dest = &triangleVertices[destIndex];
dest->colorR = vertexColor->redF();
dest->colorG = vertexColor->greenF();
dest->colorB = vertexColor->blueF();
dest->alpha = vertexColor->alphaF();
dest->posX = srcVert->x();
dest->posY = srcVert->y();
dest->posZ = srcVert->z();
dest->texU = srcUv->x();
dest->texV = srcUv->y();
dest->normX = srcNormal->x();
dest->normY = srcNormal->y();
dest->normZ = srcNormal->z();
dest->metalness = vertexColor->metalness;
dest->roughness = vertexColor->roughness;
dest->tangentX = srcTangent->x();
dest->tangentY = srcTangent->y();
dest->tangentZ = srcTangent->z();
destIndex++;
}
}
m_model = new Model(triangleVertices, triangleVertexCount);
}
int VertexColorPainter::toVoxelLength(float length)
{
int voxelLength = length * 100;
if (voxelLength > m_gridSize)
voxelLength = m_gridSize;
else if (voxelLength < -m_gridSize)
voxelLength = -m_gridSize;
return voxelLength;
}
void VertexColorPainter::paint()
{
if (!calculateMouseModelPosition(m_targetPosition))
return;
if (PaintMode::None == m_paintMode)
return;
if (nullptr == m_voxelGrid)
return;
paintToVoxelGrid();
createPaintedModel();
}
void VertexColorPainter::process()
{
paint();
emit finished();
}
const QVector3D &VertexColorPainter::targetPosition()
{
return m_targetPosition;
}

81
src/vertexcolorpainter.h Normal file
View File

@ -0,0 +1,81 @@
#ifndef DUST3D_VERTEX_COLOR_PAINTER_H
#define DUST3D_VERTEX_COLOR_PAINTER_H
#include <QObject>
#include <QVector3D>
#include <vector>
#include <map>
#include <set>
#include <QColor>
#include "outcome.h"
#include "paintmode.h"
#include "voxelgrid.h"
#include "model.h"
class PaintColor : public QColor
{
public:
float metalness = Model::m_defaultMetalness;
float roughness = Model::m_defaultRoughness;
PaintColor() :
QColor()
{
}
PaintColor(int r, int g, int b, int a = 255) :
QColor(r, g, b, a)
{
}
PaintColor(const QColor &color) :
QColor(color)
{
}
};
PaintColor operator+(const PaintColor &first, const PaintColor &second);
PaintColor operator-(const PaintColor &first, const PaintColor &second);
class VertexColorPainter : public QObject
{
Q_OBJECT
public:
VertexColorPainter(const Outcome &outcome, const QVector3D &mouseRayNear, const QVector3D &mouseRayFar);
void setRadius(float radius);
void setBrushColor(const QColor &color);
void setBrushMetalness(float value);
void setBrushRoughness(float value);
void setPaintMode(PaintMode paintMode);
void setMaskNodeIds(const std::set<QUuid> &nodeIds);
void setVoxelGrid(VoxelGrid<PaintColor> *voxelGrid);
~VertexColorPainter();
Model *takePaintedModel();
const QVector3D &targetPosition();
signals:
void finished();
public slots:
void process();
void paint();
private:
float m_radius = 0.0;
PaintMode m_paintMode = PaintMode::None;
std::set<QUuid> m_mousePickMaskNodeIds;
Outcome m_outcome;
QVector3D m_mouseRayNear;
QVector3D m_mouseRayFar;
QVector3D m_targetPosition;
QColor m_brushColor;
float m_brushMetalness = Model::m_defaultMetalness;
float m_brushRoughness = Model::m_defaultRoughness;
VoxelGrid<PaintColor> *m_voxelGrid = nullptr;
Model *m_model = nullptr;
bool calculateMouseModelPosition(QVector3D &mouseModelPosition);
void paintToVoxelGrid();
int toVoxelLength(float length);
void createPaintedModel();
public:
static const int m_gridSize;
};
#endif

1
src/voxelgrid.cpp Normal file
View File

@ -0,0 +1 @@
#include "voxelgrid.h"

85
src/voxelgrid.h Normal file
View File

@ -0,0 +1,85 @@
#ifndef DUST3D_VOXEL_GRID_H
#define DUST3D_VOXEL_GRID_H
#include <QtGlobal>
#include <unordered_map>
template<typename T>
class VoxelGrid
{
public:
struct Voxel
{
qint16 x;
qint16 y;
qint16 z;
};
struct VoxelHash
{
size_t operator()(const Voxel &voxel) const
{
return ((size_t)voxel.x ^ ((size_t)voxel.y << 1)) ^ (size_t)voxel.z;
}
};
struct VoxelEqual
{
bool operator()(const Voxel &left, const Voxel &right) const
{
return (left.x == right.x) &&
(left.y == right.y) &&
(left.z == right.z);
}
};
T query(qint16 x, qint16 y, qint16 z)
{
auto findResult = m_grid.find({x, y, z});
if (findResult == m_grid.end())
return m_nullValue;
return findResult->second;
}
T add(qint16 x, qint16 y, qint16 z, T value)
{
auto insertResult = m_grid.insert(std::make_pair(Voxel {x, y, z}, value));
if (insertResult.second) {
insertResult.first->second = m_nullValue + value;
return insertResult.first->second;
}
insertResult.first->second = insertResult.first->second + value;
return insertResult.first->second;
}
T sub(qint16 x, qint16 y, qint16 z, T value)
{
auto findResult = m_grid.find({x, y, z});
if (findResult == m_grid.end())
return m_nullValue;
findResult->second = findResult->second - value;
if (findResult->second == m_nullValue) {
m_grid.erase(findResult);
return m_nullValue;
}
return findResult->second;
}
void reset(qint16 x, qint16 y, qint16 z)
{
auto findResult = m_grid.find({x, y, z});
if (findResult == m_grid.end())
return;
m_grid.erase(findResult);
}
void setNullValue(const T &nullValue)
{
m_nullValue = nullValue;
}
private:
std::unordered_map<Voxel, T, VoxelHash, VoxelEqual> m_grid;
T m_nullValue = T();
};
#endif

View File

@ -0,0 +1 @@
build/

View File

@ -0,0 +1,171 @@
#
# Copyright (C) 2013-2020 Mattia Basaglia
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
cmake_minimum_required (VERSION 3.1 FATAL_ERROR)
set(COLORWIDGET_PROJECT_NAME QtColorWidgets)
project(${COLORWIDGET_PROJECT_NAME} CXX)
set (CMAKE_MODULE_PATH
${CMAKE_MODULE_PATH}
${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules
${CMAKE_CURRENT_LIST_DIR})
include (CheckCXXCompilerFlag)
include (cmake/install.cmake)
include (cmake/qt-configuration.cmake)
include (cmake/versioning.cmake)
SET (${COLORWIDGET_PROJECT_NAME}_VERSION_MAJOR 2)
SET (${COLORWIDGET_PROJECT_NAME}_VERSION_MINOR 1)
SET (${COLORWIDGET_PROJECT_NAME}_VERSION_PATCH 0)
SET (${COLORWIDGET_PROJECT_NAME}_VERSION "${${COLORWIDGET_PROJECT_NAME}_VERSION_MAJOR}.${${COLORWIDGET_PROJECT_NAME}_VERSION_MINOR}.${${COLORWIDGET_PROJECT_NAME}_VERSION_PATCH}")
set (QT_SUPPORTED_VERSIONS 5)
select_qt (
QT_SUPPORTED_VERSIONS "${QT_SUPPORTED_VERSIONS}"
QT_DEFAULT_VERSION 5)
set (REQUIRED_QT_COMPONENTS
Widgets
)
find_qt (
QT_SUPPORTED_VERSIONS "${QT_SUPPORTED_VERSIONS}"
REQUIRED_COMPONENTS "${REQUIRED_QT_COMPONENTS}"
OPTIONAL_COMPONENTS "")
# Auto generate moc files
set(CMAKE_AUTOMOC ON)
# Auto generate moc files
set(CMAKE_AUTOUIC ON)
# Auto generate moc files
set(CMAKE_AUTORCC ON)
option(BUILD_SHARED_LIBS "Build the shared library" ON)
option(BUILD_STATIC_LIBS "Build the static library" OFF)
set (TARGET_NAME ${COLORWIDGET_PROJECT_NAME})
set (TARGET_OUTPUT_SUFFIX "-Qt${QT_VERSION}${${COLORWIDGET_PROJECT_NAME}_VERSION_MAJOR}")
set (INCLUDE_PREFIX "QtColorWidgets")
set (COLOR_WIDGETS_LIBRARY "${TARGET_NAME}")
if ( ${BUILD_STATIC_LIBS} )
add_definitions(-DQTCOLORWIDGETS_STATICALLY_LINKED)
endif()
add_library (${TARGET_NAME} "")
set_target_properties(${TARGET_NAME}
PROPERTIES
EXPORT_NAME "${TARGET_NAME}${TARGET_OUTPUT_SUFFIX}")
set_target_properties (${TARGET_NAME}
PROPERTIES
CXX_STANDARD 11
CXX_STANDARD_REQUIRED ON
VERSION ${${COLORWIDGET_PROJECT_NAME}_VERSION}
SOVERSION ${${COLORWIDGET_PROJECT_NAME}_VERSION_MAJOR}
"INTERFACE_${COLORWIDGET_PROJECT_NAME}_MAJOR_VERSION" ${${COLORWIDGET_PROJECT_NAME}_VERSION_MAJOR}
COMPATIBLE_INTERFACE_STRING "${COLORWIDGET_PROJECT_NAME}_MAJOR_VERSION"
COMPILE_DEFINITIONS QTCOLORWIDGETS_LIBRARY
OUTPUT_NAME "${TARGET_NAME}${TARGET_OUTPUT_SUFFIX}")
check_cxx_compiler_flag ("-Wall" Wall_FLAG_SUPPORTED)
if (Wall_FLAG_SUPPORTED)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall")
endif (Wall_FLAG_SUPPORTED)
check_cxx_compiler_flag ("-pedantic" pedantic_FLAG_SUPPORTED)
if (pedantic_FLAG_SUPPORTED)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pedantic")
endif (pedantic_FLAG_SUPPORTED)
check_cxx_compiler_flag ("-Wextra" Wextra_FLAG_SUPPORTED)
if (Wextra_FLAG_SUPPORTED)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wextra")
endif (Wextra_FLAG_SUPPORTED)
set (EXPORT_HEADER "${INCLUDE_PREFIX}/colorwidgets_global.hpp")
generate_versioning_information (
TARGET_NAME ${TARGET_NAME}
EXPORT_HEADER ${EXPORT_HEADER}
EXPORT_MACRO QCP_EXPORT
VERSIONED_ENTITY ${COLORWIDGET_PROJECT_NAME}
INCLUDE_PREFIX ${INCLUDE_PREFIX}
COMPANY_NAME "Mattia Basaglia"
COMPANY_COPYRIGHT "Mattia Basaglia Copyright (C) 2013-2017"
FILE_DESCRIPTION "Color wheel widget and dialog for Qt${QT_VERSION}"
)
target_include_directories(${TARGET_NAME}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PUBLIC
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>
$<INSTALL_INTERFACE:include>
)
add_subdirectory (${CMAKE_CURRENT_SOURCE_DIR}/include/${INCLUDE_PREFIX})
add_subdirectory (${CMAKE_CURRENT_SOURCE_DIR}/resources/${INCLUDE_PREFIX})
add_subdirectory (${CMAKE_CURRENT_SOURCE_DIR}/src/${INCLUDE_PREFIX})
use_qt (
TARGET_NAME ${TARGET_NAME}
QT_SUPPORTED_VERSIONS "${QT_SUPPORTED_VERSIONS}"
REQUIRED_COMPONENTS "${REQUIRED_QT_COMPONENTS}"
OPTIONAL_COMPONENTS "")
install_project (
PROJECT_NAME ${COLORWIDGET_PROJECT_NAME}
TARGET_NAME ${TARGET_NAME}
TARGET_OUTPUT_SUFFIX ${TARGET_OUTPUT_SUFFIX}
EXPORT_HEADER ${EXPORT_HEADER}
INCLUDE_PREFIX ${INCLUDE_PREFIX}
HEADER_MATCHING_REGEX "^.*\.h$|^.*\.hpp$|^.*$"
VERSION_HEADER ${CMAKE_CURRENT_BINARY_DIR}/${COLORWIDGET_PROJECT_NAME}_version.h
NAMESPACE "")
add_subdirectory (gallery)
option(QTCOLORWIDGETS_DESIGNER_PLUGIN "Build QtDesigner plugin" ON)
if (${QTCOLORWIDGETS_DESIGNER_PLUGIN})
find_package (Qt5Designer QUIET)
if (Qt5Designer_FOUND)
add_subdirectory (color_widgets_designer_plugin)
endif(Qt5Designer_FOUND)
endif()

165
thirdparty/Qt-Color-Widgets/COPYING vendored Normal file
View File

@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,14 @@
Linking this library statically or dynamically with other modules is making a
combined work based on this library. Thus, the terms and conditions of the
GNU Lesser General Public License version 3 cover the whole combination.
As a special exception, the copyright holders of this library give you
permission to combine this library with independent
modules to produce an executable, and to copy and distribute the resulting
executable under terms of any of the GNU General Public licenses, as published
by the Free Software Foundation, provided that you also meet,
for each linked independent module, the terms and conditions of the license of
that module. An independent module is a module which is not derived from or
based on this library. If you modify this library, you may extend this
exception to your version of the library, but you are not obliged to do so.
If you do not wish to do so, delete this exception statement from your version.

View File

@ -0,0 +1,10 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
libdir=@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/include
Name: QtColorWidgets
Description: Color wheel widget and dialog for Qt
Version: @QtColorWidgets_VERSION@
Libs: -L${libdir} -l@i_target_name@@i_target_output_suffix@
Cflags: -I${includedir}/@i_project_name@ -I${includedir}

66
thirdparty/Qt-Color-Widgets/README.md vendored Normal file
View File

@ -0,0 +1,66 @@
Color Widgets
=============
Here is a color dialog that is more user-friendly than the default QColorDialog
and several other color-related widgets
The provided widgets are:
* ColorWheel, An analog widget used to select a color
* ColorPreview, A simple widget that displays a color
* GradientSlider, A slider that has a gradient background
* HueSlider, A variant of GradientSlider that has a rainbow background
* ColorSelector, A ColorPreview that shows a ColorDialog when clicked
* ColorDialog, A dialog that uses the above widgets to provide a better user experience than QColorDialog
* ColorListWidget, A widget to edit a list of colors
* Swatch, A widget to display a color palette
* ColorPaletteWidget, A widget to use and manage a list of palettes
* Color2DSlider, An analog widget used to select 2 color components
* ColorLineEdit, A widget to manipulate a string representing a color
* HarmonyColorWheel, A ColorWheel which allows defining multiple colors, separated by hue
* GradientListModel, A QAbstractListModel used to list gradients (useful for combo boxes, list views and the like)
they are all in the color_widgets namespace.
See [the gallery](gallery/README.md) for more information and screenshots.
Using it in a project
---------------------
For QMake-based projects, include color_widgets.pri in the QMake project file.
For CMake-based projects, add this as subdirectory, it will be compiled as a
library and you can link the required targets to ColorWidgets.
All the required files are in ./src and ./include.
Installing as a Qt Designer/Creator Plugin
------------------------------------------
The sources for the designer plugin are in ./color_widgets_designer_plugin
Compile the library and install in
(Qt SDK)/Tools/QtCreator/bin/designer/
(Qt SDK)/(Qt Version)/(Toolchain)/plugins/designer
mkdir build && cd build && cmake .. && make QtColorWidgetsPlugin && make install
Latest Version
--------------
The latest version of the sources can be found at the following locations:
* https://gitlab.com/mattia.basaglia/Qt-Color-Widgets
* git://gitlab.com/mattia.basaglia/Qt-Color-Widgets.git
License
-------
LGPLv3+, See COPYING.
As a special exception, this library can be included in any project under the
terms of any of the GNU liceses, distributing the whole project under a
different GNU license, see LICENSE-EXCEPTION for details.
Copyright (C) 2013-2020 Mattia Basaglia <dev@dragon.best>

View File

@ -0,0 +1 @@
include("${CMAKE_CURRENT_LIST_DIR}/@CMAKE_BASE_FILE_NAME@@CMAKE_FILE_OUTPUT_SUFFIX@-targets.cmake")

View File

@ -0,0 +1,88 @@
function (install_project
PROJECT_NAME i_project_name
TARGET_NAME i_target_name
TARGET_OUTPUT_SUFFIX i_target_output_suffix
EXPORT_HEADER i_export_header
INCLUDE_PREFIX i_include_prefix
HEADER_MATCHING_REGEX i_header_matching_regex
VERSION_HEADER i_version_header
NAMESPACE i_namespace)
install (TARGETS ${i_target_name}
EXPORT ${i_target_name}
RUNTIME DESTINATION bin
INCLUDES DESTINATION include
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib)
install (DIRECTORY include/
DESTINATION include
FILES_MATCHING
REGEX ${i_header_matching_regex}
REGEX "CMakeLists\.txt" EXCLUDE)
install (FILES ${i_version_header}
DESTINATION include/${i_include_prefix}
COMPONENT Devel)
install (FILES include/${i_export_header}
DESTINATION include/${i_include_prefix}
COMPONENT Devel)
install(
EXPORT ${i_target_name}
DESTINATION lib/cmake/${i_target_name}${i_target_output_suffix}
FILE "${i_target_name}${i_target_output_suffix}.cmake"
COMPONENT Devel)
include(CMakePackageConfigHelpers)
string (TOLOWER ${i_target_name} CMAKE_BASE_FILE_NAME)
string (TOLOWER ${i_target_output_suffix} CMAKE_FILE_OUTPUT_SUFFIX)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/${i_target_name}/${CMAKE_BASE_FILE_NAME}${CMAKE_FILE_OUTPUT_SUFFIX}-config-version.cmake"
VERSION ${${i_project_name}_VERSION}
COMPATIBILITY SameMajorVersion
)
export(EXPORT ${i_target_name}
FILE "${CMAKE_CURRENT_BINARY_DIR}/${i_target_name}/${CMAKE_BASE_FILE_NAME}${CMAKE_FILE_OUTPUT_SUFFIX}-targets.cmake"
)
configure_file("cmake/${i_project_name}-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${i_target_name}/${CMAKE_BASE_FILE_NAME}${CMAKE_FILE_OUTPUT_SUFFIX}-config.cmake"
@ONLY
)
set(ConfigPackageLocation "lib/cmake/${i_target_name}${i_target_output_suffix}")
install(EXPORT ${i_target_name}
FILE
"${CMAKE_BASE_FILE_NAME}${CMAKE_FILE_OUTPUT_SUFFIX}-targets.cmake"
NAMESPACE
"${i_namespace}"
DESTINATION
${ConfigPackageLocation}
)
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/${i_target_name}/${CMAKE_BASE_FILE_NAME}${CMAKE_FILE_OUTPUT_SUFFIX}-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${i_target_name}/${CMAKE_BASE_FILE_NAME}${CMAKE_FILE_OUTPUT_SUFFIX}-config-version.cmake"
DESTINATION
${ConfigPackageLocation}
COMPONENT
Devel
)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/${i_project_name}.pc.in
${CMAKE_CURRENT_BINARY_DIR}/${i_target_name}${i_target_output_suffix}.pc
@ONLY
)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/${i_target_name}${i_target_output_suffix}.pc
DESTINATION
lib/pkgconfig
)
endfunction (install_project)

View File

@ -0,0 +1,80 @@
define_property (TARGET
PROPERTY GIT_DESCRIBE
BRIEF_DOCS "Advanced version info for developers"
FULL_DOCS "String with information that is important for developers during
development process. This information includes git commit hash, durty status
of repo, distance from the last tag.")
define_property (TARGET
PROPERTY GIT_UNTRACKED_FILES
BRIEF_DOCS "Information about presence of untracked files"
FULL_DOCS "Used in helper functions generation to add .with-untracked suffix
to version string. Suffix is only added if there are some untracked not
ignored files in repository.")
set(HERE_DIR ${CMAKE_CURRENT_LIST_DIR})
function (target_version_information
TARGET_NAME i_target_name
EXPORT_HEADER i_export_header
EXPORT_MACRO i_export_macro
VERSIONED_ENTITY i_versioned_entity)
find_file (
headerFileTemplate
"ProjectVersioning/version.h.in"
PATHS ${CMAKE_MODULE_PATH})
if ( NOT ${headerFileTemplate} )
set(headerFileTemplate "${HERE_DIR}/ProjectVersioning/version.h.in")
endif()
find_file (
sourceFileTemplate
"ProjectVersioning/version.c.in"
PATHS ${CMAKE_MODULE_PATH})
if ( NOT ${sourceFileTemplate} )
set(sourceFileTemplate "${HERE_DIR}/ProjectVersioning/version.c.in")
endif()
exec_program (
"git"
${CMAKE_SOURCE_DIR}
ARGS "describe --always --dirty --long --tags"
OUTPUT_VARIABLE gitDescribe)
exec_program (
"git"
${CMAKE_SOURCE_DIR}
ARGS "ls-files --others --exclude-standard"
OUTPUT_VARIABLE gitUntracked)
if (gitUntracked)
set (gitUntracked ".with-untracked")
endif (gitUntracked)
configure_file (
"${headerFileTemplate}"
"${CMAKE_CURRENT_BINARY_DIR}/${i_versioned_entity}_version.h")
configure_file(
"${sourceFileTemplate}"
"${CMAKE_BINARY_DIR}/${i_versioned_entity}_version.c")
target_sources ("${i_target_name}"
PRIVATE
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/${i_versioned_entity}_version.h>
$<INSTALL_INTERFACE:include/${i_include_prefix}/${i_versioned_entity}_version.h>
PRIVATE
"${CMAKE_BINARY_DIR}/${i_versioned_entity}_version.c")
set_target_properties (${i_target_name}
PROPERTIES
GIT_DESCRIBE "${gitDescribe}"
GIT_UNTRACKED_FILES "${gitUntracked}")
unset (headerFileTemplate PARENT_SCOPE)
unset (sourceFileTemplate PARENT_SCOPE)
endfunction (target_version_information)

View File

@ -0,0 +1,34 @@
#include "${i_versioned_entity}_version.h"
unsigned int @i_versioned_entity@_versionMajor () {
return ${${i_versioned_entity}_VERSION_MAJOR};
}
unsigned int @i_versioned_entity@_versionMinor () {
return ${${i_versioned_entity}_VERSION_MINOR};
}
unsigned int @i_versioned_entity@_versionPatch () {
return ${${i_versioned_entity}_VERSION_PATCH};
}
const char* @i_versioned_entity@_versionGitInfo () {
return
"${gitDescribe}"
"${gitUntracked}";
}
const char* @i_versioned_entity@_versionFullString () {
return
"${${i_versioned_entity}_VERSION_MAJOR}."
"${${i_versioned_entity}_VERSION_MINOR}."
"${${i_versioned_entity}_VERSION_PATCH}"
"${${i_versioned_entity}_VERSION_PRE_RELEASE}"
"+${gitDescribe}"
"${gitUntracked}";
}

View File

@ -0,0 +1,23 @@
#ifndef @CMAKE_PROJECT_NAME@_VERSION_H
#define @CMAKE_PROJECT_NAME@_VERSION_H
#include "@i_export_header@"
@i_export_macro@ unsigned int @i_versioned_entity@_versionMajor ();
@i_export_macro@ unsigned int @i_versioned_entity@_versionMinor ();
@i_export_macro@ unsigned int @i_versioned_entity@_versionPatch ();
@i_export_macro@ const char* @i_versioned_entity@_versionGitInfo ();
@i_export_macro@ const char* @i_versioned_entity@_versionFullString ();
#endif /* @CMAKE_PROJECT_NAME@_VERSION_H */

View File

@ -0,0 +1,113 @@
/*
The MIT License (MIT)
Copyright (c) 2015, by [halex2005](mailto:akharlov@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#pragma once
#ifndef PRODUCT_VERSION_MAJOR
#define PRODUCT_VERSION_MAJOR @PRODUCT_VERSION_MAJOR@
#endif
#ifndef PRODUCT_VERSION_MINOR
#define PRODUCT_VERSION_MINOR @PRODUCT_VERSION_MINOR@
#endif
#ifndef PRODUCT_VERSION_PATCH
#define PRODUCT_VERSION_PATCH @PRODUCT_VERSION_PATCH@
#endif
#ifndef PRODUCT_VERSION_BUILD
#define PRODUCT_VERSION_BUILD @PRODUCT_VERSION_REVISION@
#endif
#ifndef FILE_VERSION_MAJOR
#define FILE_VERSION_MAJOR @PRODUCT_VERSION_MAJOR@
#endif
#ifndef FILE_VERSION_MINOR
#define FILE_VERSION_MINOR @PRODUCT_VERSION_MINOR@
#endif
#ifndef FILE_VERSION_PATCH
#define FILE_VERSION_PATCH @PRODUCT_VERSION_PATCH@
#endif
#ifndef FILE_VERSION_BUILD
#define FILE_VERSION_BUILD @PRODUCT_VERSION_REVISION@
#endif
#ifndef __TO_STRING
#define __TO_STRING_IMPL(x) #x
#define __TO_STRING(x) __TO_STRING_IMPL(x)
#endif
#define PRODUCT_VERSION_MAJOR_MINOR_STR __TO_STRING(PRODUCT_VERSION_MAJOR) "." __TO_STRING(PRODUCT_VERSION_MINOR)
#define PRODUCT_VERSION_MAJOR_MINOR_PATCH_STR PRODUCT_VERSION_MAJOR_MINOR_STR "." __TO_STRING(PRODUCT_VERSION_PATCH)
#define PRODUCT_VERSION_FULL_STR PRODUCT_VERSION_MAJOR_MINOR_PATCH_STR "." __TO_STRING(PRODUCT_VERSION_BUILD)
#define PRODUCT_VERSION_RESOURCE PRODUCT_VERSION_MAJOR,PRODUCT_VERSION_MINOR,PRODUCT_VERSION_PATCH,PRODUCT_VERSION_BUILD
#define PRODUCT_VERSION_RESOURCE_STR PRODUCT_VERSION_FULL_STR "\0"
#define FILE_VERSION_MAJOR_MINOR_STR __TO_STRING(FILE_VERSION_MAJOR) "." __TO_STRING(FILE_VERSION_MINOR)
#define FILE_VERSION_MAJOR_MINOR_PATCH_STR FILE_VERSION_MAJOR_MINOR_STR "." __TO_STRING(FILE_VERSION_PATCH)
#define FILE_VERSION_FULL_STR FILE_VERSION_MAJOR_MINOR_PATCH_STR "." __TO_STRING(FILE_VERSION_BUILD)
#define FILE_VERSION_RESOURCE FILE_VERSION_MAJOR,FILE_VERSION_MINOR,FILE_VERSION_PATCH,FILE_VERSION_BUILD
#define FILE_VERSION_RESOURCE_STR FILE_VERSION_FULL_STR "\0"
#ifndef USE_ICON
#define USE_ICON @USE_ICON@
#endif
#if USE_ICON
#ifndef PRODUCT_ICON
#define PRODUCT_ICON "@PRODUCT_ICON@"
#endif
#endif
#ifndef PRODUCT_COMMENTS
#define PRODUCT_COMMENTS "@PRODUCT_COMMENTS@\0"
#endif
#ifndef PRODUCT_COMPANY_NAME
#define PRODUCT_COMPANY_NAME "@PRODUCT_COMPANY_NAME@\0"
#endif
#ifndef PRODUCT_COMPANY_COPYRIGHT
#define PRODUCT_COMPANY_COPYRIGHT "@PRODUCT_COMPANY_COPYRIGHT@\0"
#endif
#ifndef PRODUCT_FILE_DESCRIPTION
#define PRODUCT_FILE_DESCRIPTION "@PRODUCT_FILE_DESCRIPTION@\0"
#endif
#ifndef PRODUCT_INTERNAL_NAME
#define PRODUCT_INTERNAL_NAME "@PRODUCT_NAME@\0"
#endif
#ifndef PRODUCT_ORIGINAL_FILENAME
#define PRODUCT_ORIGINAL_FILENAME "@PRODUCT_ORIGINAL_FILENAME@\0"
#endif
#ifndef PRODUCT_BUNDLE
#define PRODUCT_BUNDLE "@PRODUCT_BUNDLE@\0"
#endif

View File

@ -0,0 +1,66 @@
/*
The MIT License (MIT)
Copyright (c) 2015, by [halex2005](mailto:akharlov@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "VersionInfo.h"
#include "winresrc.h"
#if USE_ICON
IDI_ICON1 ICON PRODUCT_ICON
#endif
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
VS_VERSION_INFO VERSIONINFO
FILEVERSION FILE_VERSION_RESOURCE
PRODUCTVERSION PRODUCT_VERSION_RESOURCE
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "041904b0"
BEGIN
VALUE "Comments", PRODUCT_COMMENTS
VALUE "CompanyName", PRODUCT_COMPANY_NAME
VALUE "FileDescription", PRODUCT_FILE_DESCRIPTION
VALUE "FileVersion", FILE_VERSION_RESOURCE_STR
VALUE "InternalName", PRODUCT_INTERNAL_NAME
VALUE "LegalCopyright", PRODUCT_COMPANY_COPYRIGHT
VALUE "OriginalFilename", PRODUCT_ORIGINAL_FILENAME
VALUE "ProductName", PRODUCT_BUNDLE
VALUE "ProductVersion", PRODUCT_VERSION_RESOURCE_STR
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x419, 1200
END
END

View File

@ -0,0 +1,136 @@
# The MIT License (MIT)
# Copyright (c) 2015, by [halex2005](mailto:akharlov@gmail.com)
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
include (CMakeParseArguments)
set (GenerateProductVersionCurrentDir ${CMAKE_CURRENT_LIST_DIR})
# generate_product_version() function
#
# This function uses VersionInfo.in template file and VersionResource.rc file
# to generate WIN32 resource with version information and general resource strings.
#
# Usage:
# generate_product_version(
# SomeOutputResourceVariable
# NAME MyGreatProject
# ICON ${PATH_TO_APP_ICON}
# VERSION_MAJOR 2
# VERSION_MINOR 3
# VERSION_PATH ${BUILD_COUNTER}
# VERSION_REVISION ${BUILD_REVISION}
# )
# where BUILD_COUNTER and BUILD_REVISION could be values from your CI server.
#
# You can use generated resource for your executable targets:
# add_executable(target-name ${target-files} ${SomeOutputResourceVariable})
#
# You can specify resource strings in arguments:
# NAME - name of executable (no defaults, ex: Microsoft Word)
# BUNDLE - bundle (${NAME} is default, ex: Microsoft Office)
# USE_ICON - flag that shows whether icon is used or not
# ICON - path to application icon (${CMAKE_SOURCE_DIR}/product.ico by default)
# VERSION_MAJOR - 1 is default
# VERSION_MINOR - 0 is default
# VERSION_PATCH - 0 is default
# VERSION_REVISION - 0 is default
# COMPANY_NAME - your company name (no defaults)
# COMPANY_COPYRIGHT - ${COMPANY_NAME} (C) Copyright ${CURRENT_YEAR} is default
# COMMENTS - ${NAME} v${VERSION_MAJOR}.${VERSION_MINOR} is default
# ORIGINAL_FILENAME - ${NAME} is default
# INTERNAL_NAME - ${NAME} is default
# FILE_DESCRIPTION - ${NAME} is default
function(generate_product_version outfiles)
set (options)
set (oneValueArgs
NAME
BUNDLE
USE_ICON
ICON
VERSION_MAJOR
VERSION_MINOR
VERSION_PATCH
VERSION_REVISION
COMPANY_NAME
COMPANY_COPYRIGHT
COMMENTS
ORIGINAL_FILENAME
INTERNAL_NAME
FILE_DESCRIPTION)
set (multiValueArgs)
cmake_parse_arguments(PRODUCT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if (NOT PRODUCT_BUNDLE OR "${PRODUCT_BUNDLE}" STREQUAL "")
set(PRODUCT_BUNDLE "${PRODUCT_NAME}")
endif()
if (USE_ICON)
if (NOT PRODUCT_ICON OR "${PRODUCT_ICON}" STREQUAL "")
set(PRODUCT_ICON "${CMAKE_SOURCE_DIR}/product.ico")
endif()
else ()
set (USE_ICON 0)
endif ()
if (NOT PRODUCT_VERSION_MAJOR EQUAL 0 AND (NOT PRODUCT_VERSION_MAJOR OR "${PRODUCT_VERSION_MAJOR}" STREQUAL ""))
set(PRODUCT_VERSION_MAJOR 1)
endif()
if (NOT PRODUCT_VERSION_MINOR EQUAL 0 AND (NOT PRODUCT_VERSION_MINOR OR "${PRODUCT_VERSION_MINOR}" STREQUAL ""))
set(PRODUCT_VERSION_MINOR 0)
endif()
if (NOT PRODUCT_VERSION_PATCH EQUAL 0 AND (NOT PRODUCT_VERSION_PATCH OR "${PRODUCT_VERSION_PATCH}" STREQUAL ""))
set(PRODUCT_VERSION_PATCH 0)
endif()
if (NOT PRODUCT_VERSION_REVISION EQUAL 0 AND (NOT PRODUCT_VERSION_REVISION OR "${PRODUCT_VERSION_REVISION}" STREQUAL ""))
set(PRODUCT_VERSION_REVISION 0)
endif()
if (NOT PRODUCT_COMPANY_COPYRIGHT OR "${PRODUCT_COMPANY_COPYRIGHT}" STREQUAL "")
string(TIMESTAMP PRODUCT_CURRENT_YEAR "%Y")
set(PRODUCT_COMPANY_COPYRIGHT "${PRODUCT_COMPANY_NAME} (C) Copyright ${PRODUCT_CURRENT_YEAR}")
endif()
if (NOT PRODUCT_COMMENTS OR "${PRODUCT_COMMENTS}" STREQUAL "")
set(PRODUCT_COMMENTS "${PRODUCT_NAME} v${PRODUCT_VERSION_MAJOR}.${PRODUCT_VERSION_MINOR}")
endif()
if (NOT PRODUCT_ORIGINAL_FILENAME OR "${PRODUCT_ORIGINAL_FILENAME}" STREQUAL "")
set(PRODUCT_ORIGINAL_FILENAME "${PRODUCT_NAME}")
endif()
if (NOT PRODUCT_INTERNAL_NAME OR "${PRODUCT_INTERNAL_NAME}" STREQUAL "")
set(PRODUCT_INTERNAL_NAME "${PRODUCT_NAME}")
endif()
if (NOT PRODUCT_FILE_DESCRIPTION OR "${PRODUCT_FILE_DESCRIPTION}" STREQUAL "")
set(PRODUCT_FILE_DESCRIPTION "${PRODUCT_NAME}")
endif()
set (_VersionInfoFile ${CMAKE_CURRENT_BINARY_DIR}/VersionInfo.h)
set (_VersionResourceFile ${CMAKE_CURRENT_BINARY_DIR}/VersionResource.rc)
configure_file(
${GenerateProductVersionCurrentDir}/VersionInfo.in
${_VersionInfoFile}
@ONLY)
configure_file(
${GenerateProductVersionCurrentDir}/VersionResource.rc
${_VersionResourceFile}
COPYONLY)
list(APPEND ${outfiles} ${_VersionInfoFile} ${_VersionResourceFile})
set (${outfiles} ${${outfiles}} PARENT_SCOPE)
endfunction()

View File

@ -0,0 +1,58 @@
function (select_qt
QT_SUPPORTED_VERSIONS i_qt_supported_versions
QT_DEFAULT_VERSION i_default_qt_version)
set (QT_VERSION ${i_default_qt_version} CACHE STRING
"Qt version to build against")
set_property (
CACHE QT_VERSION
PROPERTY STRINGS ${i_qt_supported_versions})
endfunction (select_qt)
macro (find_qt
QT_SUPPORTED_VERSIONS i_qt_supported_versions
REQUIRED_COMPONENTS i_required_components
OPTIONAL_COMPONENTS i_optional_components)
# Auto generate moc files
if (4 EQUAL QT_VERSION)
find_package (Qt4 4.8 REQUIRED
COMPONENTS
${i_required_components}
OPTIONAL_COMPONENTS
${i_optional_components})
elseif (5 EQUAL QT_VERSION)
find_package (Qt5 5.9 REQUIRED
COMPONENTS
${i_required_components}
OPTIONAL_COMPONENTS
${i_optional_components})
else (5 EQUAL QT_VERSION)
message (FATAL_ERROR "Unsupported version of Qt: ${QT_VERSION}")
endif (4 EQUAL QT_VERSION)
endmacro (find_qt)
function (use_qt
TARGET_NAME i_target_name
QT_SUPPORTED_VERSIONS i_qt_supported_versions
REQUIRED_COMPONENTS i_required_components
OPTIONAL_COMPONENTS i_optional_components)
if (4 EQUAL QT_VERSION)
foreach (COMPONENT IN LISTS i_required_components, i_optional_components)
target_link_libraries (${i_target_name}
PRIVATE
Qt4::${COMPONENT}
)
endforeach (COMPONENT IN LISTS i_required_components, i_optional_components)
elseif (5 EQUAL QT_VERSION)
foreach (COMPONENT IN LISTS i_required_components)
target_link_libraries (${i_target_name}
PRIVATE
Qt5::${COMPONENT}
)
endforeach (COMPONENT IN LISTS i_required_components, i_optional_components)
else (5 EQUAL QT_VERSION)
message (FATAL_ERROR "Unsupported version of Qt: ${QT_VERSION}")
endif (4 EQUAL QT_VERSION)
endfunction (use_qt)

View File

@ -0,0 +1,43 @@
include (ProjectVersioning)
function (generate_versioning_information
TARGET_NAME i_target_name
EXPORT_HEADER i_export_header
EXPORT_MACRO i_export_macro
VERSIONED_ENTITY i_versioned_entity
INCLUDE_PREFIX i_include_prefix
COMPANY_NAME i_company_name
COMPANY_COPYRIGHT i_company_copyright
FILE_DESCRIPTION i_file_description
)
target_version_information (
TARGET_NAME ${i_target_name}
EXPORT_HEADER ${i_export_header}
EXPORT_MACRO ${i_export_macro}
VERSIONED_ENTITY ${i_versioned_entity}
)
if (WIN32)
include (generate_product_version)
get_target_property (gitDescribe
${i_target_name} GIT_DESCRIBE)
get_target_property (gitUntracked
${i_target_name} GIT_UNTRACKED_FILES)
generate_product_version (
win32VersionInfoFiles
NAME ${i_versioned_entity}
VERSION_MAJOR ${${i_versioned_entity}_VERSION_MAJOR}
VERSION_MINOR ${${i_versioned_entity}_VERSION_MINOR}
VERSION_PATCH ${${i_versioned_entity}_VERSION_PATCH}
COMPANY_NAME ${i_company_name}
COMPANY_COPYRIGHT ${i_company_copyright}
COMMENTS "${gitDescribe}${gitUntracked}"
FILE_DESCRIPTION ${i_file_description}
)
target_sources (${i_target_name} PRIVATE ${win32VersionInfoFiles})
endif (WIN32)
endfunction (generate_versioning_information)

View File

@ -0,0 +1,77 @@
# Copyright (C) 2013-2019 Mattia Basaglia
#
#
# This software is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Color Widgets. If not, see <http://www.gnu.org/licenses/>.
CONFIG += c++11
INCLUDEPATH += $$PWD/src $$PWD/include
SOURCES += \
$$PWD/src/QtColorWidgets/abstract_widget_list.cpp \
$$PWD/src/QtColorWidgets/bound_color_selector.cpp \
$$PWD/src/QtColorWidgets/color_2d_slider.cpp \
$$PWD/src/QtColorWidgets/color_delegate.cpp \
$$PWD/src/QtColorWidgets/color_dialog.cpp \
$$PWD/src/QtColorWidgets/color_line_edit.cpp \
$$PWD/src/QtColorWidgets/color_list_widget.cpp \
$$PWD/src/QtColorWidgets/color_names.cpp \
$$PWD/src/QtColorWidgets/color_palette.cpp \
$$PWD/src/QtColorWidgets/color_palette_model.cpp \
$$PWD/src/QtColorWidgets/color_palette_widget.cpp \
$$PWD/src/QtColorWidgets/color_preview.cpp \
$$PWD/src/QtColorWidgets/color_selector.cpp \
$$PWD/src/QtColorWidgets/color_utils.cpp \
$$PWD/src/QtColorWidgets/color_wheel.cpp \
$$PWD/src/QtColorWidgets/gradient_editor.cpp \
$$PWD/src/QtColorWidgets/gradient_list_model.cpp \
$$PWD/src/QtColorWidgets/gradient_slider.cpp \
$$PWD/src/QtColorWidgets/harmony_color_wheel.cpp \
$$PWD/src/QtColorWidgets/hue_slider.cpp \
$$PWD/src/QtColorWidgets/swatch.cpp
HEADERS += \
$$PWD/include/QtColorWidgets/abstract_widget_list.hpp \
$$PWD/include/QtColorWidgets/bound_color_selector.hpp \
$$PWD/include/QtColorWidgets/color_2d_slider.hpp \
$$PWD/include/QtColorWidgets/color_delegate.hpp \
$$PWD/include/QtColorWidgets/color_dialog.hpp \
$$PWD/include/QtColorWidgets/color_line_edit.hpp \
$$PWD/include/QtColorWidgets/color_list_widget.hpp \
$$PWD/include/QtColorWidgets/color_names.hpp \
$$PWD/include/QtColorWidgets/color_palette.hpp \
$$PWD/include/QtColorWidgets/color_palette_model.hpp \
$$PWD/include/QtColorWidgets/color_palette_widget.hpp \
$$PWD/include/QtColorWidgets/color_preview.hpp \
$$PWD/include/QtColorWidgets/color_selector.hpp \
$$PWD/include/QtColorWidgets/color_utils.hpp \
$$PWD/include/QtColorWidgets/color_wheel.hpp \
$$PWD/include/QtColorWidgets/color_wheel_private.hpp \
$$PWD/include/QtColorWidgets/colorwidgets_global.hpp \
$$PWD/include/QtColorWidgets/gradient_delegate.hpp \
$$PWD/include/QtColorWidgets/gradient_editor.hpp \
$$PWD/include/QtColorWidgets/gradient_helper.hpp \
$$PWD/include/QtColorWidgets/gradient_list_model.hpp \
$$PWD/include/QtColorWidgets/gradient_slider.hpp \
$$PWD/include/QtColorWidgets/harmony_color_wheel.hpp \
$$PWD/include/QtColorWidgets/hue_slider.hpp \
$$PWD/include/QtColorWidgets/swatch.hpp
FORMS += \
$$PWD/src/QtColorWidgets/color_dialog.ui \
$$PWD/src/QtColorWidgets/color_palette_widget.ui
RESOURCES += \
$$PWD/resources/QtColorWidgets/color_widgets.qrc

View File

@ -0,0 +1,53 @@
#
# Copyright (C) 2013-2020 Mattia Basaglia
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
TEMPLATE=lib
CONFIG += dll
QT += core gui widgets
DEFINES += QTCOLORWIDGETS_LIBRARY
TARGET=QtColorWidgets-Qt5
VERSION=2.0.0
OBJECTS_DIR = out/obj
MOC_DIR = out/generated
UI_DIR = out/generated
RCC_DIR = out/generated
include(color_widgets.pri)
build_all:!build_pass {
CONFIG -= build_all
CONFIG += release
}
unix {
LIB_TARGET = lib$${TARGET}.so
}
win32 {
LIB_TARGET = $${TARGET}.dll
}
isEmpty(PREFIX) {
PREFIX = /usr/local
}
target.path = $$PREFIX/lib
headers.path = $$PREFIX/include/QtColorWidgets
headers.files = $$HEADERS
INSTALLS += target headers

View File

@ -0,0 +1,178 @@
# Copyright (C) 2013-2020 Mattia Basaglia
#
#
# This software is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Color Widgets. If not, see <http://www.gnu.org/licenses/>.
cmake_minimum_required (VERSION 3.1 FATAL_ERROR)
project(QtColorWidgetsPlugin CXX)
set (CMAKE_MODULE_PATH
${CMAKE_MODULE_PATH}
${CMAKE_SOURCE_DIR}/cmake/modules
${CMAKE_CURRENT_LIST_DIR}/..)
include (CheckCXXCompilerFlag)
include (../cmake/qt-configuration.cmake)
include (../cmake/versioning.cmake)
SET (${PROJECT_NAME}_VERSION_MAJOR 2)
SET (${PROJECT_NAME}_VERSION_MINOR 0)
SET (${PROJECT_NAME}_VERSION_PATCH 0)
SET (${PROJECT_NAME}_VERSION "${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}.${${PROJECT_NAME}_VERSION_PATCH}")
set (QT_SUPPORTED_VERSIONS 5)
select_qt (
QT_SUPPORTED_VERSIONS "${QT_SUPPORTED_VERSIONS}"
QT_DEFAULT_VERSION 5)
set (REQUIRED_QT_COMPONENTS
Designer
)
find_qt (
QT_SUPPORTED_VERSIONS "${QT_SUPPORTED_VERSIONS}"
REQUIRED_COMPONENTS "${REQUIRED_QT_COMPONENTS}"
OPTIONAL_COMPONENTS "")
# Auto generate moc files
set(CMAKE_AUTOMOC ON)
# Auto generate moc files
set(CMAKE_AUTOUIC ON)
# Auto generate moc files
set(CMAKE_AUTORCC ON)
check_cxx_compiler_flag ("-Wall" Wall_FLAG_SUPPORTED)
if (Wall_FLAG_SUPPORTED)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall")
endif (Wall_FLAG_SUPPORTED)
check_cxx_compiler_flag ("-pedantic" pedantic_FLAG_SUPPORTED)
if (pedantic_FLAG_SUPPORTED)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pedantic")
endif (pedantic_FLAG_SUPPORTED)
check_cxx_compiler_flag ("-Wextra" Wextra_FLAG_SUPPORTED)
if (Wextra_FLAG_SUPPORTED)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wextra")
endif (Wextra_FLAG_SUPPORTED)
# Library
set (TARGET_NAME ${PROJECT_NAME})
set (TARGET_OUTPUT_SUFFIX "-Qt${QT_VERSION}${${PROJECT_NAME}_VERSION_MAJOR}")
add_library (${TARGET_NAME} SHARED "")
set_target_properties(${TARGET_NAME}
PROPERTIES
EXPORT_NAME "${TARGET_NAME}${TARGET_OUTPUT_SUFFIX}")
set_target_properties (${TARGET_NAME}
PROPERTIES
CXX_STANDARD 11
CXX_STANDARD_REQUIRED ON
VERSION ${${PROJECT_NAME}_VERSION}
SOVERSION ${${PROJECT_NAME}_VERSION_MAJOR}
"INTERFACE_${PROJECT_NAME}_MAJOR_VERSION" ${${PROJECT_NAME}_VERSION_MAJOR}
COMPATIBLE_INTERFACE_STRING "${PROJECT_NAME}_MAJOR_VERSION"
OUTPUT_NAME "${TARGET_NAME}${TARGET_OUTPUT_SUFFIX}")
target_link_libraries(${TARGET_NAME}
PRIVATE
${COLOR_WIDGETS_LIBRARY})
use_qt (
TARGET_NAME ${TARGET_NAME}
QT_SUPPORTED_VERSIONS "${QT_SUPPORTED_VERSIONS}"
REQUIRED_COMPONENTS "${REQUIRED_QT_COMPONENTS}"
OPTIONAL_COMPONENTS "")
# Sources
set(SOURCES
color_preview_plugin.cpp
color_wheel_plugin.cpp
color_widget_plugin_collection.cpp
gradient_slider_plugin.cpp
hue_slider_plugin.cpp
color_selector_plugin.cpp
color_list_plugin.cpp
swatch_plugin.cpp
color_palette_widget_plugin.cpp
color_2d_slider_plugin.cpp
color_line_edit_plugin.cpp
gradient_editor_plugin.cpp
# add new sources above this line
)
foreach (SOURCE IN LISTS SOURCES)
target_sources (${TARGET_NAME}
PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/${SOURCE}>)
endforeach (SOURCE IN SOURCES)
set(HEADERS
color_preview_plugin.hpp
color_wheel_plugin.hpp
color_widget_plugin_collection.hpp
gradient_slider_plugin.hpp
hue_slider_plugin.hpp
color_selector_plugin.hpp
color_list_plugin.hpp
swatch_plugin.hpp
color_palette_widget_plugin.hpp
color_2d_slider_plugin.hpp
color_line_edit_plugin.hpp
gradient_editor_plugin.hpp
# add new headers above this line
)
foreach (HEADER IN LISTS HEADERS)
target_sources (${TARGET_NAME}
PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/${HEADER}>)
endforeach (HEADER IN HEADERS)
# install
get_target_property (QT_QMAKE_EXECUTABLE
Qt5::qmake LOCATION)
execute_process (
COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_PLUGINS
OUTPUT_VARIABLE QT_INSTALL_PLUGINS
OUTPUT_STRIP_TRAILING_WHITESPACE)
# install(TARGETS ${COLOR_WIDGETS_PLUGIN} DESTINATION ${QT_INSTALL_PLUGINS}/designer OPTIONAL)
execute_process (
COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_LIBS
OUTPUT_VARIABLE QT_INSTALL_LIBS
OUTPUT_STRIP_TRAILING_WHITESPACE)
# install(TARGETS ${COLOR_WIDGETS_PLUGIN} DESTINATION ${QT_INSTALL_LIBS}/qtcreator/plugins OPTIONAL)
add_custom_target(${TARGET_NAME}_install
COMMAND cp $<TARGET_FILE:${TARGET_NAME}> ${QT_INSTALL_PLUGINS}/designer
COMMAND cp $<TARGET_FILE:${TARGET_NAME}> ${QT_INSTALL_LIBS}/qtcreator/plugins
DEPENDS ${TARGET_NAME}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})

View File

@ -0,0 +1,90 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "color_2d_slider_plugin.hpp"
#include "QtColorWidgets/color_2d_slider.hpp"
Color2DSlider_Plugin::Color2DSlider_Plugin(QObject *parent) :
QObject(parent), initialized(false)
{
}
void Color2DSlider_Plugin::initialize(QDesignerFormEditorInterface *)
{
initialized = true;
}
bool Color2DSlider_Plugin::isInitialized() const
{
return initialized;
}
QWidget *Color2DSlider_Plugin::createWidget(QWidget *parent)
{
return new color_widgets::Color2DSlider(parent);
}
QString Color2DSlider_Plugin::name() const
{
return "color_widgets::Color2DSlider";
}
QString Color2DSlider_Plugin::group() const
{
return "Color Widgets";
}
QIcon Color2DSlider_Plugin::icon() const
{
color_widgets::Color2DSlider w;
w.resize(64,64);
QPixmap pix(64,64);
w.render(&pix);
return QIcon(pix);
}
QString Color2DSlider_Plugin::toolTip() const
{
return "An analog widget to select 2 color components at the same time";
}
QString Color2DSlider_Plugin::whatsThis() const
{
return toolTip();
}
bool Color2DSlider_Plugin::isContainer() const
{
return false;
}
QString Color2DSlider_Plugin::domXml() const
{
return "<ui language=\"c++\">\n"
" <widget class=\"color_widgets::Color2DSlider\" name=\"color2DSlider\">\n"
" </widget>\n"
"</ui>\n";
}
QString Color2DSlider_Plugin::includeFile() const
{
return "QtColorWidgets/color_2d_slider.hpp";
}

View File

@ -0,0 +1,57 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COLOR_WIDGETS_COLOR_2D_SLIDER_PLUGIN_HPP
#define COLOR_WIDGETS_COLOR_2D_SLIDER_PLUGIN_HPP
#include <QObject>
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
class Color2DSlider_Plugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
Color2DSlider_Plugin(QObject *parent = 0);
void initialize(QDesignerFormEditorInterface *core);
bool isInitialized() const;
QWidget *createWidget(QWidget *parent);
QString name() const;
QString group() const;
QIcon icon() const;
QString toolTip() const;
QString whatsThis() const;
bool isContainer() const;
QString domXml() const;
QString includeFile() const;
private:
bool initialized;
};
#endif // COLOR_WIDGETS_COLOR_2D_SLIDER_PLUGIN_HPP

View File

@ -0,0 +1,87 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "color_line_edit_plugin.hpp"
#include "QtColorWidgets/color_line_edit.hpp"
QWidget* ColorLineEdit_Plugin::createWidget(QWidget *parent)
{
color_widgets::ColorLineEdit *widget = new color_widgets::ColorLineEdit(parent);
return widget;
}
QIcon ColorLineEdit_Plugin::icon() const
{
return QIcon::fromTheme("edit-rename");
}
QString ColorLineEdit_Plugin::domXml() const
{
return "<ui language=\"c++\">\n"
" <widget class=\"color_widgets::ColorLineEdit\" name=\"color_line_edit\">\n"
" </widget>\n"
"</ui>\n";
}
bool ColorLineEdit_Plugin::isContainer() const
{
return false;
}
ColorLineEdit_Plugin::ColorLineEdit_Plugin(QObject *parent) :
QObject(parent), initialized(false)
{
}
void ColorLineEdit_Plugin::initialize(QDesignerFormEditorInterface *)
{
initialized = true;
}
bool ColorLineEdit_Plugin::isInitialized() const
{
return initialized;
}
QString ColorLineEdit_Plugin::name() const
{
return "color_widgets::ColorLineEdit";
}
QString ColorLineEdit_Plugin::group() const
{
return "Color Widgets";
}
QString ColorLineEdit_Plugin::toolTip() const
{
return "A widget to manipulate a string representing a color";
}
QString ColorLineEdit_Plugin::whatsThis() const
{
return toolTip();
}
QString ColorLineEdit_Plugin::includeFile() const
{
return "QtColorWidgets/color_line_edit.hpp";
}

View File

@ -0,0 +1,58 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COLOR_WIDGETS_COLOR_LINE_EDIT_PLUGIN_HPP
#define COLOR_WIDGETS_COLOR_LINE_EDIT_PLUGIN_HPP
#include <QObject>
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
class ColorLineEdit_Plugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
explicit ColorLineEdit_Plugin(QObject *parent = nullptr);
void initialize(QDesignerFormEditorInterface *core) Q_DECL_OVERRIDE;
bool isInitialized() const Q_DECL_OVERRIDE;
QWidget *createWidget(QWidget *parent) Q_DECL_OVERRIDE;
QString name() const Q_DECL_OVERRIDE;
QString group() const Q_DECL_OVERRIDE;
QIcon icon() const Q_DECL_OVERRIDE;
QString toolTip() const Q_DECL_OVERRIDE;
QString whatsThis() const Q_DECL_OVERRIDE;
bool isContainer() const Q_DECL_OVERRIDE;
QString domXml() const Q_DECL_OVERRIDE;
QString includeFile() const Q_DECL_OVERRIDE;
private:
bool initialized;
};
#endif // COLOR_WIDGETS_COLOR_LINE_EDIT_PLUGIN_HPP

View File

@ -0,0 +1,88 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "color_list_plugin.hpp"
#include "QtColorWidgets/color_list_widget.hpp"
ColorListWidget_Plugin::ColorListWidget_Plugin(QObject *parent) :
QObject(parent)
{
}
void ColorListWidget_Plugin::initialize(QDesignerFormEditorInterface *)
{
initialized = true;
}
bool ColorListWidget_Plugin::isInitialized() const
{
return initialized;
}
QWidget *ColorListWidget_Plugin::createWidget(QWidget *parent)
{
return new color_widgets::ColorListWidget(parent);
}
QString ColorListWidget_Plugin::name() const
{
return "color_widgets::ColorListWidget";
}
QString ColorListWidget_Plugin::group() const
{
return "Color Widgets";
}
QIcon ColorListWidget_Plugin::icon() const
{
return QIcon::fromTheme("format-stroke-color");
}
QString ColorListWidget_Plugin::toolTip() const
{
return "An editable list of colors";
}
QString ColorListWidget_Plugin::whatsThis() const
{
return toolTip();
}
bool ColorListWidget_Plugin::isContainer() const
{
return false;
}
QString ColorListWidget_Plugin::domXml() const
{
return "<ui language=\"c++\">\n"
" <widget class=\"color_widgets::ColorListWidget\" name=\"ColorListWidget\">\n"
" </widget>\n"
"</ui>\n";
}
QString ColorListWidget_Plugin::includeFile() const
{
return "QtColorWidgets/color_list_widget.hpp";
}

View File

@ -0,0 +1,56 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COLOR_LIST_PLUGIN_HPP
#define COLOR_LIST_PLUGIN_HPP
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
class ColorListWidget_Plugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
explicit ColorListWidget_Plugin(QObject *parent = 0);
void initialize(QDesignerFormEditorInterface *core);
bool isInitialized() const;
QWidget *createWidget(QWidget *parent);
QString name() const;
QString group() const;
QIcon icon() const;
QString toolTip() const;
QString whatsThis() const;
bool isContainer() const;
QString domXml() const;
QString includeFile() const;
private:
bool initialized;
};
#endif // COLOR_LIST_PLUGIN_HPP

View File

@ -0,0 +1,120 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "color_palette_widget_plugin.hpp"
#include "QtColorWidgets/color_palette_widget.hpp"
ColorPaletteWidget_Plugin::ColorPaletteWidget_Plugin(QObject *parent) :
QObject(parent), initialized(false)
{
}
void ColorPaletteWidget_Plugin::initialize(QDesignerFormEditorInterface *)
{
initialized = true;
}
bool ColorPaletteWidget_Plugin::isInitialized() const
{
return initialized;
}
QWidget* ColorPaletteWidget_Plugin::createWidget(QWidget *parent)
{
color_widgets::ColorPaletteWidget *wid = new color_widgets::ColorPaletteWidget(parent);
color_widgets::ColorPalette palette1;
color_widgets::ColorPalette palette2;
int columns = 12;
palette1.setName("Palette 1");
palette2.setName("Palette 2");
palette1.setColumns(columns);
palette2.setColumns(columns);
for ( int i = 0; i < 6; i++ )
{
for ( int j = 0; j < columns; j++ )
{
float f = float(j)/columns;
palette1.appendColor(QColor::fromHsvF(i/8.0,1-f,0.5+f/2));
palette2.appendColor(QColor::fromHsvF(i/8.0,1-f,1-f));
}
}
color_widgets::ColorPaletteModel *model = new color_widgets::ColorPaletteModel;
model->setParent(wid);
model->addPalette(palette1, false);
model->addPalette(palette2, false);
wid->setModel(model);
return wid;
}
QString ColorPaletteWidget_Plugin::name() const
{
return "color_widgets::ColorPaletteWidget";
}
QString ColorPaletteWidget_Plugin::group() const
{
return "Color Widgets";
}
QIcon ColorPaletteWidget_Plugin::icon() const
{
color_widgets::ColorPalette w;
w.setColumns(6);
for ( int i = 0; i < 4; i++ )
{
for ( int j = 0; j < w.columns(); j++ )
{
float f = float(j)/w.columns();
w.appendColor(QColor::fromHsvF(i/5.0,1-f,0.5+f/2));
}
}
return QIcon(w.preview(QSize(64,64)));
}
QString ColorPaletteWidget_Plugin::toolTip() const
{
return "A widget that displays a color palette";
}
QString ColorPaletteWidget_Plugin::whatsThis() const
{
return toolTip();
}
bool ColorPaletteWidget_Plugin::isContainer() const
{
return false;
}
QString ColorPaletteWidget_Plugin::domXml() const
{
return "<ui language=\"c++\">\n"
" <widget class=\"color_widgets::ColorPaletteWidget\" name=\"palette_widget\">\n"
" </widget>\n"
"</ui>\n";
}
QString ColorPaletteWidget_Plugin::includeFile() const
{
return "QtColorWidgets/color_palette_widget.hpp";
}

View File

@ -0,0 +1,57 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COLOR_WIDGETS_COLOR_PALETTE_WIDGET_PLUGIN_HPP
#define COLOR_WIDGETS_COLOR_PALETTE_WIDGET_PLUGIN_HPP
#include <QObject>
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
class ColorPaletteWidget_Plugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
ColorPaletteWidget_Plugin(QObject *parent = 0);
void initialize(QDesignerFormEditorInterface *core);
bool isInitialized() const;
QWidget *createWidget(QWidget *parent);
QString name() const;
QString group() const;
QIcon icon() const;
QString toolTip() const;
QString whatsThis() const;
bool isContainer() const;
QString domXml() const;
QString includeFile() const;
private:
bool initialized;
};
#endif // COLOR_WIDGETS_COLOR_PALETTE_WIDGET_PLUGIN_HPP

View File

@ -0,0 +1,95 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "color_preview_plugin.hpp"
#include "QtColorWidgets/color_preview.hpp"
#include <QtPlugin>
ColorPreview_Plugin::ColorPreview_Plugin(QObject *parent)
: QObject(parent), initialized(false)
{
}
void ColorPreview_Plugin::initialize(QDesignerFormEditorInterface *)
{
if (initialized)
return;
initialized = true;
}
bool ColorPreview_Plugin::isInitialized() const
{
return initialized;
}
QWidget *ColorPreview_Plugin::createWidget(QWidget *parent)
{
return new color_widgets::ColorPreview(parent);
}
QString ColorPreview_Plugin::name() const
{
return "color_widgets::ColorPreview";
}
QString ColorPreview_Plugin::group() const
{
return "Color Widgets";
}
QIcon ColorPreview_Plugin::icon() const
{
return QIcon();
}
QString ColorPreview_Plugin::toolTip() const
{
return "Display a color";
}
QString ColorPreview_Plugin::whatsThis() const
{
return toolTip();
}
bool ColorPreview_Plugin::isContainer() const
{
return false;
}
QString ColorPreview_Plugin::domXml() const
{
return "<ui language=\"c++\">\n"
" <widget class=\"color_widgets::ColorPreview\" name=\"colorPreview\">\n"
" </widget>\n"
"</ui>\n";
}
QString ColorPreview_Plugin::includeFile() const
{
return "QtColorWidgets/color_preview.hpp";
}
//Q_EXPORT_PLUGIN2(color_widgets, ColorPreview_Plugin);

View File

@ -0,0 +1,55 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COLOR_PREVIEW_PLUGIN_HPP
#define COLOR_PREVIEW_PLUGIN_HPP
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
class ColorPreview_Plugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
ColorPreview_Plugin(QObject *parent = 0);
void initialize(QDesignerFormEditorInterface *core);
bool isInitialized() const;
QWidget *createWidget(QWidget *parent);
QString name() const;
QString group() const;
QIcon icon() const;
QString toolTip() const;
QString whatsThis() const;
bool isContainer() const;
QString domXml() const;
QString includeFile() const;
private:
bool initialized;
};
#endif // COLOR_PREVIEW_PLUGIN_HPP

View File

@ -0,0 +1,92 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "color_selector_plugin.hpp"
#include "QtColorWidgets/color_selector.hpp"
#include <QtPlugin>
ColorSelector_Plugin::ColorSelector_Plugin(QObject *parent)
: QObject(parent), initialized(false)
{
}
void ColorSelector_Plugin::initialize(QDesignerFormEditorInterface *)
{
if (initialized)
return;
initialized = true;
}
bool ColorSelector_Plugin::isInitialized() const
{
return initialized;
}
QWidget *ColorSelector_Plugin::createWidget(QWidget *parent)
{
return new color_widgets::ColorSelector(parent);
}
QString ColorSelector_Plugin::name() const
{
return "color_widgets::ColorSelector";
}
QString ColorSelector_Plugin::group() const
{
return "Color Widgets";
}
QIcon ColorSelector_Plugin::icon() const
{
return QIcon();
}
QString ColorSelector_Plugin::toolTip() const
{
return "Display a color and opens a color dialog on click";
}
QString ColorSelector_Plugin::whatsThis() const
{
return toolTip();
}
bool ColorSelector_Plugin::isContainer() const
{
return false;
}
QString ColorSelector_Plugin::domXml() const
{
return "<ui language=\"c++\">\n"
" <widget class=\"color_widgets::ColorSelector\" name=\"ColorSelector\">\n"
" </widget>\n"
"</ui>\n";
}
QString ColorSelector_Plugin::includeFile() const
{
return "QtColorWidgets/color_selector.hpp";
}

View File

@ -0,0 +1,55 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COLOR_SELECTOR_PLUGIN_HPP
#define COLOR_SELECTOR_PLUGIN_HPP
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
class ColorSelector_Plugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
ColorSelector_Plugin(QObject *parent = 0);
void initialize(QDesignerFormEditorInterface *core);
bool isInitialized() const;
QWidget *createWidget(QWidget *parent);
QString name() const;
QString group() const;
QIcon icon() const;
QString toolTip() const;
QString whatsThis() const;
bool isContainer() const;
QString domXml() const;
QString includeFile() const;
private:
bool initialized;
};
#endif // COLOR_SELECTOR_PLUGIN_HPP

View File

@ -0,0 +1,97 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "color_wheel_plugin.hpp"
#include "QtColorWidgets/color_wheel.hpp"
ColorWheel_Plugin::ColorWheel_Plugin(QObject *parent) :
QObject(parent), initialized(false)
{
}
void ColorWheel_Plugin::initialize(QDesignerFormEditorInterface *)
{
initialized = true;
}
bool ColorWheel_Plugin::isInitialized() const
{
return initialized;
}
QWidget *ColorWheel_Plugin::createWidget(QWidget *parent)
{
return new color_widgets::ColorWheel(parent);
}
QString ColorWheel_Plugin::name() const
{
return "color_widgets::ColorWheel";
}
QString ColorWheel_Plugin::group() const
{
return "Color Widgets";
}
QIcon ColorWheel_Plugin::icon() const
{
color_widgets::ColorWheel w;
w.resize(64,64);
w.setWheelWidth(8);
QPixmap pix(64,64);
w.render(&pix);
return QIcon(pix);
}
QString ColorWheel_Plugin::toolTip() const
{
return "A widget that allows an intuitive selection of HSL parameters for a QColor";
}
QString ColorWheel_Plugin::whatsThis() const
{
return toolTip();
}
bool ColorWheel_Plugin::isContainer() const
{
return false;
}
QString ColorWheel_Plugin::domXml() const
{
return "<ui language=\"c++\">\n"
" <widget class=\"color_widgets::ColorWheel\" name=\"colorWheel\">\n"
" <property name=\"sizePolicy\">\n"
" <sizepolicy hsizetype=\"Minimum\" vsizetype=\"Minimum\">\n"
" <horstretch>0</horstretch>\n"
" <verstretch>0</verstretch>\n"
" </sizepolicy>\n"
" </property>\n"
" </widget>\n"
"</ui>\n";
}
QString ColorWheel_Plugin::includeFile() const
{
return "QtColorWidgets/color_wheel.hpp";
}

View File

@ -0,0 +1,57 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COLOR_WHEEL_PLUGIN_HPP
#define COLOR_WHEEL_PLUGIN_HPP
#include <QObject>
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
class ColorWheel_Plugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
ColorWheel_Plugin(QObject *parent = 0);
void initialize(QDesignerFormEditorInterface *core);
bool isInitialized() const;
QWidget *createWidget(QWidget *parent);
QString name() const;
QString group() const;
QIcon icon() const;
QString toolTip() const;
QString whatsThis() const;
bool isContainer() const;
QString domXml() const;
QString includeFile() const;
private:
bool initialized;
};
#endif // COLOR_WHEEL_PLUGIN_HPP

View File

@ -0,0 +1,56 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "color_widget_plugin_collection.hpp"
#include "color_preview_plugin.hpp"
#include "color_wheel_plugin.hpp"
#include "gradient_slider_plugin.hpp"
#include "hue_slider_plugin.hpp"
#include "color_selector_plugin.hpp"
#include "color_list_plugin.hpp"
#include "swatch_plugin.hpp"
#include "color_palette_widget_plugin.hpp"
#include "color_2d_slider_plugin.hpp"
#include "color_line_edit_plugin.hpp"
#include "gradient_editor_plugin.hpp"
// add new plugin headers above this line
ColorWidgets_PluginCollection::ColorWidgets_PluginCollection(QObject *parent) :
QObject(parent)
{
widgets.push_back(new ColorPreview_Plugin(this));
widgets.push_back(new ColorWheel_Plugin(this));
widgets.push_back(new GradientSlider_Plugin(this));
widgets.push_back(new HueSlider_Plugin(this));
widgets.push_back(new ColorSelector_Plugin(this));
widgets.push_back(new ColorListWidget_Plugin(this));
widgets.push_back(new Swatch_Plugin(this));
widgets.push_back(new ColorPaletteWidget_Plugin(this));
widgets.push_back(new Color2DSlider_Plugin(this));
widgets.push_back(new ColorLineEdit_Plugin(this));
widgets.push_back(new GradientEditor_Plugin(this));
// add new plugins above this line
}
QList<QDesignerCustomWidgetInterface *> ColorWidgets_PluginCollection::customWidgets() const
{
return widgets;
}

View File

@ -0,0 +1,43 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COLOR_WIDGET_PLUGIN_COLLECTION_HPP
#define COLOR_WIDGET_PLUGIN_COLLECTION_HPP
#include <QtUiPlugin/QDesignerCustomWidgetCollectionInterface>
class ColorWidgets_PluginCollection : public QObject, public QDesignerCustomWidgetCollectionInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "mattia.basaglia.ColorWidgetsPlugin")
Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
public:
explicit ColorWidgets_PluginCollection(QObject *parent = 0);
QList<QDesignerCustomWidgetInterface*> customWidgets() const;
private:
QList<QDesignerCustomWidgetInterface*> widgets;
};
#endif // COLOR_WIDGET_PLUGIN_COLLECTION_HPP

View File

@ -0,0 +1,98 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "gradient_editor_plugin.hpp"
#include "QtColorWidgets/gradient_editor.hpp"
QWidget* GradientEditor_Plugin::createWidget(QWidget *parent)
{
color_widgets::GradientEditor *widget = new color_widgets::GradientEditor(parent);
return widget;
}
QIcon GradientEditor_Plugin::icon() const
{
color_widgets::GradientEditor w;
w.resize(64,16);
QGradientStops cols;
cols.push_back({0.2, Qt::green});
cols.push_back({0.5, Qt::yellow});
cols.push_back({0.8, Qt::red});
w.setStops(cols);
QPixmap pix(64,64);
pix.fill(Qt::transparent);
w.render(&pix, QPoint(0,16));
return QIcon(pix);
}
QString GradientEditor_Plugin::domXml() const
{
return "<ui language=\"c++\">\n"
" <widget class=\"color_widgets::GradientEditor\" name=\"gradient_editor\">\n"
" </widget>\n"
"</ui>\n";
}
bool GradientEditor_Plugin::isContainer() const
{
return false;
}
GradientEditor_Plugin::GradientEditor_Plugin(QObject *parent) :
QObject(parent), initialized(false)
{
}
void GradientEditor_Plugin::initialize(QDesignerFormEditorInterface *)
{
initialized = true;
}
bool GradientEditor_Plugin::isInitialized() const
{
return initialized;
}
QString GradientEditor_Plugin::name() const
{
return "color_widgets::GradientEditor";
}
QString GradientEditor_Plugin::group() const
{
return "Color Widgets";
}
QString GradientEditor_Plugin::toolTip() const
{
return "Widget to edit gradient stops";
}
QString GradientEditor_Plugin::whatsThis() const
{
return toolTip();
}
QString GradientEditor_Plugin::includeFile() const
{
return "QtColorWidgets/gradient_editor.hpp";
}

View File

@ -0,0 +1,58 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COLOR_WIDGETS_GRADIENT_EDITOR_PLUGIN_HPP
#define COLOR_WIDGETS_GRADIENT_EDITOR_PLUGIN_HPP
#include <QObject>
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
class GradientEditor_Plugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
explicit GradientEditor_Plugin(QObject *parent = nullptr);
void initialize(QDesignerFormEditorInterface *core) Q_DECL_OVERRIDE;
bool isInitialized() const Q_DECL_OVERRIDE;
QWidget *createWidget(QWidget *parent) Q_DECL_OVERRIDE;
QString name() const Q_DECL_OVERRIDE;
QString group() const Q_DECL_OVERRIDE;
QIcon icon() const Q_DECL_OVERRIDE;
QString toolTip() const Q_DECL_OVERRIDE;
QString whatsThis() const Q_DECL_OVERRIDE;
bool isContainer() const Q_DECL_OVERRIDE;
QString domXml() const Q_DECL_OVERRIDE;
QString includeFile() const Q_DECL_OVERRIDE;
private:
bool initialized;
};
#endif // COLOR_WIDGETS_GRADIENT_EDITOR_PLUGIN_HPP

View File

@ -0,0 +1,102 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "gradient_slider_plugin.hpp"
#include "QtColorWidgets/gradient_slider.hpp"
#include <QtPlugin>
GradientSlider_Plugin::GradientSlider_Plugin(QObject *parent)
: QObject(parent), initialized(false)
{
}
void GradientSlider_Plugin::initialize(QDesignerFormEditorInterface *)
{
if (initialized)
return;
initialized = true;
}
bool GradientSlider_Plugin::isInitialized() const
{
return initialized;
}
QWidget *GradientSlider_Plugin::createWidget(QWidget *parent)
{
return new color_widgets::GradientSlider(parent);
}
QString GradientSlider_Plugin::name() const
{
return "color_widgets::GradientSlider";
}
QString GradientSlider_Plugin::group() const
{
return "Color Widgets";
}
QIcon GradientSlider_Plugin::icon() const
{
color_widgets::GradientSlider w;
w.resize(64,16);
QVector<QColor> cols;
cols.push_back(Qt::green);
cols.push_back(Qt::yellow);
cols.push_back(Qt::red);
w.setColors(cols);
QPixmap pix(64,64);
pix.fill(Qt::transparent);
w.render(&pix,QPoint(0,16));
return QIcon(pix);
}
QString GradientSlider_Plugin::toolTip() const
{
return "Slider over a gradient";
}
QString GradientSlider_Plugin::whatsThis() const
{
return toolTip();
}
bool GradientSlider_Plugin::isContainer() const
{
return false;
}
QString GradientSlider_Plugin::domXml() const
{
return "<ui language=\"c++\">\n"
" <widget class=\"color_widgets::GradientSlider\" name=\"GradientSlider\">\n"
" </widget>\n"
"</ui>\n";
}
QString GradientSlider_Plugin::includeFile() const
{
return "QtColorWidgets/gradient_slider.hpp";
}

View File

@ -0,0 +1,34 @@
#ifndef GRADIENT_SLIDER_PLUGIN_HPP
#define GRADIENT_SLIDER_PLUGIN_HPP
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
class GradientSlider_Plugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
GradientSlider_Plugin(QObject *parent = 0);
void initialize(QDesignerFormEditorInterface *core);
bool isInitialized() const;
QWidget *createWidget(QWidget *parent);
QString name() const;
QString group() const;
QIcon icon() const;
QString toolTip() const;
QString whatsThis() const;
bool isContainer() const;
QString domXml() const;
QString includeFile() const;
private:
bool initialized;
};
#endif // GRADIENT_SLIDER_PLUGIN_HPP

View File

@ -0,0 +1,98 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
* \copyright Copyright (C) 2014 Calle Laakkonen
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "hue_slider_plugin.hpp"
#include "QtColorWidgets/hue_slider.hpp"
#include <QtPlugin>
HueSlider_Plugin::HueSlider_Plugin(QObject *parent)
: QObject(parent), initialized(false)
{
}
void HueSlider_Plugin::initialize(QDesignerFormEditorInterface *)
{
if (initialized)
return;
initialized = true;
}
bool HueSlider_Plugin::isInitialized() const
{
return initialized;
}
QWidget *HueSlider_Plugin::createWidget(QWidget *parent)
{
return new color_widgets::HueSlider(parent);
}
QString HueSlider_Plugin::name() const
{
return "color_widgets::HueSlider";
}
QString HueSlider_Plugin::group() const
{
return "Color Widgets";
}
QIcon HueSlider_Plugin::icon() const
{
color_widgets::HueSlider w;
w.resize(64,16);
QPixmap pix(64,64);
pix.fill(Qt::transparent);
w.render(&pix,QPoint(0,16));
return QIcon(pix);
}
QString HueSlider_Plugin::toolTip() const
{
return "Slider over a hue gradient";
}
QString HueSlider_Plugin::whatsThis() const
{
return toolTip();
}
bool HueSlider_Plugin::isContainer() const
{
return false;
}
QString HueSlider_Plugin::domXml() const
{
return "<ui language=\"c++\">\n"
" <widget class=\"color_widgets::HueSlider\" name=\"HueSlider\">\n"
" </widget>\n"
"</ui>\n";
}
QString HueSlider_Plugin::includeFile() const
{
return "QtColorWidgets/hue_slider.hpp";
}

View File

@ -0,0 +1,34 @@
#ifndef HUE_SLIDER_PLUGIN_HPP
#define HUE_SLIDER_PLUGIN_HPP
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
class HueSlider_Plugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
HueSlider_Plugin(QObject *parent = 0);
void initialize(QDesignerFormEditorInterface *core);
bool isInitialized() const;
QWidget *createWidget(QWidget *parent);
QString name() const;
QString group() const;
QIcon icon() const;
QString toolTip() const;
QString whatsThis() const;
bool isContainer() const;
QString domXml() const;
QString includeFile() const;
private:
bool initialized;
};
#endif // HUE_SLIDER_PLUGIN_HPP

View File

@ -0,0 +1,236 @@
#!/bin/bash
#
# Copyright (C) 2013-2020 Mattia Basaglia
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
SELFDIR=$(dirname $(readlink -se "${BASH_SOURCE[0]}"))
function class_to_underscore()
{
echo "$1" | sed -r -e 's/([a-z])([A-Z])/\1_\L\2/g' -e 's/[A-Z]/\L\0/g'
}
function class_to_header()
{
echo "$(class_to_underscore "$1").hpp"
}
function header_to_source()
{
echo "$1" | sed -r -e 's/\.h(pp)?$/.cpp/i'
}
function read_arg()
{
varname=$1
prompt="$2"
default="$3"
[ "$default" ] && prompt="${prompt} [$default]"
read -p "$prompt: " -i "$default" $varname
[ -z "${!varname}" ] && eval "$varname=\"$default\""
}
function header_to_guard()
{
echo "$1" | tr [:lower:] [:upper:] | tr /. _
}
read_arg class "Class name"
[ -z "$class" ] && exit 1
read_arg description "Description"
read_arg header "Header" "$(class_to_header "$class")"
read_arg plugin "Plugin Class" "${class}_Plugin"
read_arg plugin_header "Plugin Header" "$(class_to_header "$plugin")"
read_arg plugin_source "Plugin Source" "$(header_to_source "$plugin_header")"
read_arg plugin_path "Plugin Path" "$SELFDIR"
read_arg plugin_author "Author" "$(git config user.name)"
read_arg plugin_copyright "Copyright" "2013-$(date +%Y) $plugin_author"
echo "Summary:"
echo " Class: $class"
echo " Description: $description"
echo " Header: $header"
echo " Plugin Class: $plugin"
echo " Plugin Header: $plugin_header"
echo " Plugin Source: $plugin_source"
echo " Plugin Path: $plugin_path"
echo " Author: $plugin_author"
echo " Copyright: $plugin_copyright"
object_name="$(class_to_underscore $class)"
cat >"$plugin_path/$plugin_source" <<PLUGIN
/**
* \file
*
* \author $plugin_author
*
* \copyright Copyright (C) $plugin_copyright
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "$plugin_header"
#include "QtColorWidgets/$header"
QWidget* $plugin::createWidget(QWidget *parent)
{
color_widgets::$class *widget = new color_widgets::$class(parent);
return widget;
}
QIcon $plugin::icon() const
{
return QIcon();
}
QString $plugin::domXml() const
{
return "<ui language=\"c++\">\n"
" <widget class=\"color_widgets::$class\" name=\"$object_name\">\n"
" </widget>\n"
"</ui>\n";
}
bool $plugin::isContainer() const
{
return false;
}
$plugin::$plugin(QObject *parent) :
QObject(parent), initialized(false)
{
}
void $plugin::initialize(QDesignerFormEditorInterface *)
{
initialized = true;
}
bool $plugin::isInitialized() const
{
return initialized;
}
QString $plugin::name() const
{
return "color_widgets::$class";
}
QString $plugin::group() const
{
return "Color Widgets";
}
QString $plugin::toolTip() const
{
return "$description";
}
QString $plugin::whatsThis() const
{
return toolTip();
}
QString $plugin::includeFile() const
{
return "QtColorWidgets/$header";
}
PLUGIN
header_guard="COLOR_WIDGETS_$(header_to_guard "$plugin_header")"
cat >"$plugin_path/$plugin_header" <<PLUGIN
/**
* \file
*
* \author $plugin_author
*
* \copyright Copyright (C) $plugin_copyright
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef $header_guard
#define $header_guard
#include <QObject>
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
class $plugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
explicit $plugin(QObject *parent = nullptr);
void initialize(QDesignerFormEditorInterface *core) Q_DECL_OVERRIDE;
bool isInitialized() const Q_DECL_OVERRIDE;
QWidget *createWidget(QWidget *parent) Q_DECL_OVERRIDE;
QString name() const Q_DECL_OVERRIDE;
QString group() const Q_DECL_OVERRIDE;
QIcon icon() const Q_DECL_OVERRIDE;
QString toolTip() const Q_DECL_OVERRIDE;
QString whatsThis() const Q_DECL_OVERRIDE;
bool isContainer() const Q_DECL_OVERRIDE;
QString domXml() const Q_DECL_OVERRIDE;
QString includeFile() const Q_DECL_OVERRIDE;
private:
bool initialized;
};
#endif // $header_guard
PLUGIN
sed -i -r \
-e "\\~# add new sources above this line~i\\$plugin_source" \
-e "\\~# add new headers above this line~i\\$plugin_header" \
"$plugin_path/CMakeLists.txt"
sed -i -r \
-e "\\~// add new plugin headers above this line~i#include \"$plugin_header\"" \
-e "\\~// add new plugins above this line~i\ widgets.push_back(new $plugin(this));" \
"$plugin_path/color_widget_plugin_collection.cpp"

View File

@ -0,0 +1,106 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "swatch_plugin.hpp"
#include "QtColorWidgets/swatch.hpp"
Swatch_Plugin::Swatch_Plugin(QObject *parent) :
QObject(parent), initialized(false)
{
}
void Swatch_Plugin::initialize(QDesignerFormEditorInterface *)
{
initialized = true;
}
bool Swatch_Plugin::isInitialized() const
{
return initialized;
}
QWidget* Swatch_Plugin::createWidget(QWidget *parent)
{
color_widgets::Swatch *wid = new color_widgets::Swatch(parent);
wid->palette().setColumns(12);
for ( int i = 0; i < 6; i++ )
{
for ( int j = 0; j < wid->palette().columns(); j++ )
{
float f = float(j)/wid->palette().columns();
wid->palette().appendColor(QColor::fromHsvF(i/8.0,1-f,0.5+f/2));
}
}
return wid;
}
QString Swatch_Plugin::name() const
{
return "color_widgets::Swatch";
}
QString Swatch_Plugin::group() const
{
return "Color Widgets";
}
QIcon Swatch_Plugin::icon() const
{
color_widgets::ColorPalette w;
w.setColumns(6);
for ( int i = 0; i < 4; i++ )
{
for ( int j = 0; j < w.columns(); j++ )
{
float f = float(j)/w.columns();
w.appendColor(QColor::fromHsvF(i/5.0,1-f,0.5+f/2));
}
}
return QIcon(w.preview(QSize(64,64)));
}
QString Swatch_Plugin::toolTip() const
{
return "A widget that displays a color palette";
}
QString Swatch_Plugin::whatsThis() const
{
return toolTip();
}
bool Swatch_Plugin::isContainer() const
{
return false;
}
QString Swatch_Plugin::domXml() const
{
return "<ui language=\"c++\">\n"
" <widget class=\"color_widgets::Swatch\" name=\"swatch\">\n"
" </widget>\n"
"</ui>\n";
}
QString Swatch_Plugin::includeFile() const
{
return "QtColorWidgets/swatch.hpp";
}

View File

@ -0,0 +1,57 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COLOR_WIDGETS_SWATCH_PLUGIN_HPP
#define COLOR_WIDGETS_SWATCH_PLUGIN_HPP
#include <QObject>
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
class Swatch_Plugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
Swatch_Plugin(QObject *parent = 0);
void initialize(QDesignerFormEditorInterface *core);
bool isInitialized() const;
QWidget *createWidget(QWidget *parent);
QString name() const;
QString group() const;
QIcon icon() const;
QString toolTip() const;
QString whatsThis() const;
bool isContainer() const;
QString domXml() const;
QString includeFile() const;
private:
bool initialized;
};
#endif // COLOR_WIDGETS_SWATCH_PLUGIN_HPP

View File

@ -0,0 +1,48 @@
#
# Copyright (C) 2013-2020 Mattia Basaglia
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set (QT_SUPPORTED_VERSIONS 5)
select_qt (
QT_SUPPORTED_VERSIONS "${QT_SUPPORTED_VERSIONS}"
QT_DEFAULT_VERSION 5)
set (REQUIRED_QT_COMPONENTS
Widgets
)
find_qt (
QT_SUPPORTED_VERSIONS "${QT_SUPPORTED_VERSIONS}"
REQUIRED_COMPONENTS "${REQUIRED_QT_COMPONENTS}"
OPTIONAL_COMPONENTS "")
set(SCREENSHOT_SOURCES screenshot.cpp)
set(SCREENSHOT_BINARY screenshot_bin)
add_executable(${SCREENSHOT_BINARY} EXCLUDE_FROM_ALL ${SCREENSHOT_SOURCES})
use_qt (
TARGET_NAME ${SCREENSHOT_BINARY}
QT_SUPPORTED_VERSIONS "${QT_SUPPORTED_VERSIONS}"
REQUIRED_COMPONENTS "${REQUIRED_QT_COMPONENTS}"
OPTIONAL_COMPONENTS "")
target_link_libraries(${SCREENSHOT_BINARY}
PRIVATE
${COLOR_WIDGETS_LIBRARY})
add_custom_target(gallery
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${SCREENSHOT_BINARY}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${SCREENSHOT_BINARY}
)

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 B

View File

@ -0,0 +1,91 @@
Color Widgets
=============
Color2DSlider
-------------
![Color2DSlider](Color2DSlider.png)
This widget allow the user to select 2 HSV color components at the same time,
by default that is Saturation and Value but they can be changed.
ColorDialog
-----------
![ColorDialog](ColorDialog.png)
This is a dialog analogous to <tt>QColorDialog</tt> but with a much nicer and friendlier
user interface. It uses several of the other widgets.
ColorLineEdit
-------------
![ColorLineEdit](ColorLineEdit.png)
![ColorLineEdit with color preview](ColorLineEdit_with_color.png)
This is a <tt>QLineEdit</tt> intended to be used to edit and display color names.
It accepts several string formats:
* <tt>#f00</tt> (3 hexadecimal rgb digits)
* <tt>#ff0000</tt> (6 hexadecimal rgb digits)
* <tt>rgb(255,0,0)</tt> (function-like)
* <tt>red</tt> (color name)
It can optionally display the color it represents on its background.
ColorListWidget
---------------
![ColorListWidget](ColorListWidget.png)
It allows to display and edit a list of colors.
ColorPaletteWidget and Swatch
-----------------------------
These widgets handle color palettes.
![Swatch](Swatch.png)
**Swatch** only handles a single palette, can be used to just select colors from the
palette or to modify the palette via drag and drop operations.
**ColorPaletteModel** is a list model that represents palettes with can be used
with the Qt item view widgets, it provides a name and a preview icon for
each of the stored palettes.
It also has functionality to load and save palettes from the filesystem.
![Read-only ColorPaletteWidget](ColorPaletteWidget_readonly.png)
![ColorPaletteWidget](ColorPaletteWidget.png)
**ColorPaletteWidget** manages a list of palettes (via **ColorPaletteModel**).
Has two modes: read-only only allows to select palettes and colors,
otherwise it can be used to modify the list of palettes and the palette itself.
ColorPreview and ColorSelector
------------------------------
![ColorPreview](ColorPreview.png)
**ColorPreview** is a widget that displays a color or compares two colors.
**ColorSelector** is like **ColorPreview** but when clicked it shows a ColorDialog.
GradientSlider and HueSlider
----------------------------
![HueSlider](HueSlider.png)
**GradientSlider** is a <tt>QSlider</tt> which uses a gradient as its background.
**HueSlider** is specifically made to select a hue and has more information
about the represented color.
GradientEditor
--------------
![GradientEditor](GradientEditor.png)
**GradientEditor** is similar in appearance to **GradientSlider** but it's for editing the gradient.
GradientListModel and GradientDelegate
--------------------------------------
![GradientListModel](GradientListModel_combo.png)
![GradientListModel](GradientListModel_view.png)
**GradientListModel** is a <tt>QAbstractListModel</tt> used to list gradients (useful for combo boxes, item views and the like).
**GradientDelegate** is an item delegate to edit gradients in an item view.

Binary file not shown.

After

Width:  |  Height:  |  Size: 951 B

View File

@ -0,0 +1,213 @@
/**
* \file
*
* \author Mattia Basaglia
*
* \copyright Copyright (C) 2013-2020 Mattia Basaglia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <cstring>
#include <algorithm>
#include <QApplication>
#include <QCommandLineParser>
#include <QComboBox>
#include <QListView>
#include <QTableWidget>
#include "QtColorWidgets/color_2d_slider.hpp"
#include "QtColorWidgets/color_delegate.hpp" /// \todo show it
#include "QtColorWidgets/color_dialog.hpp"
#include "QtColorWidgets/color_line_edit.hpp"
#include "QtColorWidgets/color_list_widget.hpp"
#include "QtColorWidgets/color_palette_widget.hpp"
#include "QtColorWidgets/color_preview.hpp"
#include "QtColorWidgets/color_wheel.hpp"
#include "QtColorWidgets/harmony_color_wheel.hpp"
#include "QtColorWidgets/hue_slider.hpp"
#include "QtColorWidgets/gradient_editor.hpp"
#include "QtColorWidgets/gradient_list_model.hpp"
#include "QtColorWidgets/gradient_delegate.hpp"
bool run = false;
QStringList just_these;
void screenshot(QWidget& widget, QString name = QString())
{
if ( name.isEmpty() )
{
name = widget.metaObject()->className();
name.remove("color_widgets::");
}
if ( !just_these.isEmpty() && !just_these.contains(name) )
return;
widget.setWindowTitle(name);
QPixmap pic(widget.size());
widget.render(&pic);
name += ".png";
pic.save(name);
if ( run )
widget.show();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QCommandLineParser parser;
parser.addHelpOption();
parser.addPositionalArgument("just_these", "Only these widgets");
QCommandLineOption run_option("run", "Show widgets instead of saving to file");
parser.addOption(run_option);
parser.process(a);
run = parser.isSet(run_option);
just_these = parser.positionalArguments();
QColor demo_color(64,172,143,128);
color_widgets::ColorPalette palette1;
color_widgets::ColorPalette palette2;
int palette_columns = 12;
palette1.setName("Palette 1");
palette2.setName("Palette 2");
palette1.setColumns(palette_columns);
palette2.setColumns(palette_columns);
for ( int i = 0; i < 6; i++ )
{
for ( int j = 0; j < palette_columns; j++ )
{
float f = float(j)/palette_columns;
palette1.appendColor(QColor::fromHsvF(i/8.0,1-f,0.5+f/2));
palette2.appendColor(QColor::fromHsvF(i/8.0,1-f,1-f));
}
}
color_widgets::ColorPaletteModel palette_model;
palette_model.addPalette(palette1, false);
palette_model.addPalette(palette2, false);
color_widgets::ColorPreview preview;
preview.setColor(demo_color);
preview.setDisplayMode(color_widgets::ColorPreview::SplitAlpha);
preview.resize(128,32);
screenshot(preview);
color_widgets::ColorDialog dialog;
dialog.setColorSpace(color_widgets::ColorWheel::ColorLCH);
dialog.setColor(demo_color);
screenshot(dialog);
color_widgets::Color2DSlider slider2d;
slider2d.setColor(demo_color);
slider2d.resize(128,192);
screenshot(slider2d);
color_widgets::ColorLineEdit line_edit;
line_edit.setColor(demo_color);
line_edit.resize(line_edit.sizeHint());
screenshot(line_edit);
line_edit.setPreviewColor(true);
screenshot(line_edit, "ColorLineEdit_with_color");
color_widgets::ColorWheel wheel;
wheel.resize(256, 256);
wheel.setColor(demo_color);
screenshot(wheel);
color_widgets::HarmonyColorWheel harwheel;
harwheel.resize(256, 256);
harwheel.setColor(demo_color);
harwheel.addHarmony(.333, true);
harwheel.addHarmony(.667, true);
screenshot(harwheel);
color_widgets::Swatch swatch;
swatch.setPalette(palette1);
swatch.resize(swatch.sizeHint());
screenshot(swatch);
color_widgets::ColorPaletteWidget palette_widget;
palette_widget.setModel(&palette_model);
screenshot(palette_widget);
palette_widget.setReadOnly(true);
screenshot(palette_widget, "ColorPaletteWidget_readonly");
color_widgets::HueSlider hue_slider;
hue_slider.setColor(demo_color);
hue_slider.resize(192, hue_slider.sizeHint().height());
// hue_slider.setInvertedAppearance(true);
// hue_slider.setOrientation(Qt::Vertical);
screenshot(hue_slider);
color_widgets::ColorListWidget list_widget;
list_widget.setColors({
demo_color,
palette1.colorAt(palette_columns*0),
palette1.colorAt(palette_columns*1),
palette1.colorAt(palette_columns*3),
palette1.colorAt(palette_columns*5),
});
list_widget.resize(list_widget.sizeHint());
screenshot(list_widget);
color_widgets::GradientEditor editor;
QGradientStops gradient_colors;
float n_colors = 4;
for ( int i = 0; i <= n_colors; ++i )
gradient_colors.append(QGradientStop(i/n_colors, QColor::fromHsvF(i/n_colors, 0.5, 1)));
editor.setStops(gradient_colors);
screenshot(editor);
QComboBox gradient_list;
color_widgets::GradientListModel gradient_model;
gradient_model.setGradient("Rainbow", gradient_colors);
gradient_model.setGradient("Black to Transparent", QGradientStops{{0, Qt::black}, {1, QColor(0, 0, 0, 0)}});
gradient_list.setModel(&gradient_model);
gradient_model.setIconSize(QSize(128, 24));
gradient_list.setIconSize(gradient_model.iconSize());
QObject::connect(&editor, &color_widgets::GradientEditor::stopsChanged, &gradient_model,
[&gradient_model](const QGradientStops& stops){ gradient_model.setGradient("Rainbow", stops); });
gradient_list.resize(gradient_list.sizeHint());
screenshot(gradient_list, "GradientListModel_combo");
QListView gradient_view;
color_widgets::GradientDelegate gradient_delegate;
gradient_view.setItemDelegate(&gradient_delegate);
gradient_view.setModel(&gradient_model);
// gradient_model.setEditMode(color_widgets::GradientListModel::EditName);
gradient_model.setEditMode(color_widgets::GradientListModel::EditGradient);
gradient_view.resize(QSize(gradient_view.sizeHintForColumn(0) + 4, gradient_view.sizeHint().height()));
screenshot(gradient_view, "GradientListModel_view");
QTableWidget gradient_table;
gradient_table.setItemDelegate(&gradient_delegate);
gradient_table.setRowCount(2);
gradient_table.setColumnCount(2);
gradient_table.setItem(0, 0, new QTableWidgetItem());
gradient_table.item(0, 0)->setData(Qt::EditRole, QVariant::fromValue(gradient_model.gradientBrush(0)));
gradient_table.setItem(0, 1, new QTableWidgetItem(gradient_model.nameFromIndex(0)));
gradient_table.setItem(1, 0, new QTableWidgetItem());
gradient_table.item(1, 0)->setData(Qt::EditRole, QVariant::fromValue(gradient_model.gradientBrush(1)));
gradient_table.setItem(1, 1, new QTableWidgetItem(gradient_model.nameFromIndex(1)));
screenshot(gradient_table, "GradientDelegate_table");
if ( run )
return a.exec();
return 0;
}

View File

@ -0,0 +1 @@
#include "abstract_widget_list.hpp"

View File

@ -0,0 +1 @@
#include "bound_color_selector.hpp"

View File

@ -0,0 +1,37 @@
set (HEADERS
abstract_widget_list.hpp
bound_color_selector.hpp
color_2d_slider.hpp
color_delegate.hpp
color_dialog.hpp
color_line_edit.hpp
color_list_widget.hpp
color_names.hpp
color_palette.hpp
color_palette_model.hpp
color_palette_widget.hpp
color_preview.hpp
color_selector.hpp
color_wheel.hpp
colorwidgets_global.hpp
gradient_slider.hpp
hue_slider.hpp
swatch.hpp
gradient_editor.hpp
harmony_color_wheel.hpp
gradient_list_model.hpp
gradient_delegate.hpp
)
file(RELATIVE_PATH
PREFIX
${PROJECT_SOURCE_DIR}
${CMAKE_CURRENT_LIST_DIR})
foreach (HEADER IN LISTS HEADERS)
target_sources (${TARGET_NAME}
PRIVATE
$<INSTALL_INTERFACE:${PREFIX}/${HEADER}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/${HEADER}>)
endforeach (HEADER IN HEADERS)

View File

@ -0,0 +1 @@
#include "color_delegate.hpp"

View File

@ -0,0 +1 @@
#include "color_dialog.hpp"

View File

@ -0,0 +1 @@
#include "color_list_widget.hpp"

View File

@ -0,0 +1 @@
#include "color_preview.hpp"

View File

@ -0,0 +1 @@
#include "color_selector.hpp"

View File

@ -0,0 +1 @@
#include "color_wheel.hpp"

Some files were not shown because too many files have changed in this diff Show More